Skip to content

Chrome 105 / Deno 1.7 / Node 18 support fetch() with ReadableStream body#25636

Merged
Elchi3 merged 6 commits into
mainfrom
fetch-with-ReadableStream-body
Jan 13, 2025
Merged

Chrome 105 / Deno 1.7 / Node 18 support fetch() with ReadableStream body#25636
Elchi3 merged 6 commits into
mainfrom
fetch-with-ReadableStream-body

Conversation

@caugner

@caugner caugner commented Jan 13, 2025

Copy link
Copy Markdown
Contributor

Summary

Add subfeature for the fetch spec change allowing ReadableStream as fetch() body in 2017.

Test results and supporting details

Test case:

// Create a simple ReadableStream
const stream = new ReadableStream({
  start(controller) {
    // Push some data into the stream
    controller.enqueue(new TextEncoder().encode("Hello, "));
    controller.enqueue(new TextEncoder().encode("this is a streamed request!"));
    controller.close(); // Close the stream
  },
});

// Use fetch with the ReadableStream as the body
fetch('https://httpbin.org/post', {
  method: 'POST',
  headers: {
    'Content-Type': 'text/plain',
  },
  body: stream,
  duplex: 'half', // This is required for streaming requests
})
  .then((response) => {
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    return response.json();
  })
  .then((data) => {
    // If supported: `Response from server: Hello, this is a streamed request!`
    // Otherwise: `Response from server: [object ReadableStream]`
    console.log('Response from server:', data.data);
  })
  .catch((error) => {
    console.error('Fetch error:', error);
  });

Related issues

Fixes #12188.

@github-actions github-actions Bot added data:api Compat data for Web APIs. https://developer.mozilla.org/docs/Web/API size:m [PR only] 25-100 LoC changed labels Jan 13, 2025
Comment thread api/_globals/fetch.json Outdated
@caugner caugner marked this pull request as draft January 13, 2025 10:22
@caugner caugner changed the title Chrome 105 / Safari 11.1 support fetch() with ReadableStream body Chrome 105 supports fetch() with ReadableStream body Jan 13, 2025
Comment thread api/_globals/fetch.json Outdated
Comment thread api/_globals/fetch.json Outdated
Comment thread api/_globals/fetch.json Outdated
Comment thread api/_globals/fetch.json Outdated
@caugner caugner force-pushed the fetch-with-ReadableStream-body branch from 7615275 to 5bedd8e Compare January 13, 2025 10:55
@caugner caugner changed the title Chrome 105 supports fetch() with ReadableStream body Chrome 105 / Deno 1.7 / Node 18 support fetch() with ReadableStream body Jan 13, 2025
@caugner

caugner commented Jan 13, 2025

Copy link
Copy Markdown
Contributor Author

@skyclouds2001 Since you have some experience researching Node.js support, could you help me out here? It looks like ReadableStream body support in Node.js was only implemented here in undici 5.12 and the undici update PR seems to have only landed in v18.13.0. However, the following (ChatGPT-generated) test case seems to work in v18.0.0:

// Create a simple ReadableStream
const stream = new ReadableStream({
  start(controller) {
    // Push some data into the stream
    controller.enqueue(new TextEncoder().encode("Hello, "));
    controller.enqueue(new TextEncoder().encode("this is a streamed request!"));
    controller.close(); // Close the stream
  },
});

// Use fetch with the ReadableStream as the body
fetch('https://httpbin.org/post', {
  method: 'POST',
  headers: {
    'Content-Type': 'text/plain',
  },
  body: stream,
  duplex: 'half', // This is required for streaming requests
})
  .then((response) => {
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    return response.json();
  })
  .then((data) => {
    console.log('Response from server:', data.data);
  })
  .catch((error) => {
    console.error('Fetch error:', error);
  });
% nvm run v18.0.0 test.js                                                                                                                                                                               1 ↵ ✭
Running node v18.0.0 (npm v8.6.0)
(node:38648) ExperimentalWarning: The Fetch API is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
Response from server: Hello, this is a streamed request!

Does this make sense to you?

PS: In Firefox, the test case logs: Response from server: [object ReadableStream]

@caugner

caugner commented Jan 13, 2025

Copy link
Copy Markdown
Contributor Author

Oh, never mind, I just saw in the comments that the previous implementation seems to have already supported streams.

Comment thread api/_globals/fetch.json Outdated
@caugner caugner marked this pull request as ready for review January 13, 2025 11:21
@caugner caugner requested a review from Elchi3 January 13, 2025 11:27

@Elchi3 Elchi3 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Claas! 👍

@Elchi3 Elchi3 merged commit 86490f2 into main Jan 13, 2025
@Elchi3 Elchi3 deleted the fetch-with-ReadableStream-body branch January 13, 2025 15:30
@mdn-bot mdn-bot mentioned this pull request Jan 13, 2025
@skyclouds2001

skyclouds2001 commented Jan 13, 2025

Copy link
Copy Markdown
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

data:api Compat data for Web APIs. https://developer.mozilla.org/docs/Web/API size:m [PR only] 25-100 LoC changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Issue with "WindowOrWorkerGlobalScope.fetch()": (missing Streaming REQUEST body in Browser Compatibility matrix)

3 participants