You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
doc: document differences between Node.js fetch and WHATWG Fetch Standard
Adds a new documentation section detailing intentional divergences between Node.js’s implementation of the Fetch API and the WHATWG Fetch Standard. This includes request-body streaming semantics, async iterable support, FormData Blob streaming, CORS behavior, header restrictions, redirect handling, resource management considerations, unsupported features, and implementation notes relating to undici.
This consolidation improves clarity for developers and reduces repeated
questions around Node.js fetch behavior.
Node.js implements the [WHATWG Fetch Standard][] with intentional differences to better support server-side JavaScript environments.
585
+
586
+
#### Request Body Extensions
587
+
588
+
##### Async iterable request bodies
589
+
590
+
Node.js supports async iterables as request bodies—a behavior not included in the Fetch Standard.
591
+
```js
592
+
constdata= {
593
+
async*[Symbol.asyncIterator]() {
594
+
yield'hello';
595
+
yield'world';
596
+
}
597
+
};
598
+
599
+
awaitfetch('https://example.com', {
600
+
method:'POST',
601
+
body: data,
602
+
duplex:'half'
603
+
});
604
+
```
605
+
606
+
When using an async iterable or a `ReadableStream` as the request body, the `duplex` option must be set to `'half'`.
607
+
608
+
##### FormData with stream-backed Blob objects
609
+
610
+
`FormData` entries may include stream-backed `Blob` objects created from the filesystem, enabling efficient uploads of large files without buffering them in memory.
611
+
```js
612
+
import { openAsBlob } from'node:fs';
613
+
614
+
constfile=awaitopenAsBlob('./large-file.csv');
615
+
constform=newFormData();
616
+
form.set('file', file, 'large-file.csv');
617
+
618
+
awaitfetch('https://example.com', { method:'POST', body: form });
619
+
```
620
+
621
+
#### Response Body Extensions
622
+
623
+
##### Async iterable response bodies
624
+
625
+
The `Response` constructor accepts async iterables, allowing flexible construction of streaming responses in server environments.
626
+
```js
627
+
constres=newResponse(asyncIterable);
628
+
```
629
+
630
+
#### CORS Behavior
631
+
632
+
Node.js does not implement CORS enforcement. No preflight requests are issued, and CORS response headers are not validated. All cross-origin requests are permitted.
633
+
634
+
Applications requiring origin-based access control must implement these checks manually.
635
+
636
+
#### Header Restrictions
637
+
638
+
The Fetch Standard restricts certain headers for browser security reasons. Node.js removes these restrictions, allowing all headers—including `Host`, `Connection`, and `Content-Length`—to be set programmatically.
639
+
640
+
#### Redirect Handling
641
+
642
+
When using `redirect: 'manual'`, Node.js returns the actual redirect response rather than an opaque filtered response. This matches other server-side runtimes and allows inspection of redirect details.
643
+
644
+
#### Resource Management and Garbage Collection
645
+
646
+
In Node.js, unconsumed response bodies may delay the release of underlying network resources. This can reduce connection reuse or cause stalls under load.
647
+
648
+
Always consume or cancel the response body:
649
+
```js
650
+
constres=awaitfetch(url);
651
+
forawait (constchunkofres.body) {
652
+
// process chunk
653
+
}
654
+
```
655
+
656
+
For header-only requests, prefer `HEAD` to avoid creating a body:
0 commit comments