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

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

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

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

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

【问题讨论】:

标签: http caching etag expires-header


【解决方案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 之后引入的,并为您提供了更多控制权。见stackoverflow.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 是一个很好的做法。除此之外,它还降低了网络成本。

        希望对你有帮助;)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-09-05
          • 1970-01-01
          • 2017-03-22
          • 2016-10-28
          • 2021-07-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多