如何在res.send之后但在响应离开服务器之前挂钩==>当res.statusCode被知道时

我已经通过app.use()方法使用了Express.js中中间件工具来钩住所有的请求并logging一条消息,但是发现res.statusCode几乎总是200的事实,我检查的是不正确的。 我认为这是默认值,因为它还没有用res.send(204)自己的statusCode代替,总是200

我知道我可以在每个请求中的每个res.send(x)之后logging消息,但正如你所想象的那样,这很麻烦。

所以,问题是:

在哪里/如何将我的中间件函数与仅在一个地方的条件挂钩,并且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.send之后但在响应离开服务器之前挂钩==>当res.statusCode被知道时"

res从标准库中的 http.ServerResponseinheritance。 这意味着它是一个EventEmitter和一个finish事件。 所以在你的中间件中,注册finish事件并在发生火灾时进行日志logging:

 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 // Always 200 and not the really one. } } }); }); next(); }); 

当然,你可以用res.once注册,但是finish事件只能保证只触发一次,除非标准库中有bug,否则不应该是必须的。

这不一定会发生“ res.send之后,但在响应离开服务器之前”请求 – finish事件的文档只声称

当响应标题和主体的最后一部分已经被传递给操作系统以通过networking传输时,他的事件被发射出去。

所以,一些响应可能已经离开了服务器。 不过,我相信这是最接近你没有猴子补丁express ,我会build议反对。