You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用reqwest解析StackExchange API JSON时触发解析错误排查

解决StackExchange API JSON解析的Decode错误

问题根源

StackExchange API返回的响应采用了gzip压缩,但reqwest默认不会自动处理这类压缩内容。当你直接调用response.json()时,实际上是在解析压缩后的二进制数据,而非可读的JSON文本,因此会触发expected value, line: 1, column: 1的解析错误。

修复方案

方案1:启用客户端自动解压缩

创建reqwest客户端时开启gzip/deflate支持,让客户端自动处理压缩响应:

#[get("/test")]
async fn my_function(username: web::Query<QueryParams>) -> impl Responder {
    println!("recieved!");
    
    // 构建支持自动解压缩的客户端
    let client = match reqwest::Client::builder()
        .gzip(true)
        .deflate(true)
        .build() {
            Ok(c) => c,
            Err(_) => return HttpResponse::InternalServerError().finish(),
        };

    match client.get("https://api.stackexchange.com/2.2/users/13029516?&site=stackoverflow").await {
        Ok(response) => {
            if !response.status().is_success() {
                return HttpResponse::InternalServerError().finish();
            }

            match response.json::<serde_json::Value>().await {
                Ok(res) => println!("Success! {:?}", res),
                Err(e) => {
                    eprintln!("JSON解析失败: {}", e);
                    return HttpResponse::InternalServerError().finish();
                }
            }
        }
        Err(e) => {
            eprintln!("API请求失败: {}", e);
            return HttpResponse::InternalServerError().finish();
        }
    };

    HttpResponse::Ok().finish()
}

方案2:手动解压缩响应内容

如果不想修改客户端配置,可以手动读取响应字节并使用flate2库解压缩:

use flate2::read::GzDecoder;
use std::io::Read;

#[get("/test")]
async fn my_function(username: web::Query<QueryParams>) -> impl Responder {
    println!("recieved!");

    match reqwest::get("https://api.stackexchange.com/2.2/users/13029516?&site=stackoverflow").await {
        Ok(response) => {
            if !response.status().is_success() {
                return HttpResponse::InternalServerError().finish();
            }

            // 读取原始响应字节
            let bytes = match response.bytes().await {
                Ok(b) => b,
                Err(_) => return HttpResponse::InternalServerError().finish(),
            };

            // 解压缩gzip内容
            let mut decoder = GzDecoder::new(&bytes[..]);
            let mut json_content = String::new();
            if decoder.read_to_string(&mut json_content).is_err() {
                return HttpResponse::InternalServerError().finish();
            }

            // 解析JSON
            let res = match serde_json::from_str::<serde_json::Value>(&json_content) {
                Ok(r) => r,
                Err(_) => return HttpResponse::InternalServerError().finish(),
            };

            println!("Success! {:?}", res);
        }
        Err(_) => return HttpResponse::InternalServerError().finish(),
    };

    HttpResponse::Ok().finish()
}

注意事项

  • 替换代码中的unwrap()为错误处理逻辑,避免不必要的panic
  • 可以通过检查响应头Content-Encoding的值,判断是否需要解压缩响应内容

内容的提问来源于stack exchange,提问作者Matthew Trent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 05:54:58