多个实体的 If-None-Match 有什么用?

What are the uses for If-None-Match with multiple entities?

我正在使用 ETag header 进行缓存,浏览器会发送相应的 If-None-Match header。最初,我只是比较了这些 headers 并且它起作用了。

后来我想到 rfc2616 允许实体列表,所以我修复了它。问题是,如果修复程序被使用过...

我能想到两个用例:浏览器和缓存代理的联合 entity-tags 和自定义 client-side 缓存实现。

虽然,我从未见过浏览器在 If-None-Match 中使用多个 entity-tags 服务请求,但缓存代理可能拥有自己的请求资源版本。在进一步向服务器发送请求之前,它们可能会将浏览器发送的 If-None-Match 值替换为浏览器资源版本 entity-tag 和代理资源版本 entity-tag 的联合。这样,如果代理具有所请求资源的新版本,您可以通过从代理而不是服务器提供完整响应(使用 body 有效负载)来减少服务器负载。这种情况描述为RFC 7234 Hypertext Transfer Protocol (HTTP/1.1): Caching:

When a cache decides to revalidate its own stored responses for a request that contains an If-None-Match list of entity-tags, the cache MAY combine the received list with a list of entity-tags from its own stored set of responses (fresh or stale) and send the union of the two lists as a replacement If-None-Match header field value in the forwarded request.

我不能说 RFC 7234 的那部分支持是否广泛,但肯定有支持它的代理。检查 Colin Mollenhour 的 Node.js Caching Reverse HTTP Proxy 项目。

另一方面,您可能不想依赖浏览器来执行条件请求。您可以使用 XMLHttpRequest.setRequestHeader() 自行设置 If-None-Match HTTP header 值。如果您使用 Web Storage API, Cache API 或其他机制存储资源的多个版本,这将很有用。服务器响应必须包含 ETag HTTP header 和 entity-tag。 entity-tag 表示哪个版本的资源被认为是新鲜的。

我最近阅读了很多有关缓存机制的文章,发现自己也在问同样的问题。我只能想到存储和发送多个 ETags 有意义的用例(除了 Leonid 提到的那些):当资源 rollbacks 时。

它可能是 偶然的 ,例如服务于 json 的 api,并且基础数据经常以恢复的方式更新到以前的版本。

但它也可能是设计,其中一个大的配置对象可能只有几个不同的版本,会经常切换。 (更改的频率很重要,否则缓存不会带来太多价值)。在这种情况下,缓存会很乐意让所有可用版本始终准备好提供服务。

我知道这是不可能的,我想不出任何适合其中之一的真实情况。此外,无论如何,重新验证都很糟糕,缓存命中是可行的方法=)

此外,您可能想阅读 this。似乎所有缓存都只存储最后发送的 ETag(由于明显的内存原因,这是可以理解的)。

希望对您有所帮助