最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to hook after `res.send` but before the response leaves the server, ==> when res.statusCode is know - St

programmeradmin9浏览0评论

I already use the middleware facility in Express.js by means of app.use() to hook on all requests and log a message, but found the fact that res.statusCode is nearly always 200, which I checked is not correct. I presume this is the default value and since it is not yet replaced with my own statusCode with res.send(204) well, is always 200.

I know I can log the message after every res.send(x) in every request, but as you might imagine, that is cumbersome.

So, the question is:

Where/How can I hook my middleware function with the conditions that is only in one place and res.statusCode is the one that the client really sees?

Relevant code:

// 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);

If I move app.use(app.router) the middleware don't get executed.

I already use the middleware facility in Express.js by means of app.use() to hook on all requests and log a message, but found the fact that res.statusCode is nearly always 200, which I checked is not correct. I presume this is the default value and since it is not yet replaced with my own statusCode with res.send(204) well, is always 200.

I know I can log the message after every res.send(x) in every request, but as you might imagine, that is cumbersome.

So, the question is:

Where/How can I hook my middleware function with the conditions that is only in one place and res.statusCode is the one that the client really sees?

Relevant code:

// 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);

If I move app.use(app.router) the middleware don't get executed.

Share Improve this question asked Apr 2, 2014 at 20:46 DiosneyDiosney 10.6k15 gold badges68 silver badges113 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 23

res inherits from http.ServerResponse in the standard library. This means that it is an EventEmitter with a finish event. So in your middleware, register for the finish event and do the logging when that fires:

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();
});

You could, of course, register with res.once, but the finish event is guaranteed to fire only once, so that shouldn't be necessary unless there's a bug in the standard library.

This won't necessarily occur "after res.send but before the response leaves the server" as you request - the docs on the finish event only claim that

[T]his event is emitted when the last segment of the response headers and body have been handed off to the operating system for transmission over the network.

So, some of the response may have already left the server. However, I believe it is the closest you'll get without monkey-patching express, which I would advise against.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论