From 0c51ed05fce87b4dccc7e3e59dd2e3218df77e48 Mon Sep 17 00:00:00 2001 From: kovan Date: Fri, 13 Mar 2026 02:53:33 +0100 Subject: [PATCH 1/2] 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 https://github.com/nodejs/node/issues/52163 --- doc/api/globals.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/doc/api/globals.md b/doc/api/globals.md index 47340c897b4a36..f1679f60b93a1d 100644 --- a/doc/api/globals.md +++ b/doc/api/globals.md @@ -586,6 +586,38 @@ import { setGlobalDispatcher } from 'undici'; setGlobalDispatcher(new MyAgent()); ``` +### Differences from the standard + +The Node.js `fetch` implementation is based on [undici][] and runs in a +server-side environment, so it differs from browser-based Fetch +implementations in several ways: + +* **No CORS enforcement.** Browsers restrict cross-origin requests via + [CORS][]. Node.js does not send preflight requests or validate + `Access-Control-Allow-Origin` headers, since server-side requests do + not have an origin. All cross-origin requests are allowed by default. +* **No forbidden headers.** The [Fetch Standard][] forbids setting + certain headers (such as `Cookie`, `Host`, and `Origin`) in browser + contexts. Node.js removes these restrictions, allowing full control + over all request headers. +* **`Response` accepts async iterables.** `new Response(body)` accepts + async iterables as the `body` argument. This is a Node.js extension + not present in the Fetch Standard. +* **Response bodies must be consumed.** In browsers, garbage collection + eventually releases unused response bodies. The Node.js garbage + collector is less aggressive, so not consuming or canceling response + bodies can lead to connection leaks. Always consume the body (e.g., + with `response.text()` or `response.body.cancel()`) or use `HEAD` + requests when only headers are needed. +* **`Content-Encoding` layer limit.** Node.js limits the number of + `Content-Encoding` layers (e.g., nested gzip) in a response to 5, to + prevent resource exhaustion attacks. Browsers do not impose this + limit. +* **Manual redirect returns the actual response.** When the `redirect` + option is set to `"manual"`, Node.js returns the actual redirect + response. Browsers return a filtered response with type + `"opaqueredirect"` instead. + ### Related classes The following globals are available to use with `fetch`: @@ -1344,9 +1376,11 @@ changes: A browser-compatible implementation of [`WritableStreamDefaultWriter`][]. +[CORS]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS [CommonJS module]: modules.md [CommonJS modules]: modules.md [ECMAScript module]: esm.md +[Fetch Standard]: https://fetch.spec.whatwg.org/ [Navigator API]: https://html.spec.whatwg.org/multipage/system-state.html#the-navigator-object [RFC 5646]: https://www.rfc-editor.org/rfc/rfc5646.txt [Web Crypto API]: webcrypto.md @@ -1420,5 +1454,6 @@ A browser-compatible implementation of [`WritableStreamDefaultWriter`][]. [buffer section]: buffer.md [built-in objects]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects [timers]: timers.md +[undici]: https://undici.nodejs.org [webassembly-mdn]: https://developer.mozilla.org/en-US/docs/WebAssembly [webassembly-org]: https://webassembly.org From bc825f9c90c8f342939ce1f1ecb9a54c18b906a3 Mon Sep 17 00:00:00 2001 From: Kit Dallege Date: Wed, 25 Mar 2026 20:31:42 +0100 Subject: [PATCH 2/2] doc: fix incorrect claim about Host header in fetch Host is restricted in Node.js fetch because undici disallows setting it to align with Cloudflare Workers and Deno behavior (undici#2322). Change "No forbidden headers" to "Fewer forbidden headers" and note the Host restriction. --- doc/api/globals.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/api/globals.md b/doc/api/globals.md index f1679f60b93a1d..019f5dda2b9598 100644 --- a/doc/api/globals.md +++ b/doc/api/globals.md @@ -596,10 +596,11 @@ implementations in several ways: [CORS][]. Node.js does not send preflight requests or validate `Access-Control-Allow-Origin` headers, since server-side requests do not have an origin. All cross-origin requests are allowed by default. -* **No forbidden headers.** The [Fetch Standard][] forbids setting +* **Fewer forbidden headers.** The [Fetch Standard][] forbids setting certain headers (such as `Cookie`, `Host`, and `Origin`) in browser - contexts. Node.js removes these restrictions, allowing full control - over all request headers. + contexts. Node.js removes most of these restrictions (for example, + `Cookie` and `Origin` can be set freely), but some headers such as + `Host` remain restricted for security reasons. * **`Response` accepts async iterables.** `new Response(body)` accepts async iterables as the `body` argument. This is a Node.js extension not present in the Fetch Standard.