tldr; How are opaque responses distinguishable from a network error when sending a fetch request with mode: 'no-cors'?
I believe:
- opaque responses fail silently - fetch resolves
- network errors fail the fetch - fetch rejects
Can anyone confirm? (Edit: Same approach as used here)
Background: From my UI I want to check if various urls are reachable (e.g. that they are not blocked by firewall). In this answer: https://stackoverflow.com/a/53442328/1534823 it says:
no-cors mode means that if the browser has to do anything that requires permission from CORS, it will fail silently instead of throwing an error.
Question:
If a fetch request with 'no-cors' header:
- ... encounters a network error - will this cause the fetch promise to reject?
- ... encounters a CORS issue - it will fail silently, i.e. the fetch promise will resolve?
Documentation:
Pro: In chrome dev-tools I can simulate network errors by blocking domains, which seems to indicate the above 2 statements are true - but I am not sure how reliably that reflects real-life network errors.
Contra: These docs fail to mention that CORS exceptions also throw a TypeError for the fetch: https://developer.mozilla.org/en-US/docs/Web/API/fetch#exceptions
Contra: In the fetch spec: https://fetch.spec.whatwg.org/#concept-filtered-response-opaque it says:
In other words, an opaque filtered response and an opaque-redirect filtered response are nearly indistinguishable from a network error.
... or can I use the CORS preflight request somehow to check if a server which disallows CORS is reachable? (or just send an OPTIONS request?)
There are many questions here.
You are correct that an opaque response does not result in rejection of the promise. However, a CORS failure results in a network error, not an opaque response. However, you cannot get a CORS failure if you use "
no-cors" (note that this is not a header, it's an input to aRequestobject).With "
no-cors" you are restricted in the HTTP methods you can use, soOPTIONSis not an option (no joke). Browsers are also increasingly putting limits on what "no-cors" can reach as these responses are problematic in a world with Spectre. https://github.com/annevk/orb has more details on this. So long term usingfetch(url, { mode: "no-cors" })will probably not get you what you want as you will increasingly see more network errors, despite the server potentially being reachable.