Skip to content

Commit 0c51ed0

Browse files
committed
doc: document fetch() differences from the Fetch Standard
Add a 'Differences from the standard' section to the fetch documentation listing the ways Node.js fetch (via undici) differs from browser implementations: no CORS enforcement, no forbidden headers, async iterable support in Response, response body consumption requirements, Content-Encoding layer limits, and manual redirect behavior. Fixes #52163
1 parent 9ff27fd commit 0c51ed0

1 file changed

Lines changed: 35 additions & 0 deletions

File tree

doc/api/globals.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,38 @@ import { setGlobalDispatcher } from 'undici';
586586
setGlobalDispatcher(new MyAgent());
587587
```
588588

589+
### Differences from the standard
590+
591+
The Node.js `fetch` implementation is based on [undici][] and runs in a
592+
server-side environment, so it differs from browser-based Fetch
593+
implementations in several ways:
594+
595+
* **No CORS enforcement.** Browsers restrict cross-origin requests via
596+
[CORS][]. Node.js does not send preflight requests or validate
597+
`Access-Control-Allow-Origin` headers, since server-side requests do
598+
not have an origin. All cross-origin requests are allowed by default.
599+
* **No forbidden headers.** The [Fetch Standard][] forbids setting
600+
certain headers (such as `Cookie`, `Host`, and `Origin`) in browser
601+
contexts. Node.js removes these restrictions, allowing full control
602+
over all request headers.
603+
* **`Response` accepts async iterables.** `new Response(body)` accepts
604+
async iterables as the `body` argument. This is a Node.js extension
605+
not present in the Fetch Standard.
606+
* **Response bodies must be consumed.** In browsers, garbage collection
607+
eventually releases unused response bodies. The Node.js garbage
608+
collector is less aggressive, so not consuming or canceling response
609+
bodies can lead to connection leaks. Always consume the body (e.g.,
610+
with `response.text()` or `response.body.cancel()`) or use `HEAD`
611+
requests when only headers are needed.
612+
* **`Content-Encoding` layer limit.** Node.js limits the number of
613+
`Content-Encoding` layers (e.g., nested gzip) in a response to 5, to
614+
prevent resource exhaustion attacks. Browsers do not impose this
615+
limit.
616+
* **Manual redirect returns the actual response.** When the `redirect`
617+
option is set to `"manual"`, Node.js returns the actual redirect
618+
response. Browsers return a filtered response with type
619+
`"opaqueredirect"` instead.
620+
589621
### Related classes
590622

591623
The following globals are available to use with `fetch`:
@@ -1344,9 +1376,11 @@ changes:
13441376

13451377
A browser-compatible implementation of [`WritableStreamDefaultWriter`][].
13461378

1379+
[CORS]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS
13471380
[CommonJS module]: modules.md
13481381
[CommonJS modules]: modules.md
13491382
[ECMAScript module]: esm.md
1383+
[Fetch Standard]: https://fetch.spec.whatwg.org/
13501384
[Navigator API]: https://html.spec.whatwg.org/multipage/system-state.html#the-navigator-object
13511385
[RFC 5646]: https://www.rfc-editor.org/rfc/rfc5646.txt
13521386
[Web Crypto API]: webcrypto.md
@@ -1420,5 +1454,6 @@ A browser-compatible implementation of [`WritableStreamDefaultWriter`][].
14201454
[buffer section]: buffer.md
14211455
[built-in objects]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
14221456
[timers]: timers.md
1457+
[undici]: https://undici.nodejs.org
14231458
[webassembly-mdn]: https://developer.mozilla.org/en-US/docs/WebAssembly
14241459
[webassembly-org]: https://webassembly.org

0 commit comments

Comments
 (0)