如何在所有浏览器上控制网页缓存?
我们的调查显示,并非所有浏览器都以统一的方式尊重http缓存指令。
出于安全原因,我们不希望在我们的应用程序某些网页缓存, 有史以来,通过Web浏览器。 这至少适用于以下浏览器:
我们的要求来自安全测试。 从我们的网站注销后,您可以按下后退按钮并查看缓存的页面。
介绍
在所有提到的客户端(和代理服务器)中都可以使用的正确的最小标题集合:
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:
我也想在文件下载中设置这些标题
首先,这个问题和答案是针对“网页”(HTML页面),而不是“文件下载”(PDF,zip,Excel等)。 您最好让它们缓存并在URI路径或查询字符串中的某处使用某个文件版本标识符来强制重新下载更改后的文件。 在文件下载中使用这些无缓存标头时,请注意通过HTTPS而不是HTTP提供文件下载时的IE7 / 8错误。 有关详细信息,请参阅IE无法下载foo.jsf。 IE无法打开这个网站。 请求的网站不可用或无法找到。
(嘿,大家:请不要盲目地复制和粘贴所有标题,你可以找到)
首先,后退按钮历史不是缓存:
新鲜度模型(4.2节)不一定适用于历史机制。 也就是说,历史机制即使已经过期也可以显示先前的表示。
在旧的HTTP规范中,措辞更加明显,明确地告诉浏览器忽略后退按钮历史记录的缓存指令。
返回应该回到(回到用户登录时)的时间。 它不会前进到以前打开的URL。
但是,在实践中,缓存可能会影响后退按钮,具体情况如下:
Cache-Control: no-store, must-revalidate
(一些浏览器观察no-store
和一些观察must-revalidate
) 你永远不需要任何:
<meta>
- 根本不起作用。 完全没用。 post-check
/ pre-check
- 这是仅适用于可高速缓存资源的仅限IE的指令。 如果你想,你可以添加:
no-cache
或max-age=0
,这会使资源(URL)“陈旧”,并且需要浏览器检查服务器是否有更新的版本( no-store
已经暗示此更强)。 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
上一篇: How to control web page caching, across all browsers?
下一篇: Prevent Caching in ASP.NET MVC for specific actions using an attribute