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
,我会建议反对。

整洁!工作得很有魅力。谢谢