使用 res.write 流式传输响应时,在将它们发送到客户端错误后无法设置 headers

Cannot set headers after they are sent to the client error while streaming the response using res.write

我正在尝试使用 res.write 方法从 express 流式传输响应。下面是我的代码,当我访问服务器时出现 "Cannot set headers after they are sent to the client" 错误。我正在尝试流式传输数组的每个条目。有人可以帮忙吗?

var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  const arr = new Array(1, 2, 3, 4, 5);
  res.writeHead(200, {
    'Content-Type': 'text/plain'
  });

  for(const num of arr) {
    res.write(num);
  }

  res.end('Done!!')
});

module.exports = router;

根据 the docres.write() 需要字符串或缓冲区,而不是数字。

而且,它看起来像 this is the spot in the http.write() code,如果它不是 String 或 Buffer,它会抛出异常。

  if (!fromEnd && typeof chunk !== 'string' && !(chunk instanceof Buffer)) {
    throw new ERR_INVALID_ARG_TYPE('first argument',
                                   ['string', 'Buffer'], chunk);
  }

我不清楚为什么仅该错误会导致您报告的特定错误,但肯定需要修复它才能正常工作。

也许路由器正在捕获异常并尝试设置 500 状态?我不知道那个。无论如何,很高兴这解决了问题。


在更多地查看 Express 代码时,看起来确实有一个 try/catch 围绕着一个请求处理程序 here:

Layer.prototype.handle_request = function handle(req, res, next) {
  var fn = this.handle;

  if (fn.length > 3) {
    // not a standard request handler
    return next();
  }

  try {
    fn(req, res, next);
  } catch (err) {
    next(err);
  }
};

这会尝试将上述异常转换为错误响应,但是如果 headers 已经被刷新(当您调用 res.write() 时它们可能已经被刷新),那么这将导致您的错误经历了大约 headers 已经发送。