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

ExpressJS中res.sendFile遇客户端中止请求导致服务器崩溃

解决Express高并发中止请求时的ERR_HTTP_HEADERS_SENT问题

问题根源

当客户端中止请求(如JMeter中断连接)时,res.sendFile的回调仍会触发错误逻辑,此时响应头可能已发送或连接已断开,调用res.status(500).send会尝试重复设置响应头,触发ERR_HTTP_HEADERS_SENT错误。该错误未被正确捕获时会直接终止Node进程。开头的if (res.headersSent) return仅在接口启动时检查,无法覆盖请求中途中止的场景。

解决方案

1. 在sendFile回调中检查响应状态

在发送错误响应前,先确认响应是否仍可写入,避免重复操作:

app.get("/getFile", (req, res) => {
  try {
    res.sendFile(
      path.join(__dirname, "latest-data", "my-file.json"),
      (err) => {
        // 检查响应是否已结束或不可写入
        if (res.headersSent || !res.writable) return;
        
        if (err) {
          res.status(500).send("Internal Server Error");
        }
      }
    );
  } catch (error) {
    console.error(error.stack);
  }
});

2. 监听请求中止事件

捕获客户端中止请求的事件,提前终止后续响应逻辑:

app.get("/getFile", (req, res) => {
  let requestAborted = false;
  
  // 监听请求中止事件
  req.on('abort', () => {
    requestAborted = true;
  });

  try {
    res.sendFile(
      path.join(__dirname, "latest-data", "my-file.json"),
      (err) => {
        if (requestAborted || res.headersSent || !res.writable) return;
        
        if (err) {
          res.status(500).send("Internal Server Error");
        }
      }
    );
  } catch (error) {
    console.error(error.stack);
  }
});

3. 全局捕获未处理异常(兜底方案)

添加全局异常监听,防止单个请求的错误导致整个服务器进程崩溃:

process.on('uncaughtException', (err) => {
  if (err.code === 'ERR_HTTP_HEADERS_SENT') {
    // 针对该错误做日志记录,无需终止进程
    console.warn("Attempted to set headers after they were sent:", err.message);
  } else {
    // 其他严重错误仍需记录并处理
    console.error("Uncaught exception:", err.stack);
    // 可选:根据实际情况决定是否重启进程
    // process.exit(1);
  }
});

process.on('unhandledRejection', (reason, promise) => {
  console.error("Unhandled Rejection at:", promise, "reason:", reason);
});

额外优化点

  • 去掉接口的async关键字:res.sendFile不返回Promise,async无实际作用,反而可能误导错误捕获逻辑。
  • 考虑使用res.sendFile的options参数配置超时,避免长时间挂起的请求占用资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 12:21:29