Internet Explorer/Firefox 中的硬刷新和 XMLHttpRequest 缓存

Posted

技术标签:

【中文标题】Internet Explorer/Firefox 中的硬刷新和 XMLHttpRequest 缓存【英文标题】:Hard refresh and XMLHttpRequest caching in Internet Explorer/Firefox 【发布时间】:2011-10-10 04:26:19 【问题描述】:

我发出了一个 Ajax 请求,在其中设置了响应可缓存性和最后修改的标头:

if (!String.IsNullOrEmpty(HttpContext.Current.Request.Headers["If-Modified-Since"]))

    HttpContext.Current.Response.StatusCode = 304;
    HttpContext.Current.Response.StatusDescription = "Not Modified";
    return null;

HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.Public);
HttpContext.Current.Response.Cache.SetLastModified(DateTime.UtcNow);

这按预期工作。第一次发出 Ajax 请求时,我得到了200 OK。我第二次收到304 Not Modified

当我在 Chrome 中硬刷新 (Ctrl+F5) 时,我得到 200 OK - 太棒了!

当我在 Internet Explorer/Firefox 中硬刷新时,我得到304 Not Modified。但是,所有其他资源 (JS/CSS/html/PNG) 都会返回 200 OK

原因是“If-Not-Modified”标头是为 XMLHttpRequest 发送的,无论这些浏览器中的硬刷新如何。我相信 Steve Souders 记录了它 here。

我尝试设置一个 ETag 并在“If-None-Match”上进行调节,但无济于事(Steve Souders 页面的 cmets 中提到了这一点)。

这里有没有人得到任何智慧的宝石?

谢谢, 本

更新

我可以对照存储的最后修改日期检查“If-Modified-Since”。但是,希望这个问题能帮助其他发现标头设置错误的 SO 用户。

更新 2

虽然每次发送请求时都带有“If-Modified-Since”标头。如果到期未设置或设置为未来日期,Internet Explorer 甚至不会发出请求。没用!

更新 3

这还不如现在是一个实时博客。 Internet Explorer 不会在 localhost 时发出第二个请求。使用真实 IP 或环回将起作用。

【问题讨论】:

您是否尝试通过在脚本 src 路径中使用随机数或日期时间值更改每个请求的文件名来防止缓存(如 src='myscript.js?q=45920')?跨度> 我希望它被缓存,除非它来自硬刷新。因此设置随机查询字符串参数没有帮助。不过感谢您的建议! 【参考方案1】:

在 IE10 之前,IE 不会将刷新标志(请参阅 http://blogs.msdn.com/b/ieinternals/archive/2010/07/08/technical-information-about-conditional-http-requests-and-the-refresh-button.aspx)应用于不是作为加载文档的一部分的请求。

如果需要,您可以调整目标 URL 以包含随机数,以防止缓存副本满足未来的请求。或者,您可以发送 max-age=0 以强制 IE 在每次重用之前有条件地重新验证资源。

至于为什么浏览器会复用一个没有指定生命周期的缓存资源,请看http://blogs.msdn.com/b/ie/archive/2010/07/14/caching-improvements-in-internet-explorer-9.aspx

【讨论】:

感谢您的回答和文章。这是一个令人困惑的非标准化领域。一个不错的折衷方案可能是将由 JS 加载事件生成的 XHR 以与标记资源相同的方式处理。【参考方案2】:

我为实现一致控制而想到的解决方案是管理所有请求类型的缓存标头。

所以,我强制使用与 XMLHttpRequests 相同的标准请求,它告诉 IE 使用以下缓存策略:Cache-Control: private, max-age=0。

由于某种原因,IE 不支持各种请求类型的标头。例如,我对标准请求的缓存策略默认为浏览器,而对于 XMLHttpRequests,它被设置为上述控制策略。但是,将 /url 之类的请求作为标准获取请求,可以正确呈现结果。不幸的是,向 /url 发出与 XMLHttpRequest 相同的请求,甚至不会到达服务器,因为 get 请求已被缓存并且 XMLHttpRequest 正在访问相同的 url。

因此,要么在所有方面强制执行缓存策略,要么确保为请求类型使用不同的访问点 (uri)。我的解决方案是前者。

【讨论】:

以上是关于Internet Explorer/Firefox 中的硬刷新和 XMLHttpRequest 缓存的主要内容,如果未能解决你的问题,请参考以下文章

unity是个怎样的软件?

unity3d 摄像机拉太远影子看不见了,有没办法不受距离的影响?

视频无法在 iOS Safari 上播放 - iphone 6s

internet与Internet的区别

电脑上的internet协议要怎么设置

win10无internet安全