发起 GET 请求

use reqwest::Client;
use tokio;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建 reqwest 客户端
    let client = Client::new();

    // 发起 GET 请求
    let response = client.get("https://jsonplaceholder.typicode.com/posts/1")
        .send()
        .await?;

    // 检查响应状态
    if response.status().is_success() {
        // 读取响应体
        let body = response.text().await?;
        println!("Response body: {}", body);
    } else {
        println!("Failed to fetch data. Status: {}", response.status());
    }

    Ok(())
}

发起 POST 请求

use reqwest::Client;
use serde_json::json;
use tokio;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建 reqwest 客户端
    let client = Client::new();

    // 构建请求体
    let payload = json!({
        "title": "foo",
        "body": "bar",
        "userId": 1
    });

    // 发起 POST 请求
    let response = client.post("https://jsonplaceholder.typicode.com/posts")
        .json(&payload)
        .send()
        .await?;

    // 检查响应状态
    if response.status().is_success() {
        // 读取响应体
        let body = response.text().await?;
        println!("Response body: {}", body);
    } else {
        println!("Failed to post data. Status: {}", response.status());
    }

    Ok(())
}

设置超时

use reqwest::Client;
use std::time::Duration;
use tokio;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建 reqwest 客户端,设置全局超时
    let client = Client::builder()
        .timeout(Duration::from_secs(10))
        .build()?;

    // 发起请求,单独设置请求超时
    let response = client.get("https://jsonplaceholder.typicode.com/posts/1")
        .timeout(Duration::from_secs(5))
        .send()
        .await?;

    let body = response.text().await?;
    println!("Response body: {}", body);

    Ok(())
}

添加自定义头

use reqwest::Client;
use reqwest::header::{HeaderMap, HeaderValue, USER_AGENT};
use tokio;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new();

    // 创建头信息
    let mut headers = HeaderMap::new();
    headers.insert(USER_AGENT, HeaderValue::from_static("my-awesome-agent/1.0"));

    // 发起请求时附加头
    let response = client.get("https://jsonplaceholder.typicode.com/posts/1")
        .headers(headers)
        .send()
        .await?;

    let body = response.text().await?;
    println!("Response body: {}", body);

    Ok(())
}

处理 JSON 响应

use reqwest::Client;
use serde::Deserialize;
use tokio;

#[derive(Debug, Deserialize)]
struct Post {
    userId: i32,
    id: i32,
    title: String,
    body: String,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new();
    let response = client.get("https://jsonplaceholder.typicode.com/posts/1")
        .send()
        .await?;

    // 解析 JSON 响应体
    if response.status().is_success() {
        let post: Post = response.json().await?;
        println!("Post: {:?}", post);
    } else {
        println!("Failed to fetch data. Status: {}", response.status());
    }

    Ok(())
}

文件上传

use reqwest::Client;
use tokio;
use std::fs::File;
use std::path::Path;
use reqwest::multipart;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建 reqwest 客户端
    let client = Client::new();

    // 创建上传文件的路径
    let file_path = Path::new("path/to/your/file.txt");
    // 打开文件
    let file = File::open(file_path)?;

    // 创建 multipart/form-data 请求体
    let form = multipart::Form::new()
        .file("file", file_path)?;

    // 发起 POST 文件上传请求
    let response = client.post("https://example.com/upload")
        .multipart(form)
        .send()
        .await?;

    if response.status().is_success() {
        let body = response.text().await?;
        println!("File uploaded successfully: {}", body);
    } else {
        println!("Failed to upload file. Status: {}", response.status());
    }

    Ok(())
}

文件下载

use reqwest::Client;
use tokio;
use tokio::fs::File;
use tokio::io::AsyncWriteExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建 reqwest 客户端
    let client = Client::new();

    // 发起 GET 请求下载文件
    let response = client.get("https://example.com/file.txt")
        .send()
        .await?;

    // 检查响应状态
    if response.status().is_success() {
        // 打开文件,准备写入
        let mut file = File::create("downloaded_file.txt").await?;
        let mut stream = response.bytes_stream();

        // 将响应体逐渐写入文件
        while let Some(chunk) = stream.next().await {
            let chunk = chunk?;
            file.write_all(&chunk).await?;
        }

        println!("File downloaded successfully");
    } else {
        println!("Failed to download file. Status: {}", response.status());
    }

    Ok(())
}

使用代理

use reqwest::Client;
use tokio;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建带代理的 reqwest 客户端
    let proxy = reqwest::Proxy::all("http://proxy:8080")?;
    let client = Client::builder()
        .proxy(proxy)
        .build()?;

    // 发起 GET 请求
    let response = client.get("https://jsonplaceholder.typicode.com/posts/1")
        .send()
        .await?;

    if response.status().is_success() {
        let body = response.text().await?;
        println!("Response body: {}", body);
    } else {
        println!("Failed to fetch data. Status: {}", response.status());
    }

    Ok(())
}

