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

Next.js处理OPTIONS请求时CORS配置引发服务器头报错的解决方法

问题

在Next.js服务器上搭建公开API端点时,客户端调用正常无CORS错误,但服务器端持续抛出错误:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

当前使用的API路由代码如下:

export default async (req, res) => {
  res.setHeader("Access-Control-Allow-Credentials", true);
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader(
    "Access-Control-Allow-Methods",
    "GET,OPTIONS,PATCH,DELETE,POST,PUT"
  );
  res.setHeader(
    "Access-Control-Allow-Headers",
    "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version"
  );

  try {
    switch (req.method) {
      case "OPTIONS": {
        res.send(200);
        break;
      }
      case "GET": {
        const response = "data";
        console.log("response in GET:", response);

        if (response != null) {
          res.status(200).json(response);
        }

        res.status(500).json({ error: "Something went wrong" });
        break;
      }
      default: {
        res.status(405).end("Method Not Allowed");
        break;
      }
    }
  } catch (error) {
    console.log(error);
    res.status(500).json({ error: "Something went wrong" });
  }
};

需要修正代码以消除该错误。

解决方案

错误根源是同一个请求中多次发送响应。在GET分支里,当response != null时执行了res.status(200).json(response)发送响应,但代码没有终止,继续执行了后面的res.status(500).json(...),导致试图再次设置响应头,触发错误。

修正后的代码如下:

export default async (req, res) => {
  res.setHeader("Access-Control-Allow-Credentials", true);
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader(
    "Access-Control-Allow-Methods",
    "GET,OPTIONS,PATCH,DELETE,POST,PUT"
  );
  res.setHeader(
    "Access-Control-Allow-Headers",
    "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version"
  );

  try {
    switch (req.method) {
      case "OPTIONS": {
        // 发送OPTIONS响应后直接终止函数执行
        return res.send(200);
      }
      case "GET": {
        const response = "data";
        console.log("response in GET:", response);

        if (response != null) {
          // 发送成功响应后终止函数执行
          return res.status(200).json(response);
        }

        // 仅当response为空时执行错误响应
        return res.status(500).json({ error: "Something went wrong" });
      }
      default: {
        return res.status(405).end("Method Not Allowed");
      }
    }
  } catch (error) {
    console.log(error);
    return res.status(500).json({ error: "Something went wrong" });
  }
};

关键修改说明:

  • 在每个响应发送语句前添加return,确保发送响应后立即终止当前函数执行,避免后续代码重复发送响应。
  • 也可以用else包裹错误响应分支,但return的写法更简洁直观,能减少代码嵌套。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 03:35:15