我如何 return 304 未修改状态 Express.js?

How do I return 304 Unmodified status with Express.js?

我在 iOS 应用程序的后端使用 node 和 express。数据存储在 SQL 服务器数据库中,因此 iOS 应用程序查询服务器,服务器查询数据库,服务器接收数据库响应,然后将响应转发给 iOS 应用程序。我试图弄清楚缓存是如何工作的。我提供大量静态内容——例如博客文章。所以我打算使用 etags,但我不确定它应该如何工作。我发出请求、获取内容并在客户端缓存响应。行。然后我稍后使用存储在 'If-None-Match' header 中的先前响应的 etag 发出相同的请求。然后呢?

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

下面是我设置的一个非常简单的路由来测试这个,不涉及数据库。我只是向服务器发送一个数字,它 returns 方块。如果我向同一个 url 发送带有 etag 的请求,我将得到相同的响应。我可以检查请求的 'If-None-Match' header,但是我应该将它与什么进行比较以确定我是否应该发送 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);
});

Am I supposed to use custom generated etags and cache these on the server, then compare request etags with this cache?

是的,您可以使用类似 etag npm 模块的东西,它可以接受缓冲区或字符串并为您提供强大的 etag 值:res.setHeader('ETag', etag(body))。如果您在数据库中存储修改日期,那么您也可以简单地将它们以 Last-Modified header 的形式发送给客户端。在这种情况下,客户端最终会在后续请求中发送一个 If-Modified-Since,然后您可以使用它来与所请求资源的修改列进行比较。

在任何一种情况下,您都将负责使用适当的状态代码、headers 和 body.

进行响应

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

不需要像etag那样使用任何third-party模块。 Express 处理背后的逻辑 etag,无需编写代码。

  1. 在 Express 中启用 etag。在下面的示例中,我们使用了强大的 etags。

    // 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.

的空 body

如果 etag 未更改,则使用 header If-None-Match 提交请求的客户端将收到 HTTP 304 Not Modified

确保您的请求不会发送 Cache-Control: no-cachePostman 等工具默认会发送 header Cache-Control: no-cache,这会使 Express ETag 无效(毕竟没有缓存就是没有缓存)。您可以通过在 Postman 的设置中切换来更改此行为。

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