在 Express 中间件中获取状态码

18
我尝试通过中间件将一些请求缓存到静态文件中,这些文件可以直接由nginx提供服务。
核心代码:
function PageCache(config) {
    config = config || {};
    root = config.path || os.tmpdir() + "/_viewcache__";
    return function (req, res, next) {
        var key = req.originalUrl || req.url;
        var shouldCache = key.indexOf("search") < 0;
        if (shouldCache) {
            var extension = path.extname(key).substring(1);
            if (extension) {

            } else {
                if (key.match(/\/$/)) {
                    key = key + "index.html"
                } else {
                    key = key + ".html";
                }
            }

            var cacheFilePath = path.resolve(root + key)
            try {

                res.sendResponse = res.send;
                res.send = function (body) {
                    res.sendResponse(body);

                    // cache file only if response status code is 200
                    cacheFile(cacheFilePath, body);
                }
            }
            catch (e) {
                console.error(e);
            }
        }
        next()
    }
}

然而,我发现所有响应都被缓存了,无论状态码如何,而状态码为404、410、500或其他的响应不应该被缓存。

但是我找不到任何像res.statusres.get('status')这样的API,可以用来获取当前请求的状态码。

是否有任何替代方案?


状态码是为响应而指定的,而不是请求。当您想要发送响应时,可以使用 res.status(404).send("ok") 作为示例。 - farhadamjady
3个回答

34

当响应结束时,您可以覆盖被调用的res.end事件。您可以在响应结束时获得响应的statusCode

希望它能帮到您。

var end = res.end;

res.end  = function(chunk, encoding) {
     if(res.statusCode == 200){
         // cache file only if response status code is 200
         cacheFile(cacheFilePath, body);
     }

     res.end = end;
     res.end(chunk, encoding);
};

3
可以。为什么Express文档里没有 res.statusCode?如果有的话,那就可以省去我的麻烦了... - odigity
13
更新:由于某些原因,即使我的应用程序返回304或404,res.statusCode始终产生200。 - odigity
@odigity 这对我有效。不过我使用了不同的实现方式:res.status(404).send(); if (res.headersSent) console.log(res.statusCode); - JakeStrang
我使用与Jake相同的实现,仍然存在问题,它总是产生200。我使用 on-finished 包解决了这个问题。 - Kevin Danikowski

1
你可以使用 res.statusCode 来获取状态。

中间件中,res.statusCode 总是返回 200。 - Jompis
@Jompis 你可以使用 express-interceptor 来获取实际的响应。你会看到 res.statusCode 包含了实际的状态码。 - Jimmy.B

1
您可以使用 on-finished 中间件来确保响应头已发送,然后读取状态。
var onFinished = require('on-finished')


onFinished(res, function (err, res) {
   // read res.statusCode here
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接