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

Next.js中未认证用户重定向时出现Error [ERR_HTTP_HEADERS_SENT]错误的排查求助

解决Next.js中重定向时的ERR_HTTP_HEADERS_SENT错误

这个错误的核心原因是你在已经发送响应头之后,又尝试再次设置头或者返回页面props,导致Node.js抛出"Cannot set headers after they are sent to the client"。我来拆解问题并给出修复方案:

问题分析

你的代码里有两个关键问题:

  1. redirectUser函数重复操作响应头:
    你同时使用了writeHead、statusCode和setHeader,但writeHead(302, { Location: location })已经一次性设置了状态码和Location头,后续的statusCode = 302和setHeader(302, location)完全多余(而且setHeader的第一个参数应该是头名称,比如"Location",不是状态码302,这本身就是错误)。

  2. getInitialProps在重定向后仍继续执行return:
    当你调用redirectUser完成重定向响应后,函数没有终止,反而继续执行到最后的return { ...appProps, pageProps: { global } },这会让Next.js试图再次发送页面props的响应头,导致冲突。

修复后的代码

第一步:修正redirectUser函数

简化响应头操作,避免重复设置:

function redirectUser(ctx, location) {
  if (ctx.req) {
    // 一次性设置状态码和重定向地址,结束响应
    ctx.res.writeHead(302, { Location: location });
    ctx.res.end();
    // 返回null标记重定向已完成
    return null;
  } else {
    // 客户端直接跳转
    Router.push(location);
    return { props: {} };
  }
}

第二步:修正getInitialProps逻辑

调用重定向后立即终止函数,不再执行后续的return:

MyApp.getInitialProps = async (ctx) => {
  const jwt = false; 
  const appProps = await App.getInitialProps(ctx); 
  const global = await fetchAPI("/global");

  if (!jwt) {
    if (ctx?.ctx.pathname === "/account") {
      const redirectResult = redirectUser(ctx.ctx, "/login");
      // 服务端重定向后直接终止函数,不返回任何props
      if (!redirectResult) return;
      // 客户端跳转返回空props
      return redirectResult;
    }
  }

  // 正常情况返回页面数据
  return { ...appProps, pageProps: { global } };
};

额外建议

虽然这个修复能解决当前问题,但在Next.js中,更推荐使用Middleware来处理全局的认证重定向,这样可以避免在getInitialProps里的复杂逻辑,同时不影响页面的SSG优化。不过如果你的场景必须保留getInitialProps,上面的方案完全适用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 09:52:40