streamfetch-apiwhatwg-streams-api

Fetch with ReadableStream as Request Body


I'm trying to use fetch with a ReadableStream. In this example, the ReadableStream should simply repeat "Some data..." indefinitely.

fetch('/', {
  method: 'POST', 
  body: new ReadableStream({
    pull: function(controller) {
      console.log('pull called!');
      controller.enqueue('Some data...');
    }
  })
});

This doesn't work. While pull is executed once, no data is sent in the request body.

POST / HTTP/1.1
Host: example.com
Connection: keep-alive
Content-Length: 0
Origin: https://example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36
Accept: */*
Referer: https://example.com/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8

How can I make a ReadableStream (or any kind of stream where I can write dynamic data) usable with fetch?

Alternatively, if this isn't yet possible, could you please indicate this? Thank you.

Note: This is a more specific spin-off question from: Method for streaming data from browser to server via HTTP


Solution

  • Update in 2024: As documented on MDN, using request streams is possible in all important browsers except Firefox since September 2022. The implementation in Firefox is tracked in this issue.

    It should be noted that even though most browser support request streams now, there are some restrictions, as discussed in this issue:

    As a workaround, you could change your backend API to support uploading chunks of the data in separate requests, or you could use a websocket to transmit the data. If you don’t have control over the backend, you could set up an intermediate backend that forwards the chunks as a request stream.