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

Express中间件开发:响应体超过1MB时返回自定义错误

Express中间件限制响应体大小避免循环问题

你的代码核心问题是:当你在重写的res.end里调用res.end发送错误响应时,会再次触发你自己重写的res.end方法,导致无限循环。另外代码里还有几个需要修正的细节,比如未定义的responseSize、废弃的new BufferAPI。

下面是修复后的完整代码:

function logResponseBody(req, res, next) {
  const oldWrite = res.write;
  const oldEnd = res.end;
  const maxSize = 1024 * 1024; // 1MB,原代码是1023字节,这里修正为你要的1MB

  let totalSize = 0;
  const chunks = [];

  // 重写res.write,累加响应体大小并收集chunk
  res.write = function(chunk) {
    const buffer = Buffer.from(chunk);
    totalSize += buffer.length;
    chunks.push(buffer);

    // 如果已经超过大小限制,直接终止后续写入
    if (totalSize > maxSize) {
      return false;
    }

    return oldWrite.apply(res, arguments);
  };

  // 重写res.end,检查总大小并处理
  res.end = function(chunk) {
    // 处理最后一段chunk
    if (chunk) {
      const buffer = Buffer.from(chunk);
      totalSize += buffer.length;
      chunks.push(buffer);
    }

    // 先记录响应体日志
    const body = Buffer.concat(chunks).toString('utf8');
    console.log(req.path, body);

    // 检查是否超过大小限制
    if (totalSize > maxSize) {
      // 恢复原始的res.write和res.end,避免循环
      res.write = oldWrite;
      res.end = oldEnd;

      // 发送自定义错误响应
      return res.status(314).send('响应体过大,超过1MB限制');
    }

    // 正常结束响应
    return oldEnd.apply(res, arguments);
  };

  next();
}

app.use(logResponseBody);

关键修复点:

  • 避免循环:在发送错误响应前,先把res.write和res.end恢复为原始方法,这样调用res.status(314).send()时会使用Express原生的响应方法,不会再触发我们重写的逻辑。
  • 正确计算大小:直接累加每个chunk的字节长度,比转成字符串后计算长度更高效,也避免大字符串占用过多内存。
  • 废弃API替换:用Buffer.from()替代已废弃的new Buffer(),符合Node.js当前的最佳实践。
  • 提前终止写入:在res.write里就检查大小,一旦超过就返回false,阻止后续的响应内容写入,减少不必要的资源消耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 15:30:01