【问题标题】:Express custom log crashes while using express.static使用 express.static 时 Express 自定义日志崩溃
【发布时间】:2018-12-22 00:35:22
【问题描述】:

我目前正在尝试使用这样的简单中间件函数记录每个 Express 请求的完整结束响应:

module.exports = (req, res, next) => {
    const startTime = new Date();
    const oldEnd = res.end;

    res.end = (chunks, encoding) => {
        const responseTime = new Date() - startTime;
        res.set('Server-Timing', `total;dur=${responseTime}`);
        console.log(req.path, `Response Time: ${responseTime}`);
        res.end = oldEnd;
        res.end(chunks, encoding);
    };

    next();
}

此代码适用于普通 Express 端点,但是当我尝试提供这样的静态文件时:app.use('/static/path', express.static('path')) 我收到以下错误:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

这是因为res.set 用于服务器计时,但这意味着express.static 使用.end() 两次?当我在中间件函数中console.log 时,它只会被调用一次。

我正在使用 NodeJS 10 和 Express 4.16.4

有人知道如何解决这个问题吗?

【问题讨论】:

  • 你想达到什么目的?请详细说明“试图记录完整的结束响应”?您是否尝试测量每个请求的经过时间?
  • 我正在尝试从请求和响应对象中记录一些参数,例如:状态、标头和总响应时间。这工作正常,但在使用express.static 时不起作用。因此,我覆盖了res.end 函数,并在完成后再次调用它。设置响应标头会导致此问题,而它显然是在 res.end 之前设置的。

标签: node.js express static


【解决方案1】:

res.end 不会被调用两次。

serve-static 正在将文件流式传输到客户端,当文件的第一个块写入流时,将发送标头。来自 nodejs 文档:

response.writeHead

如果在调用this之前调用了response.write()或response.end(),则会计算隐式/可变标头并调用此函数。

因此,在流开始向客户端发送数据后,无法设置标头。但是可以将选项中的setHeader 函数传递给serve-static。

express.static('./public', {
  setHeaders: (res, path, stat) => {
    const responseTime = new Date() - res.locals.startTime;
    res.set('Server-Timing', `total;dur=${responseTime}`);
  },
});

但是,由于标头是在 Steam 开始时发送的,这不是准确的响应时间。更多的响应时间只是标题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 2011-01-05
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 2011-06-24
    相关资源
    最近更新 更多