ETag 与标头过期

Posted

技术标签:

【中文标题】ETag 与标头过期【英文标题】:ETag vs Header Expires 【发布时间】:2010-10-04 17:43:54 【问题描述】:

我环顾四周,但无法确定是否应该同时使用 ETag Expires Header 其中一个。

我要做的是确保我的 Flash 文件(和其他图像,以及不仅在这些文件发生更改时更新。

我不想做任何特别的事情,比如更改文件名或在 url 末尾添加一些奇怪的字符以使其不被缓存。

另外,我需要在我的 php 脚本中以编程方式做些什么来支持这一点还是全部是 Apache?

【问题讨论】:

developer.mozilla.org/en-US/docs/Web/HTTP/Caching(一般来说不错) 【参考方案1】:

它们略有不同 - ETag 没有任何信息可供客户端用于确定将来是否再次请求该文件。如果 ETag 就是它所拥有的一切,它总是必须提出请求。但是,当服务器从客户端请求中读取 ETag 时,服务器可以确定是发送文件(HTTP 200)还是告诉客户端仅使用其本地副本(HTTP 304)。 ETag 基本上只是一个文件的校验和,当文件的内容发生变化时,它会在语义上发生变化。

客户端(和代理/缓存)使用 Expires 标头来确定它是否甚至需要向服务器发出请求。您越接近到期日期,客户端(或代理)就越有可能从服务器发出对该文件的 HTTP 请求。

因此,您真正想要做的是使用 BOTH 标头 - 根据内容更改的频率将 Expires 标头设置为合理的值。然后配置要发送的 ETag,这样当客户端向服务器发送请求时,它可以更容易地确定是否将文件发回。

关于 ETag 的最后一点说明 - 如果您使用负载平衡的服务器设置和多台运行 Apache 的机器,您可能需要关闭 ETag 生成。这是因为 inode 被用作 ETag 哈希算法的一部分,这在服务器之间会有所不同。您可以将 Apache 配置为不使用 inode 作为计算的一部分,但您需要确保文件上的时间戳完全相同,以确保为所有服务器生成相同的 ETag。

【讨论】:

您还应该检查是否应该使用 Cache-Control 而不是 Expires。我的理解是 Cache-Control 是在 Expires 之后引入的,并为您提供了更多控制权。见***.com/questions/5799906/… 使用 Expires 标头时,最好在资源更改时更改文件名,因为客户端在文件过时之前不会再次请求文件。特别是如果您使用远期值作为到期日期。 假设我们将同时使用两者。过期时间已过,但文件未更改(Etag 相同)时会发生什么情况?服务器将返回 304,并且文件将从浏览器缓存中提供。我的问题是,此时是否会重新生成Expire时间? 小心将 ETAG Expires 标头设置为非零值。这可能导致竞争条件。见jakearchibald.com/2016/caching-best-practices 是否可以告诉服务器根本不使用 inode 或时间戳?另外,如果 ETag 仅用于表示内容,为什么还需要它们?【参考方案2】:

EtagLast-modified 标头是验证器

它们帮助浏览器和/或缓存(反向代理)了解文件/页面是否已更改,即使它保留相同的名称。

ExpiresCache-control 正在提供刷新信息

这意味着它们会通知浏览器和反向中间代理,直到什么时间或多长时间,它们可以将页面/文件保留在缓存中。

所以问题通常是使用哪个验证器,etag 或 last-modified,以及使用哪个刷新信息标头,过期或缓存控制。

【讨论】:

【参考方案3】:

ExpiresCache-Control 是“强缓存标头”

Last-ModifiedETag 是“弱缓存标头”

首先浏览器检查Expires/Cache-Control,判断是否向服务器发起请求

如果必须发出请求,它将在 HTTP 请求中发送Last-Modified/ETag。如果文档的 Etag 值匹配,服务器将发送 304 代码而不是 200,并且没有内容。浏览器将从其缓存中加载内容。

【讨论】:

您是否发现任何文档支持“强弱”缓存行为?我找不到,我的客户端浏览器现在实际上优先于 last-modified 而不是 expires,我不明白为什么。 @GMsoF 你可能想看看这个:tools.ietf.org/html/rfc7232#section-2.1 所以,如果我想确保我的更改立即传播到客户端,但仍然受益于一些缓存,我只能使用 Last-Modified 和 ETag 对吗? 这是给我最简洁也是最清楚的答案!谢谢。【参考方案4】:

另一个总结:

您需要同时使用两者。 ETag 是“服务器端”信息。过期是“客户端”缓存。

使用 ETags,除非您有负载平衡的服务器。它们是安全的,并且会让客户知道,每次您更改某些内容时,他们都应该获取您的服务器文件的新版本。

Expires 必须谨慎使用,就像您将过期日期设置在很远的将来但想立即更改其中一个文件(例如 JS 文件),一些用户可能要很久才能得到修改版!

【讨论】:

如果出现这种过期情况,你基本上需要重命名你的js并在你的HTML中更改它,并希望你没有设置HTML文件的过期1年。【参考方案5】:

我还想提一下,有些答案可能遗漏了,那就是在标题中同时包含 ETagsExpires/Cache-control 的不利之处。

根据您的需要,它可能只是在您的标头中添加额外的字节,这可能会增加数据包,这意味着更多的 TCP 开销。同样,您应该查看是否需要在标头中同时包含这两种内容的开销,或者它只会在您的请求中增加额外的权重,从而降低性能。

您可以在 Kyle Simpson 的这篇出色的博客文章中了解更多信息:http://calendar.perfplanet.com/2010/bloated-request-response-headers/

【讨论】:

【参考方案6】:

在我看来,使用 Expire Header,服务器可以告诉客户端我的数据何时会过时,而使用 Etag,服务器会检查客户端每个请求的 etag 值。

【讨论】:

【参考方案7】:

ETag 用于确定资源是否应使用副本。和 Cache-Control 之类的 Expires Header 被告知客户端在缓存几十年之前,客户端应该获取本地资源。

在现代网站中,经常会提供一个名为 hash 的文件,例如 app.98a3cf23.js,因此使用 Expires Header 是一个很好的做法。除此之外,它还降低了网络成本。

希望对你有帮助;)

【讨论】:

以上是关于ETag 与标头过期的主要内容,如果未能解决你的问题,请参考以下文章

apache_conf WordPress .htaccess配置文件。允许强制SSL,隐藏wp-config.php,标头ETag,GZIP压缩和过期缓存。

如何解决 Google Page Speed:“未指定过期时间”

CloudFront / S3 ETag:CloudFront 是不是可以在 CF TTL 过期之前发送更新的 S3 对象?

爱创课堂每日一题第二十二天-什么是Etag?

无效的 cookie 标头:过期属性为空时无法解析过期属性

apache_conf 添加标头过期缓存