I copied the web-sys fetch from the documentation but changed the URL to fetch a json file from a local nginx server. And the Accept to "application/json"
In the browser network trace I see the correct data, but in the rust code(WASM), I receive back an opaque response.
Why does this happen and how do I fix it
In Javascript, fetch
doesn't return JSON either, it returns Response
. You're expected to call Response::json
explicitly, if you need JSON.
That is the problem, the return is a response is of type opaque, that has no JSON body,
''' rust
#[wasm_bindgen]
pub async fn read_budget() -> Result<JsValue, JsValue> {
let opts = RequestInit::new();
opts.set_method("GET");
opts.set_mode(RequestMode::NoCors);
let url = format!("http://10.0.42.170/data/tst.json");
let request = Request::new_with_str_and_init(&url, &opts)?;
request
.headers()
.set("Accept", "application/json")?;
let window = web_sys::window().unwrap();
let resp_value = JsFuture::from(window.fetch_with_request(&request)).await?;
console::log_1(&resp_value);
// `resp_value` is a `Response` object.
assert!(resp_value.is_instance_of::<Response>());
let resp: Response = resp_value.dyn_into().unwrap();
console::log_1(&JsValue::from(resp.status()));
// Convert this other `Promise` into a rust `Future`.
let json = JsFuture::from(resp.json()?).await?;
let data = JsValue::from(&json);
console::log_1(&data);
Ok(json)
}
'''
Could you share the output of this example?
After awaiting the Promise, cast its return value to Response
and call its json
method: wasm-bindgen/examples/fetch/src/lib.rs at main · rustwasm/wasm-bindgen · GitHub
Response { type: "opaque", url: "", redirected: false, status: 0, ok: false, statusText: "", headers: Headers(0), body: null, bodyUsed: false }
wasmtst_bg.wasm:31514:2147483821
0 wasmtst_bg.wasm:31514:2147483821
[Vue warn]: Unhandled error during execution of setup function at at runtime-core.esm-bundler.js:51:12
Uncaught (in promise) SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data
This means that the called server didn't send any data in response.
Here is the response network traffic using the browser developer tools
The data is getting to the browser, It may not look like it but it is JSON in the browser. the copy sucks.
0 | Object { agencycode: 1, agencyname: "A1", bureaucode: 0, … } |
1 | Object { agencycode: 1, agencyname: "A1", bureaucode: 0, … } |
2 | Object { agencycode: 1, agencyname: "A1", bureaucode: 0, … } |
3 | Object { agencycode: 1, agencyname: "A1", bureaucode: 0, … } |
4 | Object { agencycode: 1, agencyname: "A1", bureaucode: 1, … } |
5 | Object { agencycode: 1, agencyname: "A1", bureaucode: 1, … } |
6 | Object { agencycode: 1, agencyname: "A1", bureaucode: 2, … } |
7 | Object { agencycode: 1, agencyname: "A1", bureaucode: 2, … } |
8 | Object { agencycode: 2, agencyname: "A2", bureaucode: 1, … } |
9 | Object { agencycode: 2, agencyname: "A2", bureaucode: 1, … } |
10 | Object { agencycode: 2, agencyname: "A2", bureaucode: 1, … } |
11 | Object { agencycode: 2, agencyname: "A2", bureaucode: 2, … } |
12 | Object { agencycode: 2, agencyname: "A2", bureaucode: 2, … } |
13 | Object { agencycode: 3, agencyname: "A3", bureaucode: 1, … } |
14 | Object { agencycode: 4, agencyname: "A4", bureaucode: 1, … } |
15 | Object { agencycode: 4, agencyname: "A4", bureaucode: 1, … } |
16 | Object { agencycode: 4, agencyname: "A4", bureaucode: 2, … } |
Here are the headers
|GET|http://10.0.42.170/data/tst.json|
Status
200
OK
VersionHTTP/1.1
Transferred14.01 kB (13.73 kB size)
Referrer Policystrict-origin-when-cross-origin
Accept-Ranges | bytes |
Access-Control-Allow-Origin | * |
---|---|
Connection | keep-alive |
Content-Length | 13730 |
Content-Type | application/json |
Date | Fri, 22 Nov 2024 21:49:00 GMT |
ETag | "6740b936-35a2" |
Last-Modified | Fri, 22 Nov 2024 17:02:46 GMT |
Server | nginx/1.22.1 |
Accept | application/json |
Accept-Encoding | gzip, deflate |
---|---|
Accept-Language | en-US,en;q=0.5 |
Cache-Control | no-cache |
Connection | keep-alive |
DNT | 1 |
Host | 10.0.42.170 |
Pragma | no-cache |
Referer | http://10.0.42.170:5173/ |
User-Agent | Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0 |
I tested it using chromium fails the same way
I created a wasm-pack test routine using wasm-pack new
I created a test using the same code but replaced the ? with .expect(")
I am also running wire shark to see what is being transferred.
The wireshark trace looks good.
Here is the stack trace
panicked at tests/web.rs:37:80:
bad fetch: JsValue(TypeError: NetworkError when attempting to fetch resource.
)
Stack:
__wbg_get_imports/imports.wbg.__wbg_new_abda76e883ba8a5f/<@http://localhost:8000/wasm-bindgen-test:595:21
logError@http://localhost:8000/wasm-bindgen-test:196:18
__wbg_get_imports/imports.wbg.__wbg_new_abda76e883ba8a5f@http://localhost:8000/wasm-bindgen-test:594:66
web-64d6174f6066e4ba.wasm.__wbg_new_abda76e883ba8a5f externref shim@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[1815]:0x7d121
web-64d6174f6066e4ba.wasm.console_error_panic_hook::Error::new::h83fd7e780f6f4c9d@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[1065]:0x72e03
web-64d6174f6066e4ba.wasm.console_error_panic_hook::hook_impl::he3645b0fb698cd86@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[324]:0x4fe98
web-64d6174f6066e4ba.wasm.console_error_panic_hook::hook::h2ab256b314cffeb0@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[1511]:0x7a281
web-64d6174f6066e4ba.wasm.wasm_bindgen_test::__rt::Context::new::{{closure}}::{{closure}}::h29a025713ebbd6af@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[904]:0x6eee2
web-64d6174f6066e4ba.wasm.std::panicking::rust_panic_with_hook::he5c089ac7305193e@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[588]:0x6273f
web-64d6174f6066e4ba.wasm.std::panicking::begin_panic_handler::{{closure}}::h010c94f3a1c5c766@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[763]:0x6a520
web-64d6174f6066e4ba.wasm.std::sys::backtrace::__rust_end_short_backtrace::hbe714695da4edadc@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[1912]:0x7d70e
web-64d6174f6066e4ba.wasm.rust_begin_unwind@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[1127]:0x7426a
web-64d6174f6066e4ba.wasm.core::panicking::panic_fmt::hdc8d2d914c0710e4@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[1182]:0x752ff
web-64d6174f6066e4ba.wasm.core::result::unwrap_failed::hdbb420d9dacf5a62@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[853]:0x6d720
web-64d6174f6066e4ba.wasm.core::result::Result<T,E>::expect::h40c4623743245bf3@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[784]:0x6b1cc
web-64d6174f6066e4ba.wasm.web::read_budget::{{closure}}::h024b103f14d4b8d9@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[84]:0x20403
web-64d6174f6066e4ba.wasm.wasm_bindgen_test::__rt::Context::execute_async::{{closure}}::h63f2332d0b54d283@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[205]:0x41147
web-64d6174f6066e4ba.wasm.<wasm_bindgen_test::__rt::TestFuture<F> as core::future::future::Future>::poll::{{closure}}::{{closure}}::h5c4be7079d8aa184@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[674]:0x66aa9
web-64d6174f6066e4ba.wasm.wasm_bindgen::convert::closures::invoke0_mut::h64049cdf4b13df78@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[799]:0x6ba52
__wbg_adapter_59@http://localhost:8000/wasm-bindgen-test:293:10
cb0@http://localhost:8000/wasm-bindgen-test:520:28
window.__wbg_test_invoke@http://localhost:8000/:26:38
__wbg_get_imports/imports.wbg.__wbg_wbgtestinvoke_dee5435586186f6e/<@http://localhost:8000/wasm-bindgen-test:525:30
handleError@http://localhost:8000/wasm-bindgen-test:227:18
__wbg_get_imports/imports.wbg.__wbg_wbgtestinvoke_dee5435586186f6e@http://localhost:8000/wasm-bindgen-test:513:76
web-64d6174f6066e4ba.wasm.wasm_bindgen_test::__rt::__wbg_test_invoke::hf09c025864567b1b@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[359]:0x5327f
web-64d6174f6066e4ba.wasm.<wasm_bindgen_test::__rt::TestFuture<F> as core::future::future::Future>::poll::{{closure}}::h4a19e46c757c8810@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[706]:0x68121
web-64d6174f6066e4ba.wasm.scoped_tls::ScopedKey<T>::set::h727d5bb285444969@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[725]:0x68d60
web-64d6174f6066e4ba.wasm.<wasm_bindgen_test::__rt::TestFuture<F> as core::future::future::Future>::poll::hbf799d4334768054@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[125]:0x30142
web-64d6174f6066e4ba.wasm.<wasm_bindgen_test::__rt::ExecuteTests as core::future::future::Future>::poll::ha61ca5777b8718eb@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[71]:0x17d7b
web-64d6174f6066e4ba.wasm.wasm_bindgen_test::__rt::Context::run::{{closure}}::he75852ddeb37f233@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[261]:0x49082
web-64d6174f6066e4ba.wasm.wasm_bindgen_futures::future_to_promise::{{closure}}::{{closure}}::hd1a560c0a35f93fd@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[131]:0x31b08
web-64d6174f6066e4ba.wasm.wasm_bindgen_futures::task::singlethread::Task::run::h9bc9b6c900cb8f37@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[245]:0x46f92
web-64d6174f6066e4ba.wasm.wasm_bindgen_futures::queue::QueueState::run_all::h802a4384e6ae92f6@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[202]:0x40a6c
web-64d6174f6066e4ba.wasm.wasm_bindgen_futures::queue::Queue::new::{{closure}}::hbf7b2f1974ce990b@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[855]:0x6d7ef
web-64d6174f6066e4ba.wasm.<dyn core::ops::function::FnMut<(A,)>+Output = R as wasm_bindgen::closure::WasmClosure>::describe::invoke::h1ed8437f66ca251e@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[660]:0x6605c
web-64d6174f6066e4ba.wasm.closure186 externref shim@http://localhost:8000/wasm-bindgen-test_bg.wasm:wasm-function[1809]:0x7d0b5
__wbg_adapter_24@http://localhost:8000/wasm-bindgen-test:216:10
real@http://localhost:8000/wasm-bindgen-test:179:20
If you are still using the code in Web_sys fetch return opaque response, not JSON - #3 by greenpdx I already pointed out the solution. You're missing some important pieces that are already available in the fetch example in the web-sys
repo.
"NetworkError when attempting to fetch resource" is a different issue. Probably CORS headers missing on the response from the server you are connecting to.
The problem was NoCors. I changed it to Cors and it worked