← 中文资源

简体中文版本

Express 报 Cannot set headers after they are sent

通过确保每个请求只发送一次响应并守护异步路径,修复“响应头已发送”错误。

阅读英文原文

症状

Express 记录 ERR_HTTP_HEADERS_SENT,而客户端仍收到看似成功的响应。原因是对同一请求的两次响应尝试:处理器发送了一次,错误路径又发送一次,或定时器与待处理回调在响应完成后触发。由于响应头已写出,第二次尝试抛错并可能使进程崩溃。

诊断

搜索处理器内所有响应调用;加 res.headersSent 守卫;在响应 close 时清理定时器。

grep -n "res.send\|res.json\|res.end\|res.status" routes/

根因

代码对已发送过响应的请求再次发送,HTTP 层因响应头与响应体已提交而拒绝。

修复

重构处理器使每条路径只发送一次响应;在任何可能的二次发送前用 if (res.headersSent) return 守卫;响应关闭时取消定时器与异步工作,避免完成后写入。发送后应 return 而非继续下落。

验证

复现请求确认不再出现 ERR_HTTP_HEADERS_SENT,且客户端只收到一个格式正确的响应。单一干净响应且无服务端错误即证明不再重复发送。

常见陷阱

在 catch 中无条件发送错误响应会在成功已发送后再写一次;应检查 headersSent 或只在未发送时处理。