从内存中的字符串发送文件,但仍包含 etag 功能

Send file from a string in memory, but still incorporate etag functionality

我在内存中缓存了一个文件。据我所知,这基本上是服务器使用 etags 的方式:

const fileInMemory = '...';

if(fileHasChanged()){
   res.status(200);
   res.write(fileInMemory);
   res.end();

else{
   res.status(304);
   res.end();
}

有谁知道如何实际实施电子标签?如何将请求中的 etag header 与 fileInMemory 字符串进行比较?它只是字节吗?

我相信 res.sendFile() 并且这些方法负责生成 etag 信息,所以我可能不得不深入研究源代码。

我相信大部分相关代码都在这里: https://github.com/expressjs/express/blob/master/lib/response.js

虽然我还没弄明白req.fresh是从哪里来的: https://github.com/expressjs/express/blob/master/lib/response.js#L206

实体标签是不透明的字符串,只要符合RFC 7232的要求,服务器就可以通过任何方式实现它们:特别是,如果负载发生变化,即使在一个无关紧要的字节中,强实体标签也必须改变。

不知道负载性质的服务器通常使用 hash 的负载。在您的示例中,您可以(预先)计算 sha256(fileInMemory) 并将其(或其中的一部分)用作实体标签。

知道负载性质的服务器使用各种其他策略,例如检查存储在某些后端数据库中的负载版本。在您的示例中,如果您的程序有一些关联的版本号,并且 fileInMemory 从不在一个版本中更改,则该版本号可能用作实体标记。

顺便说一下,实体标签必须始终用双引号括起来:so

ETag: "9c314d58"

而不是

ETag: 9c314d58