在 Rust 生态中,reqwest 可以说是最流行的 HTTP 客户端库了。它提供了一个高层级的、人性化的 API,让我们可以非常轻松地发送各种 HTTP 请求和处理响应。无论是 quickstart、自定义请求头、cookie 管理,还是文件上传,reqwest 都能帮我们优雅地搞定。
官网依赖地址:https://crates.io/crates/reqwest
github仓库地址:GitHub - seanmonstar/reqwest: An easy and powerful Rust HTTP Client
主要特性
通过查阅 reqwest 的文档和源码,我发现它主要有以下特性:
-
支持异步和阻塞两种客户端
-
可以发送纯文本、JSON、表单、多部分等多种类型的请求体
-
自定义重定向策略
-
支持 HTTP 代理
-
默认通过系统原生 TLS 实现 HTTPS(也可选择 rustls)
-
内置 Cookie 管理
-
支持 WASM
感觉非常强大,下面我们就用几个简单的例子,快速上手这个库!
发送一个 GET 请求
首先来看一个最简单的 GET 请求,访问 http://httpbin.org/ip 接口获取本机 IP。这里必须说一下,因为请求是异步的,所以还需要有tokio这个异步运行时的知识,我也发过一篇文章来说明这个tokio怎么使用:Rust异步并发编程tokio异步运行时讲解和使用,新手必学-CSDN博客。
而且因为响应式json格式的数据,所以还需要有serde_json这个json序列化相关的知识,可以看之前我发过的文章:5分钟学会Rust语言如何使用serde_json操作JSON-CSDN博客
接下来就可以看一下我们发送一个get请求,并获取到json相应的操作了:
use std::collections::HashMap;
use serde::Deserialize;
#[derive(Deserialize, Debug)]
struct Res {
origin: String,
}
#[tokio::main]
async fn main() {
// 发送get请求
let response = reqwest::get("https://httpbin.org/ip").await.unwrap();
// 获取文本字符串响应内容
let res_text = response.text().await.unwrap();
println!("response text value is: {res_text:?}");
// 将文本字符串转为结构体
let res_json: Res = serde_json::from_str(&res_text).unwrap();
println!("res_json value is: {res_json:?}");
// 或者直接在reqwest响应时转为hashmap
let res_map = reqwest::get("https://httpbin.org/ip").await.unwrap().json::<HashMap<String, String>>().await.unwrap();
println!("res hashmap value is: {res_map:?}");
}
这段代码中:
-
通过 reqwest::get 发送一个 GET 请求
-
通过 resp.json::<HashMap<String, String>>()将响应解析为 HashMap
-
打印出解析后的结果
运行后输出:
response text value is: "{\n \"origin\": \"116.232.39.24\"\n}\n"
res_json value is: Res { origin: "116.232.39.24" }
res hashmap value is:{"origin": "116.232.39.24"}
发送 POST 表单请求
我们再来试试 POST 请求。比如用 reqwest 提交一个登录表单。
// This will POST a body of `foo=bar&baz=quux`
let params = [("foo", "bar"), ("baz", "quux")];
let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
.form(¶ms)
.send()
.await?;
发送JSON请求
RequestBuilder 上还有一个 json 方法助手,它以类似于 form 方法的方式工作。它可以采用任何可以序列化为 JSON 的值。特性 json 是必需的。
// This will POST a body of `{"lang":"rust","body":"json"}`
let mut map = HashMap::new();
map.insert("lang", "rust");
map.insert("body", "json");
let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
.json(&map)
.send()
.await?;
Cookies管理
通过 ClientBuilder 上的 cookie _ store 方法,可以启用会话 Cookie 的自动存储和发送。
为客户端启用持久性 Cookie 存储:在响应中收到的 Cookie 将被保留并包含在其他请求中。
默认情况下,不使用 Cookie 存储。使用 cookie _ store (true)启用 cookie 存储将把存储设置为默认实现。如果使用 cookie _ Provider (my _ cookie _ store) ,则不必调用 cookie _ store (true) ; 在 cookie _ Provider (my _ cookie _ store)之后调用 cookie _ store (true)将导致提供的 my _ cookie _ store 被默认实现覆盖。
需要开启cookies特性才可以使用:
使用的时候:
// 自定义client,指定相关配置
// 开启cookie支持
let client = reqwest::Client::builder()
.cookie_store(true)
.build()
.unwrap();
let res = client.get(url.trim())
.send()
.await
.unwrap();
配置Proxy
注意:默认情况下启用系统代理。系统代理查看环境变量来设置 HTTP 或 HTTPS 代理。HTTP_PROXY或http_proxy为 http 连接提供 http 代理,同时 HTTPS_PROXY为https_proxyHTTPS 连接提供 HTTPS 代理。Proxy这些可以通过向ClientBuilder ie添加 来覆盖let proxy = reqwest::Proxy::http("https://secure.example")?; 或通过调用禁用ClientBuilder::no_proxy()。socks如果您像这样配置了socks代理,则需要该功能:
export https_proxy=socks5://127.0.0.1:1086
let params = [("foo", "bar"), ("baz", "quux")];
let proxy = reqwest::Proxy::http("https://secure.example").unwrap();
let client = reqwest::Client::builder()
.cookie_store(true)
.proxy(proxy)
.build()
.unwrap();
注意事项
注意:如果您计划执行多个请求,最好创建一个请求 Client并重用它,利用保持活动的连接池。