
Fetch Uploads and Ranges
Fetch has grown beyond “send a blob, receive a blob”. Interop 2026 is pushing the pieces that matter in production: streaming uploads, better FormData and MIME handling, and dependable range requests for partial content workflows.
const stream = file.stream();
await fetch('/upload', {
method: 'POST',
body: stream,
duplex: 'half',
headers: {
'content-type': file.type || 'application/octet-stream',
},
}); Upload Streams Change the Shape of Large Transfers
A streamed request body means you do not have to materialize the whole payload in memory before the first byte leaves the browser. That matters for large files, live-generated archives, and any pipeline that wants backpressure instead of giant temporary buffers.
Keep MIME Rules Explicit
Use FormData when you need multipart form semantics. Use a raw stream or blob when the payload is one binary object. On the way back, branch on Content-Type and call the matching reader instead of assuming every success response is JSON.
Range Requests Belong in the Same Toolbelt
Fetch already lets you send a Range header for previews, resumable downloads, media scrubbing, and partial verification. The important part is handling partial responses as first-class results: expect 206, validate the returned range, and retry conservatively.
Production Rules
Pair long transfers with AbortController, make retries idempotent, and log the server-side reason when a streamed upload is rejected. Streams make transport better, but they do not remove the need for clear contract boundaries.
Browser support snapshot
Live support matrix for mdn-api_request_request_request_body_readablestream from
Can I Use.
Show static fallback image

Source: caniuse.com
Browser support snapshot
Live support matrix for streams from Can I Use.
Show static fallback image

Source: caniuse.com









