Problem
Webassembly is sending a post req to an actix web server, but actix web says it cannot deserialize the json body.
In terminal (for actix web) you can see the error message of
Failed to deserialize Json from payload. Request path: /api
Error in response: Deserialize(Error("expected value", line: 1, column: 2))
And in javascript console
Response { url: "http://localhost:8080/api", status: 400, statusText: "Bad Request", /* ... */ }
I have tried sending the same request using curl, and it worked. So there is clearly something wrong with the request the wasm is sending, but I'm not sure what
curl --header "Content-Type: application/json" \ :(
--request POST \
--data '{"field1": "one", "field2": "two", "field3": "three"}' \
http://localhost:8080/api
Here's the code sending the request (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);
and here's the server receiving the request
#[post("/api")]
async fn api(body: Json<Req>) -> String {
format!("{body:?}")
}
#[derive(Debug, Deserialize)]
struct Req {
field1: String,
field2: String,
field3: String,
}
Here's how to reproduce the issue:
git clone https://github.com/Siriusmart/dummy-repo-for-asking-stackoverflow
wasm-pack build --target web wasm
to recompile the web assembly first
then cargo run
to start the server
visit http://localhost:8080 to see the site with wasm.
When the button is pressed, there should be output to the js console, saying that its a bad request, at the same time there will also be an error message in the actix web console.
The goal is to make it so that the wasm actually sends a good request to the server.
serde_wasm_bindgen
serializes Req
to a JS object, and that is what fetch()
gets. I think it calls toString()
on it, resulting it [object Object]
(not entirely sure), but this is definitely not sending JSON.
You need to serialize the data to JSON yourself, for example via serde_json
then call JsValue: From<String>
or by serializing it to JS object with serde_wasm_bindgen
then calling JSON.stringify()
on it.