使用reqwest和serde_json在Rust中解析JSON遇解码错误求助
解决reqwest解析JSON时的Decode错误
错误原因
你遇到的Error("expected value", line: 1, column: 1)错误,本质是响应内容编码不匹配导致的:
- reqwest的
json()方法默认以UTF-8编码解析响应体,但目标API返回的内容是Windows-1256编码(波斯地区常用编码) - 用UTF-8解码非UTF-8的字节会产生乱码,serde_json无法识别乱码内容为有效的JSON结构,因此抛出解析失败的错误
解决方案
步骤1:添加编码处理依赖
修改Cargo.toml,新增encoding_rs用于编码转换:
[package] name = "rust_workspace" version = "0.1.0" edition = "2021" [dependencies] serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } reqwest = { version = "0.11", features = ["json", "blocking"] } tokio = { version = "1", features = ["full"] } bytes = "1" encoding_rs = "0.8" # 新增编码转换依赖
步骤2:修改代码,手动处理编码转换
先获取原始响应字节,将其从Windows-1256转换为UTF-8后再解析JSON:
#[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { // 获取原始响应字节,跳过默认的UTF-8解码 let bytes = reqwest::get("https://tse.ir/json/MarketWatch/data_7.json") .await? .bytes() .await?; // 将Windows-1256编码的字节转换为UTF-8字符串 let (utf8_content, _, _) = encoding_rs::WINDOWS_1256.decode(&bytes); let utf8_str = utf8_content.to_string(); // 解析UTF-8格式的JSON内容 let resp: serde_json::Value = serde_json::from_str(&utf8_str)?; println!("{:#?}", resp); Ok(()) }
更鲁棒的版本:从响应头自动提取编码
如果API的编码可能变化,可以从响应头的Content-Type字段自动获取编码,无需硬编码:
#[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { let resp = reqwest::get("https://tse.ir/json/MarketWatch/data_7.json").await?; // 从Content-Type头中提取编码信息 let charset = resp.headers() .get(reqwest::header::CONTENT_TYPE) .and_then(|ct| ct.to_str().ok()) .and_then(|ct| { ct.split(';') .find(|part| part.trim().starts_with("charset=")) .map(|part| part.trim().split('=').nth(1).unwrap_or_default()) }); // 获取原始响应字节 let bytes = resp.bytes().await?; // 根据编码转换为UTF-8 let utf8_str = match charset { Some("windows-1256") => encoding_rs::WINDOWS_1256.decode(&bytes).0.to_string(), // 可扩展支持其他编码类型 _ => String::from_utf8_lossy(&bytes).to_string(), }; // 解析JSON let resp: serde_json::Value = serde_json::from_str(&utf8_str)?; println!("{:#?}", resp); Ok(()) }
验证说明
目标API的响应头明确标注了Content-Type: application/json; charset=windows-1256,因此直接指定Windows-1256编码转换是最准确的方式。转换后的UTF-8字符串可以被serde_json正常解析,彻底解决报错问题。
内容的提问来源于stack exchange,提问作者Picinfiniti
相关产品推荐
相关产品推荐

