【问题标题】:Make IE cache the resources but always revalidate让 IE 缓存资源但总是重新验证
【发布时间】:2011-06-28 09:30:23
【问题描述】:

缓存控制标头“no-cache, must-revalidate, private”允许浏览器缓存资源,但通过条件请求强制重新验证。这在 FF、Safari 和 Chrome 中按预期工作。

但是,IE7+8 不发送条件请求,即请求头中缺少“If-Modified-Since”,因此服务器以 HTTP/200 而不是 HTTP/304 响应。

以下是完整的服务器响应标头:

Last-Modified: Wed, 16 Feb 2011 13:52:26 GMT
Content-type: text/html;charset=utf-8
Content-Length: 10835
Date: Wed, 16 Feb 2011 13:52:26 GMT
Connection: keep-alive
Cache-Control: no-cache, must-revalidate, private

这似乎是一个 IE 错误,但我在网上没有找到任何相关的东西,所以我想知道是否存在另一个 header 的缺失或存在导致 IE 行为异常?

关于 no-cache 和 max-age 区别的很好的讨论:What's the difference between Cache-Control: max-age=0 and no-cache?

【问题讨论】:

  • 进入 Internet 选项==>常规选项卡==>浏览历史记录部分==>设置...按钮。查看“检查存储页面的较新版本:”选择器。确认此缓存行为是否与其设置相关联(对于大多数用户来说,它应该是自动)。
  • 与此行为相关。

标签: internet-explorer http-headers browser-cache cache-control


【解决方案1】:

我终于明白了。这是一个解释和一个经过测试的解决方案。

以下网站证实了我的观察:http://blog.httpwatch.com/2008/10/15/two-important-differences-between-firefox-and-ie-caching/

它表示 IE 不会使用“no-cache”指令在本地存储页面,因此总是发送无条件请求。

还有一篇 MS 支持文章 - https://support.microsoft.com/help/234067/ - 证实了这一点:

“Internet Explorer 支持 HTTP 1.1 Cache-Control 标头,当指定 no-cache 值时,它会阻止对特定 Web 资源的所有缓存...”

这种行为并非完全错误——但这不是 RFC 2616(第 14.9.1 节)的意图。关于'no-cache',它说“......缓存不得使用响应来满足后续请求,而无需与原始服务器成功重新验证。”所以响应可以被缓存,但必须重新验证它。除 IE 之外的主要浏览器都会缓存响应并重新验证它。为了防止存储请求,有 'no-store' Cache-Control 指令。

总之,IE 将 'no-cache' 视为 'no-store'。

以下是以一致的方式为 IE 和其他浏览器启用条件请求的解决方案

不要使用 no-cache,而是将 Expires 标头设置为过去(或 -1,具有相同的效果)。 IE 以及其他主要浏览器随后将发送条件请求。 (注意,您还应该注意 IE Vary 标头错误,它会阻止缓存。)

这些是关键的标头字段:

Last-Modified: Wed, 16 Feb 2011 13:52:26 GMT
Expires: -1
Cache-Control: must-revalidate, private
  • 需要 Last-Modified(或 ETag)作为验证器
  • Expires -1 表示资源已过时,必须重新验证
  • Cache-Control 不得包括 no-cache 或 no-store

【讨论】:

  • 太好了,这正是我要找的!
  • 运行 IE11(在 VirtualBox 中的 Win8.1 上)我没有得到相同的行为。对我来说,IE11 会验证标记为no-cache 的资源,而不是完全重新加载它们。这些资源还有一个带有旧日期的 Expires 标头。
  • 使用 ETag 是解决此问题的更通用方法,因为客户端可以轻松检查内容是否已修改,如果内容相同则停止下载。在所有浏览器中始终如一地工作。
  • 这是在哪个 IE 版本中测试的?它也适用于 IE6 吗?
  • 对我来说,IE 在图像请求中添加了 Cache-Control: no-cache,而不是响应。而且它不会缓存图像,这不是我想要的。知道如何解决吗?为什么请求中存在标头?它不是从 javascript 代码中设置的
【解决方案2】:
   $last_modified = filemtime($_SERVER['SCRIPT_FILENAME']);

   session_cache_limiter(FALSE);

   header("Content-Type: text/css");
   header("Cache-Control: max-age=1, must-revalidate, private");
   header("Last-Modified: " . gmdate("D, d M Y H:i:s", $last_modified) . " GMT");

   if(isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]))
   {
      if(strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]) >= $last_modified)
      {
         header("HTTP/1.1 304 Not Modified");
         exit;
      }
   }

【讨论】:

    猜你喜欢
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    • 1970-01-01
    相关资源
    最近更新 更多