我已经通过app.use()
使用Express.js中的middleware工具来挂接所有请求并记录一条消息,但是发现res.statusCode
几乎总是200 ,我检查的是不正确的。我认为这是默认值,并且由于尚未用我自己的statusCode
和res.send(204)
替换,因此始终为200。
[我知道我可以在每个请求中的每个res.send(x)
之后记录该消息,但是您可能会想到,这很麻烦。
所以,问题是:
我在哪里/如何将我的中间件功能与只在一个地方的条件挂钩,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
事件上的文档仅声明
[T]他的事件在响应头和主体的最后一段已移交给操作系统以通过网络传输时发出。
因此,某些响应可能已经离开服务器。但是,我相信这是您不需猴子补丁express
就能获得的最接近的距离,对此我建议不要使用。