我已经通过app.use()
在 Express.js 中使用了中间件工具来挂接所有请求并记录一条消息,但是发现res.statusCode
几乎总是 200 ,这一事实我检查过是不正确的。我认为这是默认值,由于尚未用statusCode
很好地替换为我自己的res.send(204)
,因此始终为 200 。
我知道我可以在每个请求中的每个res.send(x)
之后记录该消息,但是正如您可能想像的那样,这很麻烦。
因此,问题是:
在哪里/如何将我的中间件功能与只在一个位置的条件 Hook ,而res.statusCode
是客户端真正看到的条件?
相关代码:
// Log API requests.
app.use(function (req, res, next) {
logger.info('API request.', {
module: 'core'
data : {
req: {
method: req.method,
url : req.url,
ip : req.ip
},
res: {
status_code: res.statusCode // Always 200 and not the really one.
}
}
});
next();
});
app.use(app.router);
如果我移动
app.use(app.router)
,则不会执行中间件。 最佳答案
res
继承自http.ServerResponse
in the standard library。这意味着它是一个带有EventEmitter
事件的finish
。因此,在您的中间件中,注册finish
事件并在该事件触发时进行日志记录:
app.use(function (req, res, next) {
res.on('finish', function() {
logger.info('API request.', {
module: 'core'
data : {
req: {
method: req.method,
url : req.url,
ip : req.ip
},
res: {
status_code: res.statusCode
}
}
});
});
next();
});
当然,您可以向
res.once
注册,但是finish
事件只能触发一次,因此除非标准库中存在错误,否则不必这样做。这不一定会按照您的要求在“
res.send
之后但响应离开服务器之前”发生-finish
事件上的文档仅声明因此,某些响应可能已经离开服务器。但是,我相信,这是没有猴子补丁
express
所能获得的最接近的结果,对此我建议不要这样做。