节点快递:如何找出给定etag的状态是不是为304

Posted

技术标签:

【中文标题】节点快递:如何找出给定etag的状态是不是为304【英文标题】:node express: how to find out if status will be 304 given etag节点快递:如何找出给定etag的状态是否为304 【发布时间】:2022-01-06 17:38:45 【问题描述】:

由于在 If-None-Match 标头中收到 etag 值,我如何确定响应状态是否为 304(未修改)?我想记录此信息,但无法在节点服务器中获取它。似乎 express 自己处理这个:

https://expressjs.com/en/api.html#express.static

【问题讨论】:

【参考方案1】:

如果您只想在发送响应后记录最终状态代码,您可以侦听finish 事件,然后检查res.statusCode。这是一个简单的例子:

const express = require('express');

const app = express();

app.get("/", (req, res) => 
    res.sendFile("temp.html",  root: __dirname );
    res.on('finish', () => 
        console.log(`finish event: $res.statusCode`);
    );
);

app.listen(80);

运行这个服务器然后请求/第一次记录200,第二次记录304。

【讨论】:

就是这样!现在我可以看到浏览器保留一些缓存文件的时间,并微调其中一些文件以在缓存中保留更多时间。即使是服务人员,我也无法从客户端做到这一点。【参考方案2】:

Express,从serve-static module 获取其express.static()。该模块从here 调用send module,并且该模块使用来自here 的fresh module,这似乎是测试eTag here 的地方。

这是fresh() 函数:

function fresh (reqHeaders, resHeaders) 
  // fields
  var modifiedSince = reqHeaders['if-modified-since']
  var noneMatch = reqHeaders['if-none-match']

  // unconditional request
  if (!modifiedSince && !noneMatch) 
    return false
  

  // Always return stale when Cache-Control: no-cache
  // to support end-to-end reload requests
  // https://tools.ietf.org/html/rfc2616#section-14.9.4
  var cacheControl = reqHeaders['cache-control']
  if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) 
    return false
  

  // if-none-match
  if (noneMatch && noneMatch !== '*') 
    var etag = resHeaders['etag']

    if (!etag) 
      return false
    

    var etagStale = true
    var matches = parseTokenList(noneMatch)
    for (var i = 0; i < matches.length; i++) 
      var match = matches[i]
      if (match === etag || match === 'W/' + etag || 'W/' + match === etag) 
        etagStale = false
        break
      
    

    if (etagStale) 
      return false
    
  

  // if-modified-since
  if (modifiedSince) 
    var lastModified = resHeaders['last-modified']
    var modifiedStale = !lastModified || !(parseHttpDate(lastModified) <= parseHttpDate(modifiedSince))

    if (modifiedStale) 
      return false
    
  

  return true

要自己调用fresh() 以自行获取此值,您必须能够将serve-staticsend 将传递它的确切标头传递给它。这可能是可行的,但您必须先了解express-static()send() 如何设置响应标头,然后再将它们传递给fresh()


仅供参考,这引出了“为什么”你要这样做的问题?你想解决什么问题?也许有更好的方法来解决真正的问题。就您现在的问题而言,这有点像XY problem,您在没有告诉我们实际问题是什么的情况下询问了有关您尝试解决某个问题的问题。对于实际问题,可能有更好/更简单的解决方案。

【讨论】:

以上是关于节点快递:如何找出给定etag的状态是不是为304的主要内容,如果未能解决你的问题,请参考以下文章

HTTP状态码304与ETag详解

HTTP状态码304与ETag详解

Chrome etag 总是显示 200 ok 但 curl 得到 304 未修改

IE9收到ETag后伪造304

Nginx如何启用ETag,提高访问速度

AEM Dispatcher (4.3.3) 总是返回 200 而不是 304 (Apache 2.4.6)