• 【一起学Rust | 进阶篇 | reqwest库】纯 Rust 编写的 HTTP 客户端——reqwest



    前言

    reqwest 是一个简单而强大的 RUST HTTP 客户端,用于浏览器异步 HTTP 请求。支持 xmlHttpRequest, JSONP, CORS, 和 CommonJS 约束。

    Reqwest 简单易用,功能强大,包括异步和阻塞模式,可以处理各种类型的请求数据,支持 HTTP 代理、TLS 加密、Cookie 存储等功能,另外还包括了对 WASM 的支持。


    一、安装与引用

    在项目的 Cargo.toml 中添加依赖:

    [dependencies]
    reqwest = { version = "0.11", features = ["json"] }
    tokio = { version = "1", features = ["full"] }
    
    • 1
    • 2
    • 3

    然后在你的程序中引用该库

    use std::collections::HashMap;
    
    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
        let resp = reqwest::get("https://httpbin.org/ip")
            .await?
            .json::<HashMap<String, String>>()
            .await?;
        println!("{:#?}", resp);
        Ok(())
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    以上代码引用了reqwest库,并且创建了一个请求,这个请求的api是

    https://httpbin.org/ip
    
    • 1

    返回当前请求浏览器的ip地址,也就是你当前的ip地址。

    运行该示例,看看效果

    可以看到,获取到了api返回的json信息,里面包含我当前的ip地址。

    二、用法

    1. 创建GET请求

    如果是单个请求,可以使用get方法

    let body = reqwest::get("https://www.rust-lang.org")
        .await?
        .text()
        .await?;
    
    println!("body = {:?}", body);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如果你还要进行其他的多个请求,最好创建个Client进行复用。

    2. 创建POST请求

    有以下几种方式你可以设置POST请求体(body)。

    1.最基本的方法就是使用RequestBuilder的body方法。只需要设置body的原始数据就好。它接收各种类型,包括String和Vec。如果你想自定义类型,你可以使用reqwest::Body结构。

    let client = reqwest::Client::new();
    let res = client.post("http://httpbin.org/post")
        .body("the exact body that is sent")
        .send()
        .await?;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2. 表单

    在请求体中发送表单数据是非常常见的。这可以使用任何可以序列化为表单数据的类型来完成。他的类型可以是元组,也可以是HashMap,或者自定义类型,只要你实现了Serialize特质。

    // 请求体是`foo=bar&baz=quux`
    let params = [("foo", "bar"), ("baz", "quux")];
    let client = reqwest::Client::new();
    let res = client.post("http://httpbin.org/post")
        .form(&params)
        .send()
        .await?;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3. JSON格式

    RequestBuilder上还有一个json方法工具,其工作方式与表单方法类似。它可以接受任何可以序列化为JSON的值。JSON功能是非常有必要的。

    // 请求体 `{"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?;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4. 重定向

    默认Client会自动的处理重定向,,最大重定向链为10跳。要想自定义这个行为,可以“redirect::Policy”与“ClientBuilder”一起使用。

    一个URL,重定向到另一个URL,若是直接跳转,为1跳;若其中夹着一个中转,那么就是2跳,中间夹着N个中转,那就是N+1跳。

    5. Cookies

    可以使用ClientBuilder上的cookie_store方法启用会话cookie的自动存储和发送。

    6. 代理

    系统代理默认是启用的

    如果你用的是Socks,代理http和https可以使用环境变量http_proxy和https_proxy来提供代理,你可以这么设置代理(仅Linux环境)

    export https_proxy=socks5://127.0.0.1:1086
    
    • 1

    如果你是Windows环境,那么可以用一个reqwest::Proxy结构体,例如

    let proxy = reqwest::Proxy::http("https://secure.example")?;
    
    • 1

    其中"https://secure.example"是个获取代理的URL。此代理会拦截所有请求,然后使用"https://secure.example"的代理。

    可以为客户端配置多个代理规则。客户端将按照添加的顺序检查每个代理。这可能意味着,首先添加带有优先拦截规则的代理,如Proxy::all,将阻止列表中后面的代理工作,因此请小心。

    启用socks代理

    let proxy = reqwest::Proxy::http("socks5://192.168.1.1:9000")?;
    
    • 1

    7. 使用阻塞请求

    阻塞客户端将阻塞要当前线程的执行,而不是直接返回继续执行。但是reqwest::blocking中的功能不能在异步运行时内执行,否则在尝试阻塞时会死机。

    在项目的 Cargo.toml 中添加依赖:

    reqwest = { version = "0.11", features = ["blocking", "json"] }
    
    • 1

    然后代码这么写

    use std::collections::HashMap;
    
    fn main() -> Result<(), Box<dyn std::error::Error>> {
        let resp = reqwest::blocking::get("https://httpbin.org/ip")?
            .json::<HashMap<String, String>>()?;
        println!("{:#?}", resp);
        Ok(())
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 创建GET请求

    阻塞Response 结构体实现了Rust的Read特质,因此许多有用的标准库和第库都有方便的方法,可以在任何可以接受读取的地方获取响应。

    let body = reqwest::blocking::get("https://www.rust-lang.org")?
        .text()?;
    
    println!("body = {:?}", body);
    
    • 1
    • 2
    • 3
    • 4

    注意,如果你想要发多个请求,建议创建个Client

    2. 创建POST请求

    创建POST请求与非阻塞的基本上是一致的,但是如果你想自定义请求体类型的话,就需要使用reqwest::blocking::Body::new()构造方法,也是只有这里与非阻塞的不同,其他的请参考非阻塞的。

    let client = reqwest::blocking::Client::new();
    let res = client.post("http://httpbin.org/post")
        .body("the exact body that is sent")
        .send()?;
    
    • 1
    • 2
    • 3
    • 4

    总结

    本期内容学习了纯 Rust 编写的 HTTP 客户端——reqwest,学了其请求HTTP接口的一些方法,

    • 创建GET、POST请求
    • 使用代理
    • 重定向
    • 处理Cookies

    该库在各类编程语言中,基本上都属于比较重要的一部分,能够发起请求,就可以与web服务器进行交互,能够进行交互,就可以实现更多功能,它必将成为后续相当重要的一部分。

  • 相关阅读:
    语义分割研究现状
    Spring之事务实现原理及其注解@Transactional底层和传播机制原理
    c++ makefile + clangd 生成 compile_command.json
    牛客刷题总结——Python入门08:面向对象、正则表达式
    ICPC World Finals 2020 ‘S No Problem (树形dp) (k 条不相交路径覆盖最值问题)
    JWT(2):JWT入门使用
    42V转5V芯片——高效率、宽压输入范围和强大输出能力
    基于Springboot+Layui餐厅点餐系统
    文件上传漏洞
    计算机毕业设计选题推荐-个人健康微信小程序/安卓APP-项目实战
  • 原文地址:https://blog.csdn.net/weixin_47754149/article/details/126651896