使用 res.writeHead() 将标头发送到客户端后无法设置标头

问题描述

如果用户未通过身份验证,我正在尝试将用户重定向登录名。我现在对 jwt 进行了硬编码。这有效,但我只收到一条错误消息,说 Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

由于该功能有效,我不知道出了什么问题,也无法真正找到答案。这是我的参考代码

function redirectUser(ctx,location) {
  if (ctx.req) {
    ctx.res.writeHead(302,{ Location: location });
    ctx.res.statusCode = 302;
    ctx.res.setHeader(302,location);
    ctx.res.end();
    return { props: {} };
  } else {
    Router.push(location);
  }
}

// getinitialProps disables automatic static optimization for pages that don't
// have getStaticProps. So article,category and home pages still get SSG.
// Hopefully we can replace this with getStaticProps once this issue is fixed:
// https://github.com/vercel/next.js/discussions/10949
MyApp.getinitialProps = async (ctx) => {
  const jwt = false;

  // Calls page's `getinitialProps` and fills `appProps.pageProps`
  const appProps = await App.getinitialProps(ctx);
  // Fetch global site settings from Strapi
  const global = await fetchAPI("/global");

  if (!jwt) {
    if (ctx?.ctx.pathname === "/account") {
      redirectUser(ctx.ctx,"/login");
    }
  }

  // Pass the data to our page via props
  return { ...appProps,pageProps: { global } };
};

任何帮助将不胜感激。

解决方法

错误“错误:发送后无法设置标头。”意味着您已经在正文中,但是其他一些函数试图设置标题或状态代码。在您的情况下,是函数 ctx.res.setHeader(302,location); 导致了问题。

在 writeHead 之后,标头被烘焙,您只能调用 res.write(body),最后调用 res.end(body)

如果您已经在使用 setHeader 方法,则不需要使用 writehead

在此处阅读有关 writehead

的更多信息

所以你的 redirectUser 可能是这样的:


function redirectUser(ctx,location) {
  if (ctx.req) {
    ctx.res.writeHead(302,{ Location: location });
    ctx.res.end();
    return { props: {} };
  } else {
    Router.push(location);
  }
}