问题
Webassembly 正在向 actix web 服务器发送 post req,但 actix web 表示它无法反序列化 json 主体。
在终端(对于actix web)你可以看到错误信息
Failed to deserialize Json from payload. Request path: /api
Error in response: Deserialize(Error("expected value", line: 1, column: 2))
在 javascript 控制台中
Response { url: "http://localhost:8080/api", status: 400, statusText: "Bad Request", /* ... */ }
我已经尝试使用 curl 发送相同的请求,并且成功了。所以 wasm 发送的请求显然有问题,但我不确定是什么
curl --header "Content-Type: application/json" \ :(
--request POST \
--data '{"field1": "one", "field2": "two", "field3": "three"}' \
http://localhost:8080/api
这是发送请求的代码(web assembly)
let _ = window
.fetch_with_str_and_init("/api", &RequestInit::new().method("POST").headers(&headers).body(Some(&serde_wasm_bindgen::to_value(&req).unwrap())))
.then(&ok);
这是接收请求的服务器
#[post("/api")]
async fn api(body: Json<Req>) -> String {
format!("{body:?}")
}
#[derive(Debug, Deserialize)]
struct Req {
field1: String,
field2: String,
field3: String,
}
重现问题的方法如下:
git clone https://github.com/Siriusmart/dummy-repo-for-asking-stackoverflow
wasm-pack build --target web wasm
先重新编译 web assembly
然后
cargo run
启动服务器
访问 http://localhost:8080 以查看带有 wasm 的站点。
按下按钮时,js控制台应该有输出,说这是一个错误的请求,同时actix web控制台也会有错误信息。
目标是让 wasm 真正向服务器发送一个好的请求。
serde_wasm_bindgen
将 Req
序列化为 JS 对象,这就是 fetch()
得到的结果。我认为它调用了 toString()
,结果是 [object Object]
(不完全确定),但这绝对不是发送 JSON。
您需要自己将数据序列化为 JSON,例如通过
serde_json
然后调用 JsValue: From<String>
或使用 serde_wasm_bindgen
将其序列化为 JS 对象然后在其上调用 JSON.stringify()
。