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
相关产品推荐
相关产品推荐

