366

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

我正在尝试做的是确保我的闪存文件(和其他图像以及不仅在这些文件发生更改时更新)。

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

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

4

7 回答 7

694

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

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

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

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

于 2009-02-01T03:18:16.717 回答
115

EtagLast-modified标头是验证器

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

ExpiresCache-control正在提供刷新信息

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

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

于 2011-10-14T04:13:50.227 回答
37

Expires并且Cache-Control是“强缓存标头”

Last-Modified并且ETag是“弱缓存标头”

首先浏览器检查Expires/Cache-Control确定是否向服务器发出请求

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

于 2014-03-04T15:45:10.270 回答
12

另一个总结:

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

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

  • Expires一定要谨慎使用,如果你把过期日期设置在很远的将来,但又想立即更改其中一个文件(例如 JS 文件),有些用户可能要等很长时间才能获得修改后的版本!

于 2014-07-17T17:43:16.300 回答
1

我还想提到的另一件事是,有些答案可能已经遗漏了,那就是在你的标题中同时包含两者ETags的缺点。Expires/Cache-control

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

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

于 2016-10-14T19:21:09.770 回答
1

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

于 2016-12-22T08:36:52.280 回答
0

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

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

希望能帮助到你 ;)

于 2019-01-11T07:00:17.230 回答