我尝试使用rust-headless-chrome提取XHR请求的请求URL,使用网络请求拦截方法tab.enable_request_interception(request_interceptor)
错误:
error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut`
--> .../extract_xhr_url.rs:64:13
|
63 | let request_interceptor: Arc<dyn RequestInterceptor + Send + Sync> = Arc::new(
| _______________________________________________________________________________-
64 | |/ move |_transport: Arc<Transport>,
65 | || _session_id: SessionId,
66 | || intercepted_event: RequestPausedEvent| {
| ||________________________________________________________^ this closure implements `FnMut`, not `Fn`
... |
85 | | xhr_url = request_url.to_owned();
| | --- closure is `FnMut` because it mutates the variable `xhr_url` here
... |
100 | | },
101 | | );
| |__________- the requirement to implement `Fn` derives from here
|
= note: required for `[closure@.../extract_xhr_url.rs:64:13: 66:57]` to implement `RequestInterceptor`
= note: required for the cast from `[closure@.../extract_xhr_url.rs:64:13: 66:57]` to the object type `dyn RequestInterceptor + Send + Sync`
字符串
代码:
pub fn extract_xhr_url() -> Result<String, Box<dyn Error>> {
let main_url = "https://website.com".to_owned();
let mut xhr_url: String;
let browser = Browser::default()?;
let tab = browser.new_tab()?;
let request_pattern = RequestPattern {
url_pattern: None,
resource_Type: Some(ResourceType::Xhr),
request_stage: Some(RequestStage::Request),
};
tab.enable_fetch(Some(&[request_pattern]), None)?;
tab.navigate_to(&main_url)?.wait_until_navigated()?;
let request_interceptor: Arc<dyn RequestInterceptor + Send + Sync> = Arc::new(
move |_transport: Arc<Transport>,
_session_id: SessionId,
intercepted_event: RequestPausedEvent| {
let request_url = intercepted_event.params.request.url.as_str();
xhr_url = request_url.to_owned();
let continue_request = ContinueRequest {
request_id: intercepted_event.params.request_id,
url: Some(intercepted_event.params.request.url.clone()),
method: Some("GET".to_string()),
post_data: None,
headers: None,
intercept_response: None,
};
RequestPausedDecision::Continue(Some(continue_request))
},
);
tab.enable_request_interception(request_interceptor)?;
Ok(xhr_url)
}
型
如何将值移出Arc<dyn RequestInterceptor + Send + Sync>并将其重新分配给其作用域之外的可变变量?注意:它不能 Package 在Mutex中,因为tab.enable_request_interception()不能接受Mutex作为它的参数。
有解决办法吗?谢谢你,谢谢
////////////////////////////////////////////////////////////
好吧,按照我尝试使用Arc的建议,编译器诊断程序很安静,但它给出的结果是空的。该值似乎不会传递到闭包之外。此外,控制台在打印闭包内部的值之前打印闭包外部的值。为什么会这样呢?
代码重写:
pub fn extract_xhr_url() -> Result<String, Box<dyn Error>> {
let main_url = "https://website.com".to_owned();
// wrap it in Arc<Mutex<String>>
let xhr_url: Arc<Mutex<String>> = Arc::new(Mutex::new(String::new()));
// Clone the Arc for use in the closure
let xhr_url_clone = xhr_url.clone();
let browser = Browser::default()?;
let tab = browser.new_tab()?;
let request_pattern = RequestPattern {
url_pattern: None,
resource_Type: Some(ResourceType::Xhr),
request_stage: Some(RequestStage::Request),
};
tab.enable_fetch(Some(&[request_pattern]), None)?;
tab.navigate_to(&main_url)?.wait_until_navigated()?;
let request_interceptor: Arc<dyn RequestInterceptor + Send + Sync> = Arc::new(
move |_transport: Arc<Transport>,
_session_id: SessionId,
intercepted_event: RequestPausedEvent| {
let request_url = intercepted_event.params.request.url.as_str();
// lock it and then assign it a value
let mut xhr_url = xhr_url_clone.lock().unwrap();
*xhr_url = new_url.to_owned();
// prints the value inside of the closure to console
println!("XHR URL VALUE FROM INSIDE CLOSURE: {}", *xhr_url);
let continue_request = ContinueRequest {
request_id: intercepted_event.params.request_id,
url: Some(intercepted_event.params.request.url.clone()),
method: Some("GET".to_string()),
post_data: None,
headers: None,
intercept_response: None,
};
RequestPausedDecision::Continue(Some(continue_request))
},
);
tab.enable_request_interception(request_interceptor)?;
// prints the value outside of the closure to console
println!(
"XHR URL VALUE FROM OUTSIDE CLOSURE: {}",
*xhr_url.lock().unwrap()
);
Ok(xhr_url)
}
型
控制台:
XHR URL VALUE FROM OUTSIDE CLOSURE:
XHR URL VALUE FROM INSIDE CLOSURE: https://another-website.com/foo/bar/barz
型
1条答案
按热度按时间mf98qq941#
您不能从
Arc
中获取作为可变引用的值。不过没关系,反正不是你需要的。你真正想做的是将
xhr_url
Package 在Mutex
中(如果存在生存期问题,也可能 Package 在Arc
中),这样你就可以在 * 不 * lambda为FnMut
的情况下对它进行变异。