Javascript 如何在'res.send'之后但在响应离开服务器之前挂接,==>;当res.statusCode为已知时
我已经通过Javascript 如何在'res.send'之后但在响应离开服务器之前挂接,==>;当res.statusCode为已知时,javascript,node.js,express,middleware,Javascript,Node.js,Express,Middleware,我已经通过app.use()使用了Express.js中的中间件工具来钩住所有请求并记录消息,但发现res.statusCode几乎总是200,我检查的结果不正确。我假设这是默认值,因为它还没有被我自己的statusCode替换为res.send(204),所以它总是200 我知道我可以在每个请求中的每个res.send(x)之后记录消息,但正如您可能想象的那样,这很麻烦 因此,问题是: 在哪里/如何将中间件功能与仅在一个位置的条件挂钩,并且res.statusCode是客户端真正看到的条件?
app.use()
使用了Express.js中的中间件工具来钩住所有请求并记录消息,但发现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
。这意味着它是一个带有finish
事件的EventEmitter
。因此,在您的中间件中,注册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
,我会建议反对。整洁!工作得很有魅力。谢谢