请求重试

use reqwest::Client;
use tokio;
use std::time::Duration;

async fn fetch_with_retry(client: &Client, url: &str, retries: u32) -> Result<String, reqwest::Error> {
    let mut attempts = 0;
    
    while attempts < retries {
        attempts += 1;
        let response = client.get(url).send().await;

        match response {
            Ok(res) if res.status().is_success() => {
                return res.text().await;
            }
            Ok(_) | Err(_) if attempts < retries => {
                println!("Attempt {} failed, retrying...", attempts);
                tokio::time::sleep(Duration::from_secs(2)).await;
            }
            Err(err) => return Err(err),
        }
    }

    Err(reqwest::Error::new(reqwest::StatusCode::REQUEST_TIMEOUT, "Exceeded max retries"))
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建 reqwest 客户端
    let client = Client::new();

    // 发起带重试的 GET 请求
    let url = "https://jsonplaceholder.typicode.com/posts/1";
    match fetch_with_retry(&client, url, 3).await {
        Ok(body) => println!("Response body: {}", body),
        Err(err) => println!("Failed to fetch data. Error: {}", err),
    }

    Ok(())
}

使用 Cookies

use reqwest::Client;
use reqwest::cookie::Jar;
use reqwest::Url;
use std::sync::Arc;
use tokio;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建一个 Cookie jar
    let cookie_jar = Jar::default();
    let cookie_jar = Arc::new(cookie_jar);

    // 创建带 Cookie jar 的 reqwest 客户端
    let client = Client::builder()
        .cookie_store(true)
        .cookie_provider(cookie_jar.clone())
        .build()?;

    // 发起 GET 请求
    let url = Url::parse("https://jsonplaceholder.typicode.com/posts/1")?;
    let response = client.get(url.clone()).send().await?;
    
    if response.status().is_success() {
        let body = response.text().await?;
        println!("Response body: {}", body);
    } else {
        println!("Failed to fetch data. Status: {}", response.status());
    }

    // 查看所存储的 cookies
    let cookies = cookie_jar.cookies(&url);
    for cookie in cookies.iter() {
        println!("Cookie: {}", cookie);
    }

    Ok(())
}

处理并发请求

use reqwest::Client;
use tokio;
use futures::future::join_all;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建 reqwest 客户端
    let client = Client::new();

    let urls = vec![
        "https://jsonplaceholder.typicode.com/posts/1",
        "https://jsonplaceholder.typicode.com/posts/2",
        "https://jsonplaceholder.typicode.com/posts/3",
    ];

    let requests: Vec<_> = urls.into_iter().map(|url| client.get(url).send()).collect();

    // 执行并发请求
    let responses = join_all(requests).await;

    for response in responses {
        match response {
            Ok(res) if res.status().is_success() => {
                let body = res.text().await?;
                println!("Response body: {}", body);
            }
            Ok(res) => println!("Failed to fetch data. Status: {}", res.status()),
            Err(err) => println!("Request failed: {:?}", err),
        }
    }

    Ok(())
}

处理重定向

use reqwest::Client;
use tokio;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::builder()
        .redirect(reqwest::redirect::Policy::limited(3))
        .build()?;

    let response = client.get("http://httpbin.org/absolute-redirect/5")
        .send()
        .await?;

    println!("Final destination: {}", response.url());
    println!("Response body: {}", response.text().await?);

    Ok(())
}

使用自签名证书

use reqwest::Client;
use tokio;
use reqwest::Certificate;
use std::fs;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 读取 CA 证书文件
    let cert = fs::read("path/to/your/ca_cert.pem")?;
    let cert = Certificate::from_pem(&cert)?;

    let client = Client::builder()
        .add_root_certificate(cert)
        .build()?;

    let response = client.get("https://your-secure-server.com")
        .send()
        .await?;

    println!("Response body: {}", response.text().await?);

    Ok(())
}

处理表单数据

use reqwest::Client;
use tokio;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new();

    let params = [("key1", "value1"), ("key2", "value2")];

    let response = client.post("https://httpbin.org/post")
        .form(&params)
        .send()
        .await?;

    if response.status().is_success() {
        println!("Response body: {}", response.text().await?);
    } else {
        println!("Failed to send form data. Status: {}", response.status());
    }

    Ok(())
}

putao
8 声望1 粉丝

推动世界向前发展,改善民生。


« 上一篇
axum--代码案例
下一篇 »
numbers_parser