提问人:Matthew Trent 提问时间:5/2/2023 更新时间:5/2/2023 访问量:234
无法从 StackAPI 解析 JSON:预期值“,行:1,列:1
Can't parse JSON from StackAPI: expected value", line: 1, column: 1
问:
我正在尝试从这个端点解析 JSON:https://api.stackexchange.com/2.2/users/13029516?&site=stackoverflow。
它看起来像这样:
{
"items": [
{
"badge_counts": {
"bronze": 27,
"silver": 14,
"gold": 0
},
"account_id": 17932441,
"is_employee": false,
"last_modified_date": 1677242400,
"last_access_date": 1682981080,
"reputation_change_year": 313,
"reputation_change_quarter": 29,
"reputation_change_month": 0,
"reputation_change_week": 10,
"reputation_change_day": 0,
"reputation": 2234,
"creation_date": 1583703647,
"user_type": "registered",
"user_id": 13029516,
"website_url": "https://matthewtrent.me/links",
"link": "https://stackoverflow.com/users/13029516/matthew-trent",
"profile_image": "https://lh3.googleusercontent.com/a/AATXAJwHVeuBCVo52xa3k_IryQ1llGDNWkHRYiO0R2xh=k-s256",
"display_name": "Matthew Trent"
}
],
"has_more": false,
"quota_max": 300,
"quota_remaining": 271
}
但我不能。我正在使用该软件包。这是我使用它的端点(简化):reqwest
#[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() != 200 {
return HttpResponse::InternalServerError().finish();
} else {
let res = response.json::<serde_json::Value>().await.unwrap(); // <-- where it panics
println!("Success! {:?}", res);
}
}
Err(_) => return HttpResponse::InternalServerError().finish(),
};
HttpResponse::Ok().finish()
}
它对线感到恐慌.奇怪的是,我命中了不同的端点(例如:),它运行良好并列出了 JSON 结果。我唯一的猜测是 Stack API 的 JSON 格式不正确?let res = response.json::<serde_json::Value>().await.unwrap();
https://pokeapi.co/api/v2/pokemon/ditto
这是我针对 https://api.stackexchange.com/2.2/users/13029516?&site=stackoverflow 运行它时的输出:
recieved!
thread 'actix-rt|system:0|arbiter:0' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
recieved!
thread 'actix-rt|system:0|arbiter:1' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
recieved!
thread 'actix-rt|system:0|arbiter:2' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
recieved!
thread 'actix-rt|system:0|arbiter:3' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
recieved!
thread 'actix-rt|system:0|arbiter:4' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
recieved!
thread 'actix-rt|system:0|arbiter:5' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
recieved!
thread 'actix-rt|system:0|arbiter:6' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
recieved!
thread 'actix-rt|system:0|arbiter:7' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
recieved!
thread 'actix-rt|system:0|arbiter:0' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
任何帮助都会很棒,谢谢。
答:
此操作失败,因为 Stack Exchange API 不完全遵循 HTTP 规范。
虽然我们的 API 是基于 HTTP 的,但我们选择在一个特定领域与标准 HTTP 不同。在正常操作期间,我们保证所有响应都使用 GZIP 或 DEFLATE 进行压缩。
如果检查请求和响应标头,您将看到 API 返回 尽管 reqwest 未发送包含 .Content-Encoding: gzip
Accept-Encoding
gzip
Reqwest 决定忽略未知编码并尝试读取它,从而导致垃圾数据。
幸运的是,您可以启用 reqwest 功能,以便它既可以发送标头,也可以解码 GZIP 编码的响应。如果您想使用 DEFLATE,还有一个功能。gzip
Accept-Encoding: gzip
deflate
[dependencies]
reqwest = { verson = "0.11", features = ["json", "gzip", "deflate"] }
还可以在运行时使用 ClientBuilder::gzip
方法关闭此行为。
评论
.text()
gzip
reqwest
deflate