【发布时间】:2010-10-23 20:59:43
【问题描述】:
对于两个后续请求,如果其中一个发生更改,以下两个标头中哪一个会被浏览器赋予更大的权重:ETag 或 Last-Modified?
【问题讨论】:
标签: http caching last-modified etag
对于两个后续请求,如果其中一个发生更改,以下两个标头中哪一个会被浏览器赋予更大的权重:ETag 或 Last-Modified?
【问题讨论】:
标签: http caching last-modified etag
根据RFC 2616 第 13.3.4 节,HTTP 1.1 客户端必须在任何缓存条件请求中使用 ETag,如果 ETag 和 Last Modified 都存在,则它应该同时使用两者。 ETag 标头被认为是一个强验证器(参见第 13.3.3 节),除非服务器明确声明为弱,而 Last Modified 标头被认为是弱的,除非它与 Date 标头之间存在至少一分钟的差异。但是请注意,服务器不需要发送任何一个(但它应该,如果可以的话)。
请注意,客户端不会检查标头是否已更改;它只是在下一个条件请求中盲目地使用它们;由服务器评估是否发送请求的内容或 304 Not Modified 响应。如果服务器只发送一个,那么客户端将单独使用那个(尽管只有强验证器对 Range 请求有用)。当然,中间缓存(除非它们已通过缓存控制指令阻止缓存)和服务器也可以自行决定它们将如何作用于标头; RFC 规定,如果验证器不一致,它们不得返回 304 Not Modified,但由于标头值是由服务器生成的,因此它有很大的余地。
在实践中,我注意到 Chrome、FireFox 和 IE 7+ 都会发送两个标头(如果可用)。我还测试了发送修改后的标头时的行为,我已经从 RFC 中的信息中怀疑了这一点。我测试的四个客户端仅在页面被刷新或当前进程第一次请求页面时才发送条件请求。
【讨论】:
这不是更像一个“OR”表达式吗?在伪代码中:
if ETagFromServer != ETagOnClient || LastModifiedFromServer != LastModifiedOnClient
GetFromServer
else
GetFromCache
【讨论】:
=!是正确的比较运算符。客户端需要保留从服务器接收到的文字字符串,因为转换可能会产生微小的差异。您不能假设“更新更好”。
为什么?考虑服务器操作员恢复资源的错误版本的情况。还原的版本较旧 - 但正确。
客户端必须使用服务器当前提供的版本;只有在相同的情况下,它才能使用缓存版本。因此,服务器必须检查相等性,而不是“更新”。
【讨论】: