Express.js 的自定义计算 Etag

Custom Computed Etag for Express.js

我正在开发一个简单的本地图像服务器,该服务器使用一些 JSON 向 Web 应用程序提供图像。 Web 应用程序具有分页功能,它将向 express.js 服务器发出获取请求“/images?page=X&limit&200”,returns JSON 文件位于单个数组中。我想利用浏览器的内部缓存,这样如果用户转到上一页 express.js returns 一个 ETAG。我想知道如何使用 express.js 实现这一点?对于这个应用程序,我真的只是想让ETAG的计算接受页面、目录和限制三个参数(不需要考虑整个JSON body)。此外,此应用程序仅供本地使用,因此我希望服务器完成繁重的工作,因为我认为它比浏览器更快。我确实看到 https://www.npmjs.com/package/etag 这看起来很有希望,但我不确定如何将它与 express.js

一起使用

下面是 express.js 代码的样板:

var express = require('express');
var app = express();
var fs = require('fs');

app.get('/', async (req, res) =>{
  
  let files = [];
  
  let directory = fs.readdirSync("mypath");
  
  let page = parseInt(req.query.page);
  let limit = parseInt(req.query.limit);
  
  for (let i = 0; i < limit; ++i) {
    files.push(new Promise((resolve) => {
      fs.readFile(files[i + page * limit].name, (err, data) => {
        // format the data so easy to use for UI
        resolve(JSON.parse(data));
      });
    });
  }
  
  let results = await Promise.all(files);
  // compute an etag here and attach it the results. 
  res.send(results);
});

app.listen(3000);

当您的服务器向客户端发送 ETag 时,它还必须准备在随后的“条件”中检查客户端在 If-None-Match header 中发回服务器的 ETag请求。

如果匹配,服务器响应status 304;否则使用 E​​Tag 没有任何好处。

var serverEtag = "<compute from page, directory and limit>";
var clientEtag = req.get("If-None-Match");
if (clientEtag === serverEtag) res.status(304).end();
else {
  // Your code from above
  res.set("ETag", serverEtag);
  res.send(results);
}

serverEtag 的计算可以基于目录中最后一次修改的时间,因此只要该目录中的任何图像发生变化,它就会发生变化。重要的是,这可以在不执行代码中的 fs.readFile 语句的情况下完成。