如何从GET响应中获取cookie?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从GET响应中获取cookie?相关的知识,希望对你有一定的参考价值。
我正在编写一个函数,向网站发出GET请求并返回响应cookie:
extern crate futures;
extern crate hyper;
extern crate tokio_core;
use tokio_core::reactor::Core;
use hyper::Client;
use std::error::Error;
use hyper::header::Cookie;
use futures::future::Future;
fn get_new_cookie() -> Result<String, Box<Error>> {
println!("Getting cookie...");
let core = Core::new()?;
let client = Client::new(&core.handle());
println!("Created client");
let uri = "http://www.cnn.com".parse().expect("Cannot parse url");
println!("Parsed url");
let response = client.get(uri).wait().expect("Cannot get url.");
println!("Got response");
let cookie = response
.headers()
.get::<Cookie>()
.expect("Cannot get cookie");
println!("Cookie: {}", cookie);
Ok(cookie)
}
fn main() {
println!("{:?}", get_new_cookie());
}
这不起作用;它被卡在client.get(...)
字符串上。我得到的输出是:
Getting cookie...
Created client
Parsed url
之后没有任何反应。
我做错了什么以及如何改变它以便它起作用?
答案
作为Stefan points out,通过调用wait
,你正在让线程睡眠,直到未来完成。但是,该线程需要运行事件循环,因此您只是导致死锁。使用Core::run
更正确。
作为Francis Gagné points out,“Cookie”标头用于向服务器发送cookie。 SetCookie
用于向客户端发送cookie。它还会将所有cookie的向量一起返回:
fn get_new_cookie() -> Result<String, Box<Error>> {
println!("Getting cookie...");
let mut core = Core::new()?;
let client = Client::new(&core.handle());
println!("Created client");
let uri = "http://www.cnn.com".parse().expect("Cannot parse url");
println!("Parsed url");
let response = core.run(client.get(uri)).expect("Cannot get url.");
println!("Got response");
let cookie = response
.headers()
.get::<SetCookie>()
.expect("Cannot get cookie");
println!("Cookie: {:?}", cookie);
Ok(cookie.join(","))
}
但是,如果您只需要同步API,请改用Reqwest。它建立在Hyper之上:
extern crate reqwest;
use std::error::Error;
use reqwest::header::SetCookie;
fn get_new_cookie() -> Result<String, Box<Error>> {
let response = reqwest::get("http://www.cnn.com")?;
let cookies = match response.headers().get::<SetCookie>() {
Some(cookies) => cookies.join(","),
None => String::new(),
};
Ok(cookies)
}
fn main() {
println!("{:?}", get_new_cookie());
}
另一答案
见documentation for the wait
method:
注意:此方法不适合调用事件循环或类似的I / O情况,因为它会阻止事件循环进行(这会阻塞线程)。只有在保证与此未来相关的阻塞工作将由另一个线程完成时,才应调用此方法。
Future::wait
已经是deprecated in the tokio-reform
分支。
我建议设计完整的应用程序来处理异步概念(即get_new_cookie
应该采用Handle
并返回Future
,而不是分配自己的事件循环)。
您可以使用Core::run
运行请求,如下所示:
let response = core.run(client.get(uri)).expect("Cannot get url.");
以上是关于如何从GET响应中获取cookie?的主要内容,如果未能解决你的问题,请参考以下文章