如何在所有浏览器上控制网页缓存?

我们的调查显示,并非所有浏览器都以统一的方式尊重http缓存指令。

出于安全原因,我们不希望在我们的应用程序某些网页缓存, 有史以来,通过Web浏览器。 这至少适用于以下浏览器:

  • Internet Explorer 6+
  • Firefox 1.5+
  • Safari 3+
  • Opera 9+
  • 我们的要求来自安全测试。 从我们的网站注销后,您可以按下后退按钮并查看缓存的页面。


    介绍

    在所有提到的客户端(和代理服务器)中都可以使用的正确的最小标题集合:

    Cache-Control: no-cache, no-store, must-revalidate
    Pragma: no-cache
    Expires: 0
    

    Cache-Control是根据客户端和代理的HTTP 1.1规范(并且由Expires旁边的某些客户端隐式地要求)。 Pragma根据史前客户的HTTP 1.0规范。 Expires是针对客户端和代理的HTTP 1.0和1.1规范。 在HTTP 1.1中, Cache-Control优先于Expires ,因此它毕竟仅适用于HTTP 1.0代理。

    如果您不关心IE6及其在仅通过no-store提供通过HTTPS提供页面时的破损缓存,则可以省略Cache-Control: no-cache

    Cache-Control: no-store, must-revalidate
    Pragma: no-cache
    Expires: 0
    

    如果你不关心IE6和HTTP 1.0客户端(HTTP 1.1是1997年推出的),那么你可以省略Pragma

    Cache-Control: no-store, must-revalidate
    Expires: 0
    

    如果你不关心HTTP 1.0代理,那么你可以省略Expires

    Cache-Control: no-store, must-revalidate
    

    另一方面,如果服务器自动包含有效的Date标头,则理论上也可以省略Cache-Control并仅依赖Expires

    Date: Wed, 24 Aug 2016 18:32:02 GMT
    Expires: 0
    

    但是,如果最终用户操纵操作系统日期并且客户端软件依赖它,那可能会失败。

    如果指定了上述Cache-Control参数,其他Cache-Control参数(如max-age就无关紧要。 Last-Modified头部包含在这里的大多数其他答案中,只有当你真的想要缓存请求时才有意思,所以你根本不需要指定它。

    如何设置它?

    使用PHP:

    header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1.
    header("Pragma: no-cache"); // HTTP 1.0.
    header("Expires: 0"); // Proxies.
    

    使用Java Servlet或Node.js:

    response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
    response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
    response.setHeader("Expires", "0"); // Proxies.
    

    使用ASP.NET-MVC

    Response.Cache.SetCacheability(HttpCacheability.NoCache);  // HTTP 1.1.
    Response.Cache.AppendCacheExtension("no-store, must-revalidate");
    Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
    Response.AppendHeader("Expires", "0"); // Proxies.
    

    使用ASP.NET:

    Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
    Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
    Response.AppendHeader("Expires", "0"); // Proxies.
    

    使用ASP:

    Response.addHeader "Cache-Control", "no-cache, no-store, must-revalidate" ' HTTP 1.1.
    Response.addHeader "Pragma", "no-cache" ' HTTP 1.0.
    Response.addHeader "Expires", "0" ' Proxies.
    

    使用Ruby on Rails或Python / Flask:

    response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate" # HTTP 1.1.
    response.headers["Pragma"] = "no-cache" # HTTP 1.0.
    response.headers["Expires"] = "0" # Proxies.
    

    使用Python / Django:

    response["Cache-Control"] = "no-cache, no-store, must-revalidate" # HTTP 1.1.
    response["Pragma"] = "no-cache" # HTTP 1.0.
    response["Expires"] = "0" # Proxies.
    

    使用Python /金字塔:

    request.response.headerlist.extend(
        (
            ('Cache-Control', 'no-cache, no-store, must-revalidate'),
            ('Pragma', 'no-cache'),
            ('Expires', '0')
        )
    )
    

    使用Google Go:

    responseWriter.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") // HTTP 1.1.
    responseWriter.Header().Set("Pragma", "no-cache") // HTTP 1.0.
    responseWriter.Header().Set("Expires", "0") // Proxies.
    

    使用Apache .htaccess文件:

    <IfModule mod_headers.c>
        Header set Cache-Control "no-cache, no-store, must-revalidate"
        Header set Pragma "no-cache"
        Header set Expires 0
    </IfModule>
    

    使用HTML4:

    <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
    <meta http-equiv="Pragma" content="no-cache" />
    <meta http-equiv="Expires" content="0" />
    

    HTML元标记与HTTP响应标头

    重要的是要知道,当通过HTTP连接提供HTML页面,并且HTTP响应头文件和HTML <meta http-equiv>标签中存在头文件时,则HTTP响应头文件中指定的将优先通过HTML元标记。 只有当通过file:// URL从本地磁盘文件系统查看页面时,才会使用HTML元标记。 另请参阅W3 HTML规范章节5.2.2。 请不要以编程方式指定它们,因为Web服务器可以包含一些默认值。

    通常,您最好不要指定HTML元标记以避免初学者混淆,并依赖硬HTTP响应标头。 而且,特别是那些<meta http-equiv>标签在HTML5中无效 。 只允许HTML5规范中列出的http-equiv值。

    验证实际的HTTP响应标头

    为了验证这一点,你可以在webbrowser的开发者工具集的HTTP流量监视器中看到/调试它们。 您可以通过在Chrome / Firefox23 + / IE9 +中按F12,然后打开“网络”或“网络”选项卡面板,然后单击感兴趣的HTTP请求来发现有关HTTP请求和响应的所有细节。 以下屏幕截图来自Chrome:

    Chrome开发人员工具集HTTP通信监视器,显示stackoverflow.com上的HTTP响应标头

    我也想在文件下载中设置这些标题

    首先,这个问题和答案是针对“网页”(HTML页面),而不是“文件下载”(PDF,zip,Excel等)。 您最好让它们缓存并在URI路径或查询字符串中的某处使用某个文件版本标识符来强制重新下载更改后的文件。 在文件下载中使用这些无缓存标头时,请注意通过HTTPS而不是HTTP提供文件下载时的IE7 / 8错误。 有关详细信息,请参阅IE无法下载foo.jsf。 IE无法打开这个网站。 请求的网站不可用或无法找到。


    (嘿,大家:请不要盲目地复制和粘贴所有标题,你可以找到)

    首先,后退按钮历史不是缓存:

    新鲜度模型(4.2节)不一定适用于历史机制。 也就是说,历史机制即使已经过期也可以显示先前的表示。

    在旧的HTTP规范中,措辞更加明显,明确地告诉浏览器忽略后退按钮历史记录的缓存指令。

    返回应该回到(回到用户登录时)的时间。 它不会前进到以前打开的URL。

    但是,在实践中,缓存可能会影响后退按钮,具体情况如下:

  • 必须通过HTTPS传递页面,否则此缓存清除将不可靠。 另外,如果你不使用HTTPS,那么你的页面很容易被其他许多方面的登录窃取。
  • 你必须发送Cache-Control: no-store, must-revalidate (一些浏览器观察no-store和一些观察must-revalidate
  • 你永远不需要任何:

  • 带缓存头的<meta> - 根本不起作用。 完全没用。
  • post-check / pre-check - 这是仅适用于可高速缓存资源的仅限IE的指令。
  • 发送相同的标题两次或十几个部分。 一些PHP代码片段实际上取代了之前的头文件,导致只发送最后一个头文件。
  • 如果你想,你可以添加:

  • no-cachemax-age=0 ,这会使资源(URL)“陈旧”,并且需要浏览器检查服务器是否有更新的版本( no-store已经暗示此更强)。
  • HTTP / 1.0客户端过去的日期Expires (尽管现在真正的仅限HTTP / 1.0的客户端完全不存在)。

  • 奖金:新的HTTP缓存RFC。


    正如porneL所说,你想要的不是停用缓存,而是停用历史缓冲区。 不同的浏览器有自己的微妙方法来禁用历史缓冲区。

    在Chrome(v28.0.1500.95 m)中,我们只能通过Cache-Control: no-store来完成此操作。

    在FireFox(v23.0.1)中,其中任何一个都可以工作:

  • Cache-Control: no-store

  • Cache-Control: no-cache (仅限https)

  • Pragma: no-cache (仅限https)

  • Vary: * (仅限https)

  • 在Opera(v12.15)中,我们只能通过Cache-Control: must-revalidate来做到这一点Cache-Control: must-revalidate (仅限https)。

    在Safari(v5.1.7,7534.57.2)中,其中任何一个都可以工作:

  • Cache-Control: no-store
    <body onunload="">在html中

  • Cache-Control: no-store (仅限https)

  • 在IE8(v8.0.6001.18702IC)中,其中任何一个都可以工作:

  • Cache-Control: must-revalidate, max-age=0

  • Cache-Control: no-cache

  • Cache-Control: no-store

  • Cache-Control: must-revalidate
    Expires: 0

  • Cache-Control: must-revalidate
    Expires: Sat, 12 Oct 1991 05:00:00 GMT

  • Pragma: no-cache (仅限https)

  • Vary: * (仅限https)

  • 结合上述提供的这个解决方案适用于Chrome 28,FireFox 23,IE8,Safari 5.1.7和Opera 12.15: Cache-Control: no-store, must-revalidate (仅限https)

    请注意,因为Opera不会停用纯HTTP页面的历史缓冲区,所以需要https。 如果你真的无法使用HTTPS并且你准备忽略Opera,那么你可以做的最好的事情是:

    Cache-Control: no-store
    <body onunload="">
    

    下面显示了我的测试的原始日志:

    HTTP:

  • Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    失败:Opera 12.15
    成功:Chrome 28,FireFox 23,IE8,Safari 5.1.7

  • Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    失败:Opera 12.15
    成功:Chrome 28,FireFox 23,IE8,Safari 5.1.7

  • Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    失败:Safari 5.1.7,Opera 12.15
    成功案例:Chrome 28,FireFox 23,IE8

  • Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    失败:Safari 5.1.7,Opera 12.15
    成功案例:Chrome 28,FireFox 23,IE8

  • Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    失败:Chrome 28,FireFox 23,Safari 5.1.7,Opera 12.15
    成功:IE8

  • Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    失败:Chrome 28,FireFox 23,Safari 5.1.7,Opera 12.15
    成功:IE8

  • Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    失败:Chrome 28,FireFox 23,Safari 5.1.7,Opera 12.15
    成功:IE8

  • Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    失败:Chrome 28,FireFox 23,Safari 5.1.7,Opera 12.15
    成功:IE8

  • Cache-Control: no-store
    失败:Safari 5.1.7,Opera 12.15
    成功案例:Chrome 28,FireFox 23,IE8

  • Cache-Control: no-store
    <body onunload="">
    失败:Opera 12.15
    成功:Chrome 28,FireFox 23,IE8,Safari 5.1.7

  • Cache-Control: no-cache
    失败:Chrome 28,FireFox 23,Safari 5.1.7,Opera 12.15
    成功:IE8

  • Vary: *
    失败:Chrome 28,FireFox 23,IE8,Safari 5.1.7,Opera 12.15
    成功:没有

  • Pragma: no-cache
    失败:Chrome 28,FireFox 23,IE8,Safari 5.1.7,Opera 12.15
    成功:没有

  • Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    失败:Chrome 28,FireFox 23,Safari 5.1.7,Opera 12.15
    成功:IE8

  • Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    失败:Chrome 28,FireFox 23,Safari 5.1.7,Opera 12.15
    成功:IE8

  • Cache-Control: must-revalidate, max-age=0
    失败:Chrome 28,FireFox 23,Safari 5.1.7,Opera 12.15
    成功:IE8

  • Cache-Control: must-revalidate
    Expires: 0
    失败:Chrome 28,FireFox 23,Safari 5.1.7,Opera 12.15
    成功:IE8

  • Cache-Control: must-revalidate
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    失败:Chrome 28,FireFox 23,Safari 5.1.7,Opera 12.15
    成功:IE8

  • Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    失败:Chrome 28,FireFox 23,IE8,Safari 5.1.7,Opera 12.15
    成功:没有

  • HTTPS:

  • Cache-Control: private, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    <body onunload="">
    失败:Chrome 28,FireFox 23,IE8,Safari 5.1.7,Opera 12.15
    成功:没有

  • Cache-Control: private, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    <body onunload="">
    失败:Chrome 28,FireFox 23,IE8,Safari 5.1.7,Opera 12.15
    成功:没有

  • Vary: *
    失败:Chrome 28,Safari 5.1.7,Opera 12.15
    成功:FireFox 23,IE8

  • Pragma: no-cache
    失败:Chrome 28,Safari 5.1.7,Opera 12.15
    成功:FireFox 23,IE8

  • Cache-Control: no-cache
    失败:Chrome 28,Safari 5.1.7,Opera 12.15
    成功:FireFox 23,IE8

  • Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0
    失败:Chrome 28,Safari 5.1.7,Opera 12.15
    成功:FireFox 23,IE8

  • Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    失败:Chrome 28,Safari 5.1.7,Opera 12.15
    成功:FireFox 23,IE8

  • Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    失败:Chrome 28,Safari 5.1.7,Opera 12.15
    成功:FireFox 23,IE8

  • Cache-Control: must-revalidate
    失败:Chrome 28,FireFox 23,IE8,Safari 5.1.7
    成功:Opera 12.15

  • Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0
    <body onunload="">
    失败:Chrome 28,FireFox 23,IE8,Safari 5.1.7
    成功:Opera 12.15

  • Cache-Control: must-revalidate, max-age=0
    失败:Chrome 28,FireFox 23,Safari 5.1.7
    成功:IE8,Opera 12.15

  • Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    失败:Chrome 28,Safari 5.1.7
    成功:FireFox 23,IE8,Opera 12.15

  • Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    失败:Chrome 28,Safari 5.1.7
    成功:FireFox 23,IE8,Opera 12.15

  • Cache-Control: no-store
    失败:Opera 12.15
    成功:Chrome 28,FireFox 23,IE8,Safari 5.1.7

  • Cache-Control: private, no-cache, no-store, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    失败:Opera 12.15
    成功:Chrome 28,FireFox 23,IE8,Safari 5.1.7

  • Cache-Control: private, no-cache, no-store, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    失败:Opera 12.15
    成功:Chrome 28,FireFox 23,IE8,Safari 5.1.7

  • Cache-Control: private, no-cache
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    失败:Chrome 28,Safari 5.1.7,Opera 12.15
    成功:FireFox 23,IE8

  • Cache-Control: must-revalidate
    Expires: 0
    失败:Chrome 28,FireFox 23,Safari 5.1.7,
    成功:IE8,Opera 12.15

  • Cache-Control: must-revalidate
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    失败:Chrome 28,FireFox 23,Safari 5.1.7,
    成功:IE8,Opera 12.15

  • Cache-Control: private, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    <body onunload="">
    失败:Chrome 28,FireFox 23,Safari 5.1.7,
    成功:IE8,Opera 12.15

  • Cache-Control: private, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    <body onunload="">
    失败:Chrome 28,FireFox 23,Safari 5.1.7,
    成功:IE8,Opera 12.15

  • Cache-Control: private, must-revalidate
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    失败:Chrome 28,Safari 5.1.7
    成功:FireFox 23,IE8,Opera 12.15

  • Cache-Control: no-store, must-revalidate
    失败:没有
    成功:Chrome 28,FireFox 23,IE8,Safari 5.1.7,Opera 12.15

  • 链接地址: http://www.djcxy.com/p/9501.html

    上一篇: How to control web page caching, across all browsers?

    下一篇: Prevent Caching in ASP.NET MVC for specific actions using an attribute