If-Modified-Since 覆盖浏览器中的 If-None-Match

Posted

技术标签:

【中文标题】If-Modified-Since 覆盖浏览器中的 If-None-Match【英文标题】:If-Modified-Since overrides If-None-Match in the browser 【发布时间】:2012-10-11 07:14:17 【问题描述】:

我有一个为特定 url 提供 ETag 的 Web 服务器。当浏览器对该 url 执行请求时,它会向 http-header “If-None-Match” 提供包含在服务器对该 url 的先前响应中的 ETag 值。现在,如果我以编程方式添加请求标头“If-Modified-Since”并将其设置为未来或过去的日期(没关系),浏览器将停止发送“If-None-Match”标头。我在 FireFox 和 Chrome 中都看到了这一点(未经任何其他浏览器测试)。我不能从 HTTP/1.1 规范中得出结论应该是这种情况。为什么会这样?

这是一个简单的代码示例,可以重现该场景。该代码假定服务器使用 Etag-header 进行响应。

var request = new XMLHttpRequest();
request.open("GET", someUrl, true);
request.onreadystatechange = function();

// This statement makes the browser stop sending the "If-None-Match" header
request.setRequestHeader("If-Modified-Since", "Sat, 29 Oct 1994 19:43:31 GMT"); 

request.send(null);

【问题讨论】:

您可能想改为阅读greenbytes.de/tech/webdav/…。 【参考方案1】:

现在,如果我以编程方式添加请求标头“If-Modified-Since”并将其设置为未来或过去日期(没关系),浏览器将停止发送“If-None-Match” -标题。

如果服务器同时为给定资源提供了 Etag 和 Last-Modified 标头,则它们不应该这样做:

HTTP/1.1 客户端 [...] 如果实体标签和 Last-Modified 值都已 由源服务器提供,应该使用两个验证器 缓存条件请求。这允许 HTTP/1.0 和 HTTP/1.1 缓存以适当响应。

编辑:当调用XmlHttpRequest.open() 时,实现使用nsIHttpChannel 准备请求,如果可以找到本地缓存项,则使用If-Modified-SinceIf-None-Match 标头等。

现在,当您使用If-(Un)Modified-SinceIf-None-Match 调用SetRequestHeader() 时,它会清除请求中的两个标头并设置您的值。

【讨论】:

服务器不提供 Last-Modified 标头。浏览器之所以要设置 If-Modified-Since 标头(实际上只有 IE 需要),是为了防止 IE 过度激进的缓存。在我的代码中,我将 If-Modified-Since 设置为当前时间,此外我还设置了“Cache-Control”:“max-age=0”。 @Tore 查看编辑。执行此操作的是 XHR 实现。如果您通过设置任何相关标头来覆盖内置缓存,则会删除它已设置的所有缓存标头。 你的意思是 setRequestHeader(),而不是 setResponseHeader()?

以上是关于If-Modified-Since 覆盖浏览器中的 If-None-Match的主要内容,如果未能解决你的问题,请参考以下文章

如何防止 Web 浏览器对缓存文件发出“If-Modified-Since”请求?

HTTP If-Modified-Since引发的浏览器缓存汇总

HTTP的请求头标签 If-Modified-Since

HTTP的请求头标签 If-Modified-Since

HTTP 缓存 - 与服务器检查,始终发送 If-Modified-Since

在请求中发送“if-modified-since”标头