Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve documentation for no-cors mode #36476

Merged
merged 2 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions files/en-us/web/api/fetch_api/using_fetch/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ See [Locked and disturbed streams](#locked_and_disturbed_streams) for more infor

### Setting headers

Request headers give the server information about the request: for example, the {{httpheader("Content-Type")}} header tells the server the format of the request's body. Many headers are set automatically by the browser and can't be set by a script: these are called {{glossary("Forbidden header name", "Forbidden header names")}}.
Request headers give the server information about the request: for example, the {{httpheader("Content-Type")}} header tells the server the format of the request's body.

To set request headers, assign them to the `headers` option.

Expand All @@ -155,7 +155,7 @@ const response = await fetch("https://example.org/post", {
});
```

If the `mode` option is set to `no-cors`, you can only set {{glossary("CORS-safelisted request header", "CORS-safelisted request headers")}}.
Many headers are set automatically by the browser and can't be set by a script: these are called {{glossary("Forbidden header name", "Forbidden header names")}}. If the {{domxref("Request.mode", "mode")}} option is set to `no-cors`, then the set of permitted headers is further restricted.

### Making POST requests

Expand All @@ -174,16 +174,18 @@ const response = await fetch("https://example.org/post", {

### Making cross-origin requests

Whether a request can be made cross-origin or not is determined by the value of the `mode` option. This may take one of three values: `cors`, `no-cors`, or `same-origin`.
Whether a request can be made cross-origin or not is determined by the value of the {{domxref("RequestInit", "", "mode")}} option. This may take one of three values: `cors`, `same-origin`, or `no-cors`.

- By default, `mode` is set to `cors`, meaning that if the request is cross-origin then it will use the [Cross-Origin Resource Sharing (CORS)](/en-US/docs/Web/HTTP/CORS) mechanism. This means that:
- For fetch requests the default value of `mode` is `cors`, meaning that if the request is cross-origin then it will use the [Cross-Origin Resource Sharing (CORS)](/en-US/docs/Web/HTTP/CORS) mechanism. This means that:

- if the request is a [simple request](/en-US/docs/Web/HTTP/CORS#simple_requests), then the request will always be sent, but the server must respond with the correct {{httpheader("Access-Control-Allow-Origin")}} header or the browser will not share the response with the caller.
- if the request is not a simple request, then the browser will send a [preflighted request](/en-US/docs/Web/HTTP/CORS#preflighted_requests) to check that the server understands CORS and allows the request, and the real request will not be sent unless the server responds to the preflighted request with the appropriate CORS headers.

- Setting `mode` to `same-origin` disallows cross-origin requests completely.

- Setting `mode` to `no-cors` means the request must be a simple request, which restricts the headers that may be set, and restricts methods to `GET`, `HEAD`, and `POST`.
- Setting `mode` to `no-cors` disables CORS for cross-origin requests. This restricts the headers that may be set, and restricts methods to GET, HEAD, and POST. The response is _opaque_, meaning that its headers and body are not available to JavaScript. Most of the time a website should not use `no-cors`: the main application of it is for certain service worker use cases.

See the reference documentation for {{domxref("RequestInit", "", "mode")}} for more details.

### Including credentials

Expand Down
44 changes: 22 additions & 22 deletions files/en-us/web/api/request/mode/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,32 @@ browser-compat: api.Request.mode

The **`mode`** read-only property of the {{domxref("Request")}}
interface contains the mode of the request (e.g., `cors`,
`no-cors`, `same-origin`, `navigate` or `websocket`.) This is used
`no-cors`, `same-origin`, or `navigate`.) This is used
sideshowbarker marked this conversation as resolved.
Show resolved Hide resolved
to determine if cross-origin requests lead to valid responses, and which properties of the response are readable.

To construct a request with a specific mode, pass the desired value as the {{domxref("RequestInit", "", "mode")}} option to the {{domxref("Request.Request()")}} constructor.

Note that setting particular modes, especially `no-cors`, places restrictions on the request methods and headers that may be used, and prevents JavaScript from accessing the response headers or body. See the documentation for {{domxref("RequestInit", "", "mode")}} for more details.

## Value

- A `RequestMode` value.

- : The associated _mode_, available values of which are:

- `same-origin`
- : If a request is made to another origin with this mode
set, the result is an error. You could use this to ensure that a request is always
being made to your origin.
- `no-cors`
- : Prevents the method from being anything other than `HEAD`, `GET` or `POST`, and the headers from being anything other than {{Glossary("CORS-safelisted request header", "CORS-safelisted request headers")}}.
If any ServiceWorkers intercept these requests, they may not add or override any headers except for those that are {{Glossary("CORS-safelisted request header", "CORS-safelisted request headers")}}.
In addition, JavaScript may not access any properties of the resulting {{domxref("Response")}}.
This ensures that ServiceWorkers do not affect the semantics of the Web and prevents security and privacy issues arising from leaking data across domains.
- `cors`
- : Allows cross-origin requests, for example to access various
APIs offered by 3rd party vendors. These are expected to adhere to the [CORS protocol](/en-US/docs/Web/HTTP/CORS). Only a [limited set](https://fetch.spec.whatwg.org/#concept-filtered-response-cors) of headers are exposed in the {{domxref("Response")}}, but the body is
readable.
- `navigate`
- : A mode for supporting navigation. The `navigate` value is intended to be used only by HTML navigation. A navigate request is created only while navigating between documents.
- `websocket`
- : A special mode used only when establishing a [WebSocket](/en-US/docs/Web/API/WebSockets_API) connection.
One of the following values:

- `same-origin`

- : Disallows cross-origin requests. If a request is made to another origin with this mode set, the result is an error.

- `no-cors`

- : Disables CORS for cross-origin requests. The response is _opaque_, meaning that its headers and body are not available to JavaScript.

- `cors`

- : If the request is cross-origin then it will use the [Cross-Origin Resource Sharing (CORS)](/en-US/docs/Web/HTTP/CORS) mechanism.

- `navigate`

- : A mode for supporting navigation. The `navigate` value is intended to be used only by HTML navigation. A navigate request is created only while navigating between documents.

### Default mode

Expand Down
20 changes: 16 additions & 4 deletions files/en-us/web/api/requestinit/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,26 @@ You can also construct a `Request` with a `RequestInit`, and pass the `Request`

- `mode` {{optional_inline}}

- : One of the following values:
- : Sets cross-origin behavior for the request. One of the following values:

- `same-origin`
- : Disallows cross-origin requests completely.

- : Disallows cross-origin requests. If a `same-origin` request is sent to a different origin, the result is a network error.

- `cors`
- : If the request is cross-origin then it will use the [Cross-Origin Resource Sharing (CORS)](/en-US/docs/Web/HTTP/CORS) mechanism.

- : If the request is cross-origin then it will use the [Cross-Origin Resource Sharing (CORS)](/en-US/docs/Web/HTTP/CORS) mechanism. Only {{glossary("CORS-safelisted response header", "CORS-safelisted response headers")}} are exposed in the response.

- `no-cors`
- : The request must be a [simple request](/en-US/docs/Web/HTTP/CORS#simple_requests), which restricts the headers that may be set to {{glossary("CORS-safelisted request header", "CORS-safelisted request headers")}}, and restricts methods to `GET`, `HEAD`, and `POST`.

- : Disables CORS for cross-origin requests. This option comes with the following restrictions:

- The method may only be one of `HEAD`, `GET` or `POST`.
- The headers may only be {{Glossary("CORS-safelisted request header", "CORS-safelisted request headers")}}, with the additional restriction that the {{httpheader("Range")}} header is also not allowed. This also applies to any headers added by service workers.
- The response is _opaque_, meaning that its headers and body are not available to JavaScript, and its {{domxref("Response.status", "status code", "", "nocode")}} is always `0`.

The main application for `no-cors` is for a service worker: although the response to a `no-cors` request can't be read by JavaScript, it can be cached by a service worker and then used as a response to an intercepted fetch request. Note that in this situation you don't know whether the request succeeded or not, so you should adopt a caching strategy which enables the cached response to be updated from the network (such as [cache first with cache refresh](/en-US/docs/Web/Progressive_web_apps/Guides/Caching#cache_first_with_cache_refresh)).

- `navigate`
- : Used only by HTML navigation. A `navigate` request is created only while navigating between documents.

Expand Down