You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React服务端组件中fetch接收204响应抛出TypeError的原因与处理

问题:Next.js服务端组件中fetch 204响应触发错误的原因及解决办法

在Next.js App Router场景下,当API路由返回HTTP 204(No Content)状态码时,服务端组件(RSC)中的fetch请求会抛出错误:

TypeError: Response constructor: Invalid response status code 204

但将状态码改为202(Accepted)则无此问题,且客户端组件中执行相同的fetch请求完全正常。以下是相关代码示例:

API路由代码

export default function handler(req, res) {
  res.status(204).end();
}

服务端组件代码

export default async function Home() {
  let res;
  try {
    res = await fetch("https://rpvequ-3000.csb.app/api/hello");
    console.log("res.status", res.status);
    console.log("res", res);
  } catch (error) {
    console.log("res in error", res);
    console.log("error", error);
  }
  return (
    <main>
      <p>HELLO WORLD</p>
    </main>
  );
}

客户端组件对比代码

"use client";
import React, { useEffect } from "react";

const ClientComp = ({ children }) => {
  useEffect(() => {
    let res;
    (async () => {
      try {
        res = await fetch("http://localhost:3000/api/hello");
        console.log("res.status", res.status);
        console.log("res", res);
      } catch (error) {
        console.log("res in error", res);
        console.log("error", error);
      }
    })();
  }, []);

  return <div>{children}</div>;
};

export default ClientComp;

原因分析

Next.js服务端组件中使用的fetch并非浏览器原生实现,而是经过框架封装的版本,需遵循React服务端组件的序列化规则。

HTTP 204状态码的核心要求是响应不能包含任何内容体,但Next.js封装的fetch在处理响应时,会尝试将结果序列化为可传递给客户端的格式,这个过程中可能因204响应无内容体的特性与内部Response构造逻辑冲突,最终抛出错误。

而客户端组件使用的是浏览器原生fetch,其处理逻辑完全符合HTTP规范,能正常识别并返回204响应的Response对象,不会触发错误。


解决办法:在RSC中处理204响应

1. 使用原生Node.js HTTP模块替代fetch

绕开Next.js封装的fetch,直接用Node.js的http/https模块发送请求,完全控制响应处理流程:

import https from 'https';

export default async function Home() {
  let statusCode;
  try {
    statusCode = await new Promise((resolve, reject) => {
      https.get('https://rpvequ-3000.csb.app/api/hello', (res) => {
        resolve(res.statusCode);
        res.resume(); // 消耗响应流,避免内存泄漏
      }).on('error', reject);
    });
    console.log('statusCode', statusCode);
    if (statusCode === 204) {
      // 自定义204响应的处理逻辑
      console.log('Received 204 No Content');
    }
  } catch (error) {
    console.log('error', error);
  }
  return (
    <main>
      <p>HELLO WORLD</p>
    </main>
  );
}

2. 捕获错误并针对性处理

通过try/catch捕获错误,结合错误信息判断是否为204响应相关问题:

export default async function Home() {
  let res;
  try {
    res = await fetch("https://rpvequ-3000.csb.app/api/hello");
    console.log("res.status", res.status);
    // 正常响应的处理逻辑
  } catch (error) {
    if (error.message.includes('Invalid response status code 204')) {
      // 处理204响应的业务逻辑
      console.log('Handled 204 No Content response');
    } else {
      console.log('Other error', error);
    }
  }
  return (
    <main>
      <p>HELLO WORLD</p>
    </main>
  );
}

3. 修改API返回状态码(临时方案)

如果业务允许,可将204替换为202(Accepted)或200(OK,返回空对象/空字符串作为响应体),规避Next.js的序列化错误。


测试注意事项

每次重启开发服务器时需删除.next文件夹,否则fetch会直接使用缓存内容,导致测试结果不准确。

内容的提问来源于stack exchange,提问作者Magnus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 23:57:04