vercel / vercel/next.js

`Request` object behaves differently in fetch

Open
#66,840 9 comments 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug Runtime
Dominant language
JavaScript
Stars
142k
Forks
32.5k
Avg merge
2d 14h
Merged PRs (30d)
351

Description

Link to the code that reproduces this issue

https://github.com/lennartkerkvliet/next-fetch-request-bug

To Reproduce

When sending a request body using the Request object in a Next.js application while using server actions, the content-length parameter is not included in the request and instead chunked transfer encoding is used. This behavior differs from the expected functionality of the Fetch API, which internally is also constructing a Request object.

Steps to reproduce the behavior:

  1. Create a Request object with a body.
  2. Pass the Request object to the fetch function.

Example code:

const body = JSON.stringify({ username: "test", password: "password" });
const request = new Request("https://www.my-site.com/api/login", { 
    method: "POST", 
    headers: { "Content-Type": "application/json" },
    body: body
});
const response = await fetch(request); // Server receives an empty body
Current vs. Expected behavior

I would expect the parameters in Request to be identical to when using the more traditional use of fetch API:

const body = JSON.stringify({ username: "test", password: "password" });
const response = await fetch("https://www.my-site.com/api/login", { 
    method: "POST", 
    headers: { "Content-Type": "application/json" },
    body: body
});

but instead will return the latter

Screenshot 2024-06-13 at 18 27 51
Provide environment information
Operaring System:
  Arch: arm64
  Version: macOS Sonoma 14.4.1

Binaries:
  Node: v22.2.0
  npm: 10.7.0

Relevant Packages:
  next: 14.2.3
Which area(s) are affected? (Select all that apply)

Not sure, Runtime

Which stage(s) are affected? (Select all that apply)

next dev (local), Vercel (Deployed), Other (Deployed)

Additional context
  • Using plain Node.js, the above code works as expected.

It seems to be somewhat related to the changes NextJS is making to the Response object and in particular the duplex option. The Django server I am using for my own project does not support transfer-encoding, and will mark the request as a "Bad request syntax".

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reproduction linked in the issue and compare the two fetch forms: passing a Request object versus passing the URL and options directly. Investigate the server-action/runtime path involved in constructing and sending the Request. Done means the Request form sends the body with Content-Length rather than chunked transfer encoding and is accepted by the described Django server.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, next.js, node.js
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.