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】:Etag 和 Last-modified 标头是验证器。
它们帮助浏览器和/或缓存(反向代理)了解文件/页面是否已更改,即使它保留相同的名称。
Expires 和 Cache-control 正在提供刷新信息。
这意味着它们会通知浏览器和反向中间代理,直到什么时间或多长时间,它们可以将页面/文件保留在缓存中。
所以问题通常是使用哪个验证器,etag 或 last-modified,以及使用哪个刷新信息标头,过期或缓存控制。
【讨论】:
【参考方案3】:Expires
和 Cache-Control
是“强缓存标头”
Last-Modified
和 ETag
是“弱缓存标头”
首先浏览器检查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】:我还想提一下,有些答案可能遗漏了,那就是在标题中同时包含 ETags
和 Expires/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 对象?