Skip to content Skip to sidebar Skip to footer

Fetch Api Default Cross-origin Behavior

The Fetch Specifications say that the default Fetch mode is 'no-cors' - A request has an associated mode, which is 'same-origin', 'cors', 'no-cors', 'navigate', or 'websocket'. U

Solution 1:

For cross-origin requests, the Fetch algorithm sets the “response tainting” for the request to cors and requires the fetch to be performed using the CORS protocol.

Specifically, see the following substeps of step 12 of the “Main fetch” algorithm:

request’s current url’s origin is same origin with request’s origin and CORS flag is unsetrequest’s current url’s scheme is "data"request’s mode is "navigate" or "websocket" 1. Set request’s response tainting to "basic". 2. Return the result of performing a scheme fetch using request. … ↪ request’s mode is "no-cors" 1. Set request’s response tainting to "opaque". 2. Return the result of performing a scheme fetch using request. … ↪ Otherwise 1. Set request’s response tainting to "cors". 2. Return the result of performing an HTTP fetch using request with CORS flag set.

What it amounts to is, if the request URL isn’t same-origin with your code’s origin, and the scheme isn’t data and the mode isn’t navigate or websocket or isn’t explicitly set to no-cors, then that Otherwise condition gets reached, and the request gets made using the CORS protocol.

That explanation simplifies things a bit because in the case where the request has characteristics that trigger the browser to do a preflight, there’s a substep just above that Otherwise substep that gets reached instead—but again in that case, the “response tainting” gets set to cors.

But, I seem to be noticing this behavioral difference between mode: 'no-cors' and an unspecified mode.

The difference is because when you explicitly set mode: 'no-cors' for the request, in that case the “↪ request’s mode is "no-cors"” substep gets reached instead of the Otherwise substep.

(Though I think maybe the spec could be refined to make it more clear that the mode at that point doesn’t actually just default to no-cors—which is what you might otherwise conclude based on the “Unless stated otherwise, it is "no-cors"” statement from the spec cited in the question.)

As demonstrated in this JSFiddle sample, explicitly defining mode as 'no-cors' makes the response inaccessible to the Javascript,

Right—that’s because it causes the “↪ request’s mode is "no-cors"” substep in the “Main fetch” algorithm to get reached instead of the Otherwise substep.

while not specifying a mode makes the Response object available to the calling method.

Because the Otherwise substep does then get reached, so a CORS-enabled fetch gets performed.

Does explicitly specifying the fetch mode work differently from the default behavior that internally uses the same mode?

Yes, for a cross-origin request, explicitly setting mode: 'no-cors' forces the request to be made without using CORS, while leaving it unspecified causes it to be made using CORS.

But as mentioned above, I think maybe the spec should get refined to be a bit more clear on this.

I think that “Unless stated otherwise, it is "no-cors"” statement about the mode definitely isn’t meant to specify that requests that get made using the fetch(…) method without an explicit mode specified end up having their mode locked into no-cors.

Post a Comment for "Fetch Api Default Cross-origin Behavior"