如何使用 Express.js 返回 304 未修改状态?

问题描述 投票:0回答:2

我正在使用 Node 和 Express 作为 iOS 应用程序的后端。数据存储在 SQL Server 数据库中,因此 iOS 应用程序查询服务器,服务器查询数据库,服务器接收数据库响应,然后将响应转发给 iOS 应用程序。我正在尝试弄清楚缓存是如何工作的。我提供大量静态内容 - 例如博客文章。所以我计划使用 etag,但我不确定它应该如何工作。我发出请求、获取内容并在客户端缓存响应。好的。然后,我稍后使用存储在“If-None-Match”标头中的先前响应的 etag 发出相同的请求。然后呢?

Express.js 会自动处理这个问题吗?似乎没有 - 我无法让它生成 304 响应。如果我在发送响应之前尝试检查响应标头,则会得到 null,因此在发送响应之前我无法获取响应的 etag。那么我该如何将请求 etag 与服务器发回的内容的 etag 进行比较呢?我是否应该使用自定义生成的 etag 并将它们缓存在服务器上,然后将请求 etag 与此缓存进行比较?

下面是我设置的一个非常简单的路线来测试它,不涉及数据库。我只需向服务器发送一个数字,它就会返回平方。如果我将带有 etag 的请求发送到相同的 url,我将得到相同的响应。我可以检查请求的“If-None-Match”标头,但是我应该将其与什么进行比较以确定是否应该发送 304 而不是 200 状态?

router.use("/square/:testId", function(req, res) {

  var obj = {};
  obj["testId"] = req.params.testId;
  obj["result"] = req.params.testId * req.params.testId;

  res.setHeader('Cache-Control', 'public, max-age=5');

  var h2 = JSON.stringify(res.headers,null,2);
  console.log("The response headers: " + h2);
  //Prints null

  res.status(200).send(obj);
});
node.js express caching etag
2个回答
25
投票

无需使用

etag
之类的任何第三方模块。 Express 处理
etag
背后的逻辑,无需编写代码。

  1. 在 Express 中启用

    etag
    。在下面的示例中,我们使用强 etag。

    // Use string ETag  
    app.set('etag', 'strong');  
    
  2. 使用

    GET
    方法构建您的响应:

    app.get('/my-data', (req, res) => {   
       ...
       res.append('Last-Modified', (new Date(lastModifiedStringDate)).toUTCString());
       return res.send(response);   
    }
    

瞧,Express 将发送您的回复内容

200 OK
或带有回复的空正文
304 Not Modified

如果

If-None-Match
未更改,则提交带有标头
304 Not Modified
的请求的客户端将收到 HTTP
etag

我们在回复中添加

Last-Modified
作为加号。您不需要像我们一样使用它。但 Express 也会使用类似的逻辑(时间)尊重
If-Modified-Since:
标头,而不是内容 (
Etags
)。


4
投票

我是否应该使用自定义生成的 etag 并将它们缓存在服务器上,然后将请求 etag 与此缓存进行比较?

是的,您可以使用类似 etag npm 模块的东西,它可以接受缓冲区或字符串并为您提供强大的 etag 值:

res.setHeader('ETag', etag(body))
。如果您将修改日期存储在数据库中,那么您也可以简单地将这些日期以
Last-Modified
标头的形式发送给客户端。在这种情况下,客户端最终会在后续请求中发送
If-Modified-Since
,然后您可以使用它来与所请求资源的修改列进行比较。

无论哪种情况,您都将负责使用适当的状态代码、标头和正文进行响应。

如果您从实际文件系统提供静态文件,那么您可以使用 serve-static Express 中间件,它将自动提供正确的缓存行为。

© www.soinside.com 2019 - 2024. All rights reserved.