// `response` is an instance of System.Net.Http.HttpResponseMessage
response.Headers.CacheControl = new CacheControlHeaderValue
{
NoCache = true,
NoStore = true,
MustRevalidate = true
};
response.Headers.Pragma.ParseAdd("no-cache");
// We can't use `response.Content.Headers.Expires` directly
// since it allows only `DateTimeOffset?` values.
response.Content?.Headers.TryAddWithoutValidation("Expires", 0.ToString());
Update: 写完这个答案之后,我意识到我们的Web服务器将自己标识为HTTP 1.0服务器 . Headers 我've listed are the correct ones in order for responses from an HTTP 1.0 server to not be cached by browsers. For an HTTP 1.1 server, look at BalusC' s answer .
Cache-Control: must-revalidate Expires: Sat, 12 Oct 1991 05:00:00 GMT
Pragma: no-cache (仅限https)
Vary: * (仅限https)
Combining the above gives us this solution which works for Chrome 28, FireFox 23, IE8, Safari 5.1.7, and Opera 12.15:Cache-Control: no-store, must-revalidate (仅限https)
26 回答
请参阅此链接以获取有关缓存的案例研究:
http://securityevaluators.com/knowledge/case_studies/caching/
根据文章的总结,只有
Cache-Control: no-store
适用于Chrome,Firefox和IE . IE接受其他控件,但Chrome和Firefox不接受 . 链接是一个很好的阅读完成与缓存和记录概念证明的历史 .在我的情况下,我用铬修复了问题
当用户出于安全原因单击按钮时,我需要清除previus表单数据的内容
除了 Headers 之外,请考虑通过 https 为您的页面提供服务 . 许多浏览器默认不会缓存https .
要完成BalusC - > ANSWER如果您使用的是perl,则可以使用CGI添加HTTP标头 .
使用Perl:
使用apache httpd.conf
Note: 当我尝试使用html META时,浏览器会忽略它们并缓存页面 .
BalusC提供的答案中的 Headers 不会阻止Safari 5(以及可能的旧版本)在使用浏览器的后退按钮时显示浏览器缓存中的内容 . 防止这种情况的一种方法是向body标记添加一个空的onunload事件处理程序属性:
这个hack显然打破了Safari中的后向缓存:Is there a cross-browser onload event when clicking the back button?
HTTP 1.1的RFC说适当的方法是为以下内容添加HTTP标头:
缓存控制:无缓存
如果较旧的浏览器不正确地符合HTTP 1.1,则可能会忽略它 . 对于那些你可以尝试 Headers :
Pragma:没有缓存
这也适用于HTTP 1.1浏览器 .
经过一些研究后,我们提出了以下似乎涵盖大多数浏览器的 Headers 列表:
Expires:星期一,1997年7月26日05:00:00 GMT
Cache-Control:no-cache,私有,must-revalidate,max-stale = 0,post-check = 0,pre-check = 0 no-store
Pragma:无缓存
在ASP.NET中,我们使用以下代码段添加了这些内容:
发现:http://forums.asp.net/t/1013531.aspx
在响应中使用pragma标头是一个妻子的故事 . RFC2616仅将其定义为请求标头
http://www.mnot.net/cache_docs/#PRAGMA
我对
<head><meta>
元素没有运气 . 直接添加HTTP缓存相关参数(在HTML文档之外)确实对我有用 .Python中使用web.py
web.header
调用的示例代码如下 . 我故意编辑我的个人不相关的实用程序代码 .这些指令不会降低任何安全风险 . 它们实际上是为了迫使UA 's to refresh volatile information, not keep UA' s保留信息 . 见this similar question . 至少,不能保证任何路由器,代理等也不会忽略缓存指令 .
从更积极的角度来看,有关计算机物理访问,软件安装等的政策将使您在安全性方面领先于大多数公司 . 如果这些信息的消费者是公众的成员,那么你唯一能做的就是帮助他们理解,一旦信息到达他们的机器,那台机器就是责任,而不是你的 .
我只是想指出,如果有人想要阻止仅缓存动态内容,那么应该以编程方式添加这些额外的标头 .
我编辑了我的项目的配置文件以附加no-cache标头,但是也禁用了缓存静态内容,这通常是不可取的 . 修改代码中的响应标头可确保缓存图像和样式文件 .
这很明显,但仍值得一提 .
另一个警告 . 小心使用HttpResponse类中的ClearHeaders方法 . 如果你鲁莽地使用它可能会给你一些伤痕 . 喜欢它给了我 .
重定向ActionFilterAttribute事件后,清除所有标头的后果正在丢失TempData存储中的所有会话数据和数据 . 在重定向发生时,从Action重定向或不清除 Headers 更安全 .
第二个想法我不鼓励所有人使用ClearHeaders方法 . 最好分开删除 Headers . 并正确设置Cache-Control标头我正在使用此代码:
PHP documentation for the header function有一个相当完整的例子(由第三方提供):
简介
适用于所有提到的客户端(和代理)的正确最小标头集:
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代理 .如果您只通过
no-store
通过HTTPS提供页面时不关心IE6及其损坏的缓存,那么您可以省略Cache-Control: no-cache
.如果您不关心IE6或HTTP 1.0客户端(1997年引入了HTTP 1.1),那么您可以省略
Pragma
.如果您不关心HTTP 1.0代理,那么您可以省略
Expires
.另一方面,如果服务器自动包含有效的
Date
标头,那么理论上你也可以省略Cache-Control
并仅依赖Expires
.但是如果例如这可能会失败最终用户操纵操作系统日期,客户端软件依赖它 .
如果指定了上述
Cache-Control
参数,则其他Cache-Control
参数(如max-age
)无关紧要 . 这里的大多数其他答案中包含的Last-Modified Headers 仅在您缓存请求时才有意义,因此您根本不需要指定它 .如何设置?
使用PHP:
使用Java Servlet或Node.js:
使用ASP.NET-MVC
使用ASP.NET Web API:
使用ASP.NET:
使用ASP:
使用Ruby on Rails或Python / Flask:
使用Python / Django:
使用Python / Pyramid:
使用Go:
使用Apache
.htaccess
文件:使用HTML4:
HTML元标记与HTTP响应标头
重要的是要知道,当HTTP页面通过HTTP连接提供,并且HTTP响应头和HTML
<meta http-equiv>
标签中存在标头时,HTTP响应头中指定的标头将优先于HTML元标记 . 仅当通过file://
URL从本地磁盘文件系统查看页面时,才会使用HTML元标记 . 另见W3 HTML spec chapter 5.2.2 . 如果不以编程方式指定它们,请注意这一点,因为Web服务器可以包含一些默认值 .通常,您最好只是 not 指定HTML元标记以避免启动者混淆,并依赖于硬HTTP响应标头 . 此外,特别是那些
<meta http-equiv>
标签在HTML5中是invalid . 仅允许HTML5 specification中列出的http-equiv
值 .验证实际的HTTP响应标头
要验证这一个和另一个,您可以在webbrowser的开发人员工具集的HTTP流量监视器中查看/调试它们 . 您可以通过在Chrome / Firefox23 / IE9中按F12,然后打开"Network"或"Net"选项卡面板,然后单击感兴趣的HTTP请求来查看有关HTTP请求和响应的所有详细信息 . below screenshot来自Chrome:
我想在文件下载上设置这些 Headers
首先,这个问题和答案的目标是"web pages"(HTML页面),而不是"file downloads"(PDF,zip,Excel等) . 您最好将它们缓存并在URI路径或查询字符串中的某处使用某些文件版本标识符以强制在已更改的文件上重新下载 . 无论如何在文件下载时应用这些无缓存标头时,请注意通过HTTPS而不是HTTP提供文件下载时的IE7 / 8错误 . 有关详细信息,请参阅IE cannot download foo.jsf. IE was not able to open this internet site. The requested site is either unavailable or cannot be found .
我发现此页面上的所有答案仍然存在问题 . 特别是,我注意到当你通过点击后退按钮访问它时,它们都不会阻止IE8使用页面的缓存版本 .
经过大量的研究和测试,我发现我真正需要的唯一两个 Headers 是:
有关Vary标头的说明,请查看http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6
在IE6-8,FF1.5-3.5,Chrome 2-3,Safari 4和Opera 9-10上,当您单击页面链接或放置URL时,这些 Headers 会导致从服务器请求页面直接在地址栏中 . 这涵盖了截至2010年1月所使用的所有浏览器中的_235340 .
在IE6和Opera 9-10上,按下后退按钮仍然会导致加载缓存版本 . 在我测试的所有其他浏览器上,他们确实从服务器获取了一个新版本 . 到目前为止,我还没有找到任何一组 Headers ,当你点击后退按钮时,这些 Headers 会导致这些浏览器不返回页面的缓存版本 .
Update: 写完这个答案之后,我意识到我们的Web服务器将自己标识为HTTP 1.0服务器 . Headers 我've listed are the correct ones in order for responses from an HTTP 1.0 server to not be cached by browsers. For an HTTP 1.1 server, look at BalusC' s answer .
通过设置Pragma:no-cache,我在所有浏览器中获得了最佳和最一致的结果
另外,为了更好地衡量,如果您正在使用它来启用缓存,请确保重置
.htaccess
文件中的ExpiresDefault
.之后,您可以使用
ExpiresByType
为要缓存的文件设置特定值:如果你的动态文件例如,这也可以派上用场php等正在被浏览器缓存,你无法弄清楚原因 . 检查
ExpiresDefault
.我发现web.config路由很有用(尝试将其添加到答案中但似乎没有被接受,因此在此处发布)
这是express / node.js做同样的方式:
IE6中有一个错误
即使您使用“Cache-Control:no-cache”,也始终缓存带有“Content-Encoding:gzip”的内容 .
http://support.microsoft.com/kb/321722
您可以为IE6用户禁用gzip压缩(检查用户代理是否为“MSIE 6”)
如果您遇到IE6-IE8 over SSL和缓存的下载问题:无缓存标头(以及与MS Office文件类似的值),您可以在POST请求中使用cache:private,no-store标头和返回文件 . 有用 .
将修改后的http标头设置为1995年的某个日期通常可以解决问题 .
这是一个例子:
免责声明:我强烈建议阅读@BalusC的回答 . 阅读以下缓存教程后:http://www.mnot.net/cache_docs/(我建议您也阅读它),我认为这是正确的 . 但是,由于历史原因(以及我自己测试过),我将在下面提供我的原始答案:
我试过PHP的'接受'答案,这对我不起作用 . 然后我做了一点研究,发现了一个轻微的变种,测试了它,并且它有效 . 这里是:
这应该工作 . 问题是当设置 Headers 的相同部分两次时,如果
false
未作为第二个参数发送到 Headers 函数,则 Headers 函数将简单地覆盖之前的header()
调用 . 因此,在设置Cache-Control
时,例如,如果不希望将所有参数放在一个header()
函数调用中,他必须执行以下操作:查看更完整的文档here .
正如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
(仅限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)Combining the above gives us this solution which works for Chrome 28, FireFox 23, IE8, Safari 5.1.7, and Opera 12.15:
Cache-Control: no-store, must-revalidate
(仅限https)请注意,需要https,因为Opera不会为普通的http页面停用历史记录缓冲区 . 如果你真的无法获得https并且你准备忽略Opera,你可以做的最好的是:
下面显示了我的测试的原始日志:
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="">
失败:歌剧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="">
失败:歌剧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="">
失败:歌剧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,Safari5.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
失败:歌剧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="">
失败:歌剧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="">
失败:歌剧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
接受的答案似乎不适用于IIS7,因为大量关于缓存标头未在II7中发送的问题:
Something is forcing responses to have cache-control: private in IIS7
IIS7: Cache Setting Not Working... why?
IIS7 + ASP.NET MVC Client Caching Headers Not Working
Set cache-control for aspx pages
Cache-control: no-store, must-revalidate not sent to client browser in IIS7 + ASP.NET MVC
等等
接受的答案是正确的,必须设置哪个 Headers ,而不是必须如何设置 Headers . 这种方式适用于IIS7:
第一行将
Cache-control
设置为no-cache
,第二行添加其他属性no-store, must-revalidate
对于ASP.NET Core,创建一个简单的中间件类:
然后注册
Startup.cs
确保你之后添加它
(嘿,大家:请不要盲目地复制并粘贴你能找到的所有 Headers )
首先,Back button history is not a cache:
在旧的HTTP规范中,措辞甚至更强,明确告诉浏览器忽略后退按钮历史记录的缓存指令 .
返回应该回到过去(到用户登录的时候) . 它不会向前导航到先前打开的URL .
但是,实际上,在非常特定的情况下,缓存可以影响后退按钮:
页面必须通过 HTTPS 递送,否则此缓存破坏赢得了't be reliable. Plus, if you'不使用HTTPS,那么您的页面很容易在许多其他方式登录窃取 .
你必须发送
Cache-Control: no-store, must-revalidate
(某些浏览器观察no-store
,有些浏览器观察must-revalidate
)你永远不需要任何:
带有缓存标头的
<meta>
- 根本不起作用 . 完全没用 .post-check
/pre-check
- 它是仅适用于可缓存资源的IE-only指令 .两次或十几个部分发送相同的 Headers . 一些PHP片段实际上取代了以前的 Headers ,导致只发送了最后一个 .
如果需要,可以添加:
no-cache
或max-age=0
,这将使资源(URL)"stale"并要求浏览器检查服务器是否有更新的版本(no-store
已经暗示这更强大) .Expires
,其中包含HTTP / 1.0客户端的过去日期(尽管这些天真正的HTTP / 1.0仅客户端完全不存在) .额外奖励:The new HTTP caching RFC .