我们如何控制所有浏览器的网页缓存?

发布于 2024-07-04 12:17:38 字数 292 浏览 8 评论 0原文

我们的调查表明,并非所有浏览器都以统一的方式遵守 HTTP 缓存指令。

出于安全原因,我们不希望网络浏览器永远缓存应用程序中的某些页面。 这必须至少适用于以下浏览器:

  • Internet Explorer 6+
  • Firefox 1.5+
  • Safari 3+
  • Opera 9+
  • Chrome

我们的要求来自安全测试。 从我们的网站注销后,您可以按后退按钮并查看缓存的页面。

Our investigations have shown us that not all browsers respect the HTTP cache directives in a uniform manner.

For security reasons we do not want certain pages in our application to be cached, ever, by the web browser. This must work for at least the following browsers:

  • Internet Explorer 6+
  • Firefox 1.5+
  • Safari 3+
  • Opera 9+
  • Chrome

Our requirement came from a security test. After logging out from our website you could press the back button and view cached pages.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

ˇ宁静的妩媚 2024-07-11 12:17:38

另外,为了更好地衡量,如果您使用 .htaccess 文件启用缓存,请确保重置 ExpiresDefault 文件。

ExpiresDefault "access plus 0 seconds"

之后,您可以使用 ExpiresByType 为要缓存的文件设置特定值:

ExpiresByType image/x-icon "access plus 3 month"

如果您的动态文件(例如 php 等)被浏览器缓存,这也可能会派上用场,您可以不明白为什么。 检查ExpiresDefault

Also, just for good measure, make sure you reset the ExpiresDefault in your .htaccess file if you're using that to enable caching.

ExpiresDefault "access plus 0 seconds"

Afterwards, you can use ExpiresByType to set specific values for the files you want to cache:

ExpiresByType image/x-icon "access plus 3 month"

This may also come in handy if your dynamic files e.g. php, etc. are being cached by the browser, and you can't figure out why. Check ExpiresDefault.

关于从前 2024-07-11 12:17:38

我发现 web.config 路由很有用(尝试将其添加到答案中,但似乎没有被接受,因此在此发布)

<configuration>
<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Cache-Control" value="no-cache, no-store, must-revalidate" />
            <!-- HTTP 1.1. -->
            <add name="Pragma" value="no-cache" />
            <!-- HTTP 1.0. -->
            <add name="Expires" value="0" />
            <!-- Proxies. -->
        </customHeaders>
    </httpProtocol>
</system.webServer>

这是执行相同操作的express/node.js 方法:

app.use(function(req, res, next) {
    res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
    res.setHeader('Pragma', 'no-cache');
    res.setHeader('Expires', '0');
    next();
});

I found the web.config route useful (tried to add it to the answer but doesn't seem to have been accepted so posting here)

<configuration>
<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Cache-Control" value="no-cache, no-store, must-revalidate" />
            <!-- HTTP 1.1. -->
            <add name="Pragma" value="no-cache" />
            <!-- HTTP 1.0. -->
            <add name="Expires" value="0" />
            <!-- Proxies. -->
        </customHeaders>
    </httpProtocol>
</system.webServer>

And here is the express / node.js way of doing the same:

app.use(function(req, res, next) {
    res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
    res.setHeader('Pragma', 'no-cache');
    res.setHeader('Expires', '0');
    next();
});
心意如水 2024-07-11 12:17:38

我发现这个页面上的所有答案仍然有问题。 特别是,我注意到,当您通过点击后退按钮访问该页面时,它们都不会阻止 IE8 使用该页面的缓存版本。

经过大量研究和测试,我发现我真正需要的唯一两个标头是:

缓存控制:无存储
变化:*

有关 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 放入地址栏中时,这些标头会导致从服务器请求该页面。 截至 1 月,这涵盖了大约 99% 正在使用的浏览器'10。

在 IE6 和 Opera 9-10 上,点击后退按钮仍然会导致加载缓存版本。 在我测试的所有其他浏览器上,它们确实从服务器获取了新版本。 到目前为止,我还没有发现任何一组标头会导致这些浏览器在您点击后退按钮时不返回页面的缓存版本。

更新:写完这个答案后,我意识到我们的网络服务器将自己标识为 HTTP 1.0 服务器。 我列出的标头是正确的标头,以便浏览器不会缓存来自 HTTP 1.0 服务器的响应。 对于 HTTP 1.1 服务器,请查看 BalusC 的 回答

I found that all of the answers on this page still had problems. In particular, I noticed that none of them would stop IE8 from using a cached version of the page when you accessed it by hitting the back button.

After much research and testing, I found that the only two headers I really needed were:

Cache-Control: no-store
Vary: *

For an explanation of the Vary header, check out http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6

On IE6-8, FF1.5-3.5, Chrome 2-3, Safari 4, and Opera 9-10, these headers caused the page to be requested from the server when you click on a link to the page, or put the URL directly in the address bar. That covers about 99% of all browsers in use as of Jan '10.

On IE6, and Opera 9-10, hitting the back button still caused the cached version to be loaded. On all other browsers I tested, they did fetch a fresh version from the server. So far, I haven't found any set of headers that will cause those browsers to not return cached versions of pages when you hit the back button.

Update: After writing this answer, I realized that our web server is identifying itself as an HTTP 1.0 server. The headers I'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.

欲拥i 2024-07-11 12:17:38

请参阅有关缓存的案例研究的链接:

http://securityevaluators.com/knowledge/case_studies/caching /

总结,根据文章所述,只有 Cache-Control: no-store 适用于 Chrome、Firefox 和 IE。 IE 接受其他控件,但 Chrome 和 Firefox 不接受。 该链接是一本很好的读物,其中包含缓存的历史和记录概念证明。

See this link to a Case Study on Caching:

http://securityevaluators.com/knowledge/case_studies/caching/

Summary, according to the article, only Cache-Control: no-store works on Chrome, Firefox and IE. IE accepts other controls, but Chrome and Firefox do not. The link is a good read complete with the history of caching and documenting proof of concept.

甜是你 2024-07-11 12:17:38

免责声明:我强烈建议阅读@BalusC 的答案。 阅读以下缓存教程后: http://www.mnot.net/cache_docs/ (我建议您也阅读它),我相信它是正确的。 然而,由于历史原因(并且因为我自己测试过),我将在下面包含我的原始答案:


我尝试了 PHP 的“已接受”答案,但它对我不起作用。 然后我做了一些研究,发现了一个轻微的变体,并对其进行了测试,并且它起作用了。 就是这样:

header('Cache-Control: no-store, private, no-cache, must-revalidate');     // HTTP/1.1
header('Cache-Control: pre-check=0, post-check=0, max-age=0, max-stale = 0', false);  // HTTP/1.1
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');                  // Date in the past  
header('Expires: 0', false); 
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
header ('Pragma: no-cache');

应该可以。 问题是,当两次设置标头的同一部分时,如果 false 没有作为第二个参数发送给标头函数,标头函数将简单地覆盖之前的 header()< /代码> 调用。 因此,在设置 Cache-Control 时,例如,如果不想将所有参数放入一个 header() 函数调用中,则必须执行以下操作:

header('Cache-Control: this');
header('Cache-Control: and, this', false);

请在此处查看更完整的文档。

DISCLAIMER: I strongly suggest reading @BalusC's answer. After reading the following caching tutorial: http://www.mnot.net/cache_docs/ (I recommend you read it, too), I believe it to be correct. However, for historical reasons (and because I have tested it myself), I will include my original answer below:


I tried the 'accepted' answer for PHP, which did not work for me. Then I did a little research, found a slight variant, tested it, and it worked. Here it is:

header('Cache-Control: no-store, private, no-cache, must-revalidate');     // HTTP/1.1
header('Cache-Control: pre-check=0, post-check=0, max-age=0, max-stale = 0', false);  // HTTP/1.1
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');                  // Date in the past  
header('Expires: 0', false); 
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
header ('Pragma: no-cache');

That should work. The problem was that when setting the same part of the header twice, if the false is not sent as the second argument to the header function, header function will simply overwrite the previous header() call. So, when setting the Cache-Control, for example if one does not want to put all the arguments in one header() function call, he must do something like this:

header('Cache-Control: this');
header('Cache-Control: and, this', false);

See more complete documentation here.

知足的幸福 2024-07-11 12:17:38

您可以使用位置块来设置单个文件,而不是整个应用程序在 IIS 中获取缓存

 <location path="index.html">
    <system.webServer>
      <httpProtocol>
        <customHeaders>
          <add name="Cache-Control" value="no-cache" />
        </customHeaders>
      </httpProtocol>
    </system.webServer>
  </location>

you can use location block for set individual file instead of whole app get caching in IIS

 <location path="index.html">
    <system.webServer>
      <httpProtocol>
        <customHeaders>
          <add name="Cache-Control" value="no-cache" />
        </customHeaders>
      </httpProtocol>
    </system.webServer>
  </location>
赠我空喜 2024-07-11 12:17:38

通过设置,我在所有浏览器中获得了最佳且最一致的结果
编译指示:无缓存

I've had best and most consistent results across all browsers by setting
Pragma: no-cache

临风闻羌笛 2024-07-11 12:17:38

除了标头之外,还可以考虑通过 https 提供您的页面。 许多浏览器默认不会缓存 https。

In addition to the headers consider serving your page via https. Many browsers will not cache https by default.

以酷 2024-07-11 12:17:38

BalusC 提供的答案中的标头不会阻止 Safari 5(也可能是旧版本)在使用浏览器的后退按钮时显示浏览器缓存中的内容。 防止这种情况的一种方法是向 body 标记添加一个空的 onunload 事件处理程序属性:

<body onunload=""> 

此 hack 显然破坏了 Safari 中的前后缓存: 点击后退按钮时是否有跨浏览器onload事件?

The headers in the answer provided by BalusC does not prevent Safari 5 (and possibly older versions as well) from displaying content from the browser cache when using the browser's back button. A way to prevent this is to add an empty onunload event handler attribute to the body tag:

<body onunload=""> 

This hack apparently breaks the back-forward cache in Safari: Is there a cross-browser onload event when clicking the back button?

樱桃奶球 2024-07-11 12:17:38

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

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

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

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

Back 应该返回到过去(到用户登录的时间)。 它不会向前导航到以前打开的 URL。

然而,实际上,在非常特殊的情况下,缓存可能会影响后退按钮:

  • 页面必须通过HTTPS传送,否则,这种缓存破坏将不可靠。 另外,如果您不使用 HTTPS,那么您的页面很容易受到许多其他方式的登录窃取。
  • 必须发送Cache-Control:no-store,must-revalidate(有些浏览器观察no-store,有些浏览器观察must-revalidate

永远不需要任何:

  • 带有缓存标头的 - 它根本不起作用。 完全没用。
  • post-check/pre-check — 这是一个仅适用于 IE 的指令,仅适用于可缓存资源。
  • 发送相同的标头两次或分成十几部分。 一些 PHP 片段实际上替换了以前的标头,导致只发送最后一个标头。

如果需要,您可以添加:

  • no-cachemax-age=0,这将使资源(URL)“过时”并要求浏览器与服务器检查如果有更新的版本(no-store 已经意味着这更强大)。
  • 对于 HTTP/1.0 客户端,过期 的日期是过去的日期(尽管现在完全不存在仅支持 HTTP/1.0 的客户端)。

奖励:新的 HTTP 缓存 RFC

(hey, everyone: please don't just mindlessly copy&paste all headers you can find)

First of all, Back button history is not a cache:

The freshness model (Section 4.2) does not necessarily apply to history mechanisms. That is, a history mechanism can display a previous representation even if it has expired.

In the old HTTP spec, the wording was even stronger, explicitly telling browsers to disregard cache directives for back button history.

Back is supposed to go back in time (to the time when the user was logged in). It does not navigate forward to a previously opened URL.

However, in practice, the cache can influence the back button, in very specific circumstances:

  • Page must be delivered over HTTPS, otherwise, this cache-busting won't be reliable. Plus, if you're not using HTTPS, then your page is vulnerable to login stealing in many other ways.
  • You must send Cache-Control: no-store, must-revalidate (some browsers observe no-store and some observe must-revalidate)

You never need any of:

  • <meta> with cache headers — it doesn't work at all. Totally useless.
  • post-check/pre-check — it's an IE-only directive that only applies to cachable resources.
  • Sending the same header twice or in dozen parts. Some PHP snippets out there actually replace previous headers, resulting in only the last one being sent.

If you want, you could add:

  • no-cache or max-age=0, which will make resource (URL) "stale" and require browsers to check with the server if there's a newer version (no-store already implies this even stronger).
  • Expires with a date in the past for HTTP/1.0 clients (although real HTTP/1.0-only clients are completely non-existent these days).

Bonus: The new HTTP caching RFC.

少女七分熟 2024-07-11 12:17:38

要完成 BalusC -> 答案
如果您使用 Perl,则可以使用 CGI 添加 HTTP 标头。

使用 Perl:

Use CGI;    
sub set_new_query() {
        binmode STDOUT, ":utf8";
        die if defined $query;
        $query = CGI->new();
        print $query->header(
                        -expires       => 'Sat, 26 Jul 1997 05:00:00 GMT',
                        -Pragma        => 'no-cache',
                        -Cache_Control => join(', ', qw(
                                            private
                                            no-cache
                                            no-store
                                            must-revalidate
                                            max-age=0
                                            pre-check=0
                                            post-check=0 
                                           ))
        );
    }

使用 apache httpd.conf

<FilesMatch "\.(html|htm|js|css|pl)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>

注意:当我尝试使用 html META 时,浏览器会忽略它们并缓存页面。

To complete BalusC -> ANSWER
If you are using perl you can use CGI to add HTTP headers.

Using Perl:

Use CGI;    
sub set_new_query() {
        binmode STDOUT, ":utf8";
        die if defined $query;
        $query = CGI->new();
        print $query->header(
                        -expires       => 'Sat, 26 Jul 1997 05:00:00 GMT',
                        -Pragma        => 'no-cache',
                        -Cache_Control => join(', ', qw(
                                            private
                                            no-cache
                                            no-store
                                            must-revalidate
                                            max-age=0
                                            pre-check=0
                                            post-check=0 
                                           ))
        );
    }

Using apache httpd.conf

<FilesMatch "\.(html|htm|js|css|pl)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>

Note: When I tried to use the html META, browsers ignored them and cached the page.

我爱人 2024-07-11 12:17:38
//In .net MVC
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult FareListInfo(long id)
{
}

// In .net webform
<%@ OutputCache NoStore="true" Duration="0" VaryByParam="*" %>
//In .net MVC
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult FareListInfo(long id)
{
}

// In .net webform
<%@ OutputCache NoStore="true" Duration="0" VaryByParam="*" %>
浪漫之都 2024-07-11 12:17:38

接受的答案似乎不适用于 IIS7+,因为有关 II7 中未发送缓存标头的大量问题:

等等

接受的答案是正确的,其中必须设置标头,但不是必须如何设置它们。 这种方式适用于 IIS7:

Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.AppendCacheExtension("no-store, must-revalidate");
Response.AppendHeader("Pragma", "no-cache");
Response.AppendHeader("Expires", "-1");

第一行将 Cache-control 设置为 no-cache,第二行添加其他属性 no-store、must-revalidate

The accepted answer does not appear to work for IIS7+, going by the large number of questions about cache headers not being sent in II7:

And so on

The accepted answer is correct in which headers must be set, but not in how they must be set. This way works with IIS7:

Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.AppendCacheExtension("no-store, must-revalidate");
Response.AppendHeader("Pragma", "no-cache");
Response.AppendHeader("Expires", "-1");

The first line sets Cache-control to no-cache, and the second line adds the other attributes no-store, must-revalidate

八巷 2024-07-11 12:17:38

就我而言,我解决了 chrome 中的问题,

<form id="form1" runat="server" autocomplete="off">

当用户出于安全原因单击返回按钮时,我需要清除先前表单数据的内容

in my case i fix the problem in chrome with this

<form id="form1" runat="server" autocomplete="off">

where i need to clear the content of a previus form data when the users click button back for security reasons

无名指的心愿 2024-07-11 12:17:38

header 函数的 PHP 文档 有一个相当完整的示例(由第三方提供):

    header('Pragma: public');
    header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");                  // Date in the past   
    header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
    header('Cache-Control: no-store, no-cache, must-revalidate');     // HTTP/1.1
    header('Cache-Control: pre-check=0, post-check=0, max-age=0', false);    // HTTP/1.1
    header ("Pragma: no-cache");
    header("Expires: 0", false);

The PHP documentation for the header function has a rather complete example (contributed by a third party):

    header('Pragma: public');
    header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");                  // Date in the past   
    header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
    header('Cache-Control: no-store, no-cache, must-revalidate');     // HTTP/1.1
    header('Cache-Control: pre-check=0, post-check=0, max-age=0', false);    // HTTP/1.1
    header ("Pragma: no-cache");
    header("Expires: 0", false);
野鹿林 2024-07-11 12:17:38

如果您遇到 IE6-IE8 通过 SSL 和 MS Office 文件的缓存:无缓存标头(和类似值)的下载问题,您可以使用缓存:私有、无存储标头并在 POST 请求上返回文件。 有用。

If you're facing download problems with IE6-IE8 over SSL and cache:no-cache header (and similar values) with MS Office files you can use cache:private,no-store header and return file on POST request. It works.

岁月打碎记忆 2024-07-11 12:17:38

将修改后的 http 标头设置为 1995 年的某个日期通常可以解决问题。

这是一个例子:

Expires: Wed, 15 Nov 1995 04:58:08 GMT
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
Cache-Control: no-cache, must-revalidate

Setting the modified http header to some date in 1995 usually does the trick.

Here's an example:

Expires: Wed, 15 Nov 1995 04:58:08 GMT
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
Cache-Control: no-cache, must-revalidate
绅士风度i 2024-07-11 12:17:38

HTTP 1.1 的 RFC 表示正确的方法是添加 HTTP 标头for:

Cache-Control: no-cache

如果较旧的浏览器未正确兼容 HTTP 1.1,则可能会忽略此设置。 对于那些你可以尝试标头:

Pragma: no-cache

这也应该适用于 HTTP 1.1 浏览器。

The RFC for HTTP 1.1 says the proper method is to add an HTTP Header for:

Cache-Control: no-cache

Older browsers may ignore this if they are not properly compliant to HTTP 1.1. For those you can try the header:

Pragma: no-cache

This is also supposed to work for HTTP 1.1 browsers.

负佳期 2024-07-11 12:17:38

对于 IIS web.config,您可以使用它:

<configuration>
  <system.webServer>
    <rewrite>
      <outboundRules>
        <rule name="RewriteCacheControlForHtmlFile" preCondition="IsHtmlFile">
          <match serverVariable="RESPONSE_Cache_Control" pattern=".*" />
          <action type="Rewrite" value="no-cache, no-store, must-revalidate" />
        </rule>
        <rule name="RewritePragmaForHtmlFile" preCondition="IsHtmlFile">
          <match serverVariable="RESPONSE_Pragma" pattern=".*" />
          <action type="Rewrite" value="no-cache" />
        </rule>
        <rule name="RewriteExpiresForHtmlFile" preCondition="IsHtmlFile">
          <match serverVariable="RESPONSE_Expires" pattern=".*" />
          <action type="Rewrite" value="0" />
        </rule>
        <preConditions>
          <preCondition name="IsHtmlFile">
            <add input="{RESPONSE_CONTENT_TYPE}" pattern="html$" />
          </preCondition>
        </preConditions>
      </outboundRules>
    </rewrite>
    <security>
      <requestFiltering allowDoubleEscaping="true" />
    </security>
  </system.webServer>
</configuration>

它仅适用于索引文件,而不适用于您仍可能想要缓存的其他文件。

For IIS web.config you can use this:

<configuration>
  <system.webServer>
    <rewrite>
      <outboundRules>
        <rule name="RewriteCacheControlForHtmlFile" preCondition="IsHtmlFile">
          <match serverVariable="RESPONSE_Cache_Control" pattern=".*" />
          <action type="Rewrite" value="no-cache, no-store, must-revalidate" />
        </rule>
        <rule name="RewritePragmaForHtmlFile" preCondition="IsHtmlFile">
          <match serverVariable="RESPONSE_Pragma" pattern=".*" />
          <action type="Rewrite" value="no-cache" />
        </rule>
        <rule name="RewriteExpiresForHtmlFile" preCondition="IsHtmlFile">
          <match serverVariable="RESPONSE_Expires" pattern=".*" />
          <action type="Rewrite" value="0" />
        </rule>
        <preConditions>
          <preCondition name="IsHtmlFile">
            <add input="{RESPONSE_CONTENT_TYPE}" pattern="html
quot; />
          </preCondition>
        </preConditions>
      </outboundRules>
    </rewrite>
    <security>
      <requestFiltering allowDoubleEscaping="true" />
    </security>
  </system.webServer>
</configuration>

It will only apply to the index files and not other files you still might want to be cached.

書生途 2024-07-11 12:17:38

我已经用这种方法解决了。

2 个注意事项:

1)服务器端事件不会在后退单击时触发,而是在 javascript 上触发。

2)我有2个javascript来读取/写入

function setCookie(name, value, days)
{
    var expires = "";
    if (days)
    {
        var date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + (value || "") + expires + "; path=/";
}

function getCookie(name)
{
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');

    for (var i = ca.length - 1; i >= 0; i--)
    {
        var c = ca[i];
        while (c.charAt(0) == ' ')
        {
            c = c.substring(1, c.length);
        }

        if (c.indexOf(nameEQ) == 0)
        {
            return c.substring(nameEQ.length, c.length);
        }
    }
    return null;
}

我的Page_Load中的cookie,我插入了这个:(这不会在后退单击时触发)

    protected void Page_Load(object sender, EventArgs e)
    {
       Page.RegisterClientScriptBlock("", "<script>setCookie('" + Session.SessionID + "', '" + Login + "', '100');</script>");
    }

其中“登录”是我的id值,注销后为-1(您可以使用其他东西,一个布尔值)例如)。

然后在我的页面中我添加了以下内容:(这是在后退单击时触发的)

<script type="text/javascript">
if (getCookie('<%= Session.SessionID %>') < 0)
        {
            if (history.length > 0)
            {
                history.go(+1);
            }
        }

</script>

没有其他内容。

使用此解决方案,后退单击在每个页面上启用,并且仅在同一浏览器上的每个页面上注销后禁用。

i have solved in this way.

2 considerations:

1) the server side events are not fired on back click, instead of javascript.

2) i have 2 javascript to read/write cookies

function setCookie(name, value, days)
{
    var expires = "";
    if (days)
    {
        var date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + (value || "") + expires + "; path=/";
}

function getCookie(name)
{
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');

    for (var i = ca.length - 1; i >= 0; i--)
    {
        var c = ca[i];
        while (c.charAt(0) == ' ')
        {
            c = c.substring(1, c.length);
        }

        if (c.indexOf(nameEQ) == 0)
        {
            return c.substring(nameEQ.length, c.length);
        }
    }
    return null;
}

in my Page_Load i inserted this: (this is NOT fired on back click)

    protected void Page_Load(object sender, EventArgs e)
    {
       Page.RegisterClientScriptBlock("", "<script>setCookie('" + Session.SessionID + "', '" + Login + "', '100');</script>");
    }

where 'Login' is my id value that is -1 after logout (you could use something else, a boolean for example).

then in my page i added this: (this IS fired on back click)

<script type="text/javascript">
if (getCookie('<%= Session.SessionID %>') < 0)
        {
            if (history.length > 0)
            {
                history.go(+1);
            }
        }

</script>

nothing else.

with this solution back click is enable on every page and disable only after logout on each page on the same browser.

梦太阳 2024-07-11 12:17:38

我只是想指出,如果有人想阻止仅缓存动态内容,则应以编程方式添加这些附加标头。

我编辑了项目的配置文件以附加无缓存标头,但这也禁用了缓存静态内容,这通常是不可取的。
修改代码中的响应标头可确保缓存图像和样式文件。

这是很明显的,但仍然值得一提。

还有一个警告。 使用 HttpResponse 类中的 ClearHeaders 方法时要小心。 如果你鲁莽地使用它,可能会给你带来一些瘀伤。 就像它给了我一样。

在 ActionFilterAttribute 事件上重定向后,清除所有标头的后果是丢失所有会话数据和 TempData 存储中的数据。 从操作重定向或者在重定向发生时不清除标头会更安全。

再想一想,我不鼓励所有人使用 ClearHeaders 方法。 最好单独删除标头。 为了正确设置 Cache-Control 标头,我使用以下代码:

filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.AppendCacheExtension("no-store, must-revalidate");

I just want to point out that if someone wants to prevent caching ONLY dynamic content, adding those additional headers should be made programmatically.

I edited configuration file of my project to append no-cache headers, but that also disabled caching static content, which isn't usually desirable.
Modifying response headers in code assures that images and style files will be cached.

This is quite obvious, yet still worth mentioning.

And another caution. Be careful using ClearHeaders method from HttpResponse class. It may give you some bruises if you use it recklessly. Like it gave me.

After redirecting on ActionFilterAttribute event the consequences of clearing all headers are losing all session data and data in TempData storage. It's safer to redirect from an Action or don't clear headers when redirection is taking place.

On second thought I discourage all to use ClearHeaders method. It's better to remove headers separately. And to set Cache-Control header properly I'm using this code:

filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.AppendCacheExtension("no-store, must-revalidate");
七七 2024-07-11 12:17:38

我对 元素没有运气。 直接添加 HTTP 缓存相关参数(在 HTML 文档之外)确实对我有用。

使用 web.py web.header 调用的 Python 示例代码如下。 我故意编辑了与个人无关的实用程序代码。

    import web
    import sys
    import PERSONAL-UTILITIES

    myname = "main.py"

    urls = (
        '/', 'main_class'
    )

    main = web.application(urls, globals())

    render = web.template.render("templates/", base="layout", cache=False)

    class main_class(object):
        def GET(self):
            web.header("Cache-control","no-cache, no-store, must-revalidate")
            web.header("Pragma", "no-cache")
            web.header("Expires", "0")
            return render.main_form()

        def POST(self):
            msg = "POSTed:"
            form = web.input(function = None)
            web.header("Cache-control","no-cache, no-store, must-revalidate")
            web.header("Pragma", "no-cache")
            web.header("Expires", "0")
            return render.index_laid_out(greeting = msg + form.function)

    if __name__ == "__main__":
        nargs = len(sys.argv)
        # Ensure that there are enough arguments after python program name
        if nargs != 2:
            LOG-AND-DIE("%s: Command line error, nargs=%s, should be 2", myname, nargs)
        # Make sure that the TCP port number is numeric
        try:
            tcp_port = int(sys.argv[1])
        except Exception as e:
            LOG-AND-DIE ("%s: tcp_port = int(%s) failed (not an integer)", myname, sys.argv[1])
        # All is well!
        JUST-LOG("%s: Running on port %d", myname, tcp_port)
        web.httpserver.runsimple(main.wsgifunc(), ("localhost", tcp_port))
        main.run()

I had no luck with <head><meta> elements. Adding HTTP cache related parameters directly (outside of the HTML doc) does indeed work for me.

Sample code in Python using web.py web.header calls follows. I purposefully redacted my personal irrelevant utility code.

    import web
    import sys
    import PERSONAL-UTILITIES

    myname = "main.py"

    urls = (
        '/', 'main_class'
    )

    main = web.application(urls, globals())

    render = web.template.render("templates/", base="layout", cache=False)

    class main_class(object):
        def GET(self):
            web.header("Cache-control","no-cache, no-store, must-revalidate")
            web.header("Pragma", "no-cache")
            web.header("Expires", "0")
            return render.main_form()

        def POST(self):
            msg = "POSTed:"
            form = web.input(function = None)
            web.header("Cache-control","no-cache, no-store, must-revalidate")
            web.header("Pragma", "no-cache")
            web.header("Expires", "0")
            return render.index_laid_out(greeting = msg + form.function)

    if __name__ == "__main__":
        nargs = len(sys.argv)
        # Ensure that there are enough arguments after python program name
        if nargs != 2:
            LOG-AND-DIE("%s: Command line error, nargs=%s, should be 2", myname, nargs)
        # Make sure that the TCP port number is numeric
        try:
            tcp_port = int(sys.argv[1])
        except Exception as e:
            LOG-AND-DIE ("%s: tcp_port = int(%s) failed (not an integer)", myname, sys.argv[1])
        # All is well!
        JUST-LOG("%s: Running on port %d", myname, tcp_port)
        web.httpserver.runsimple(main.wsgifunc(), ("localhost", tcp_port))
        main.run()

烈酒灼喉 2024-07-11 12:17:38

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

在 Chrome (v28.0.1500.95 m) 中,我们只能通过 Cache-Control: no-store 来做到这一点。

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

  1. Cache-Control: no-store

  2. < p>Cache-Control: no-cache(仅限 https)

  3. Pragma: no-cache(仅限 https)

  4. Vary:*(仅限 https)

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

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

  1. Cache-Control: no-store

    in html

  2. Cache-Control: no-store(仅限 https)

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

  1. Cache-Control: Must-revalidate, max-age=0< /code>

  2. 缓存控制:无缓存

  3. 缓存控制:无存储

  4. 缓存控制:必须重新验证

    过期:0

  5. 缓存控制:必须重新验证

    过期:1991 年 10 月 12 日星期六 05:00:00 GMT

  6. Pragma:no-cache(仅限 https)

  7. 变化:*(仅限https)

结合以上内容,我们得到了适用于 Chrome 28、FireFox 23、IE8、Safari 5.1.7 和 Opera 12.15 的解决方案: Cache-Control: no-store, Must-revalidate (仅 https)

请注意,需要 https,因为 Opera 不会停用纯 http 页面的历史缓冲区。 如果你确实无法获取 https 并且准备忽略 Opera,那么你能做的最好的事情就是:

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

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

HTTP:

  1. Cache-控制:私有、无缓存、无存储、必须重新验证、max-age=0、代理重新验证、s-maxage=0

    过期:0

    编译指示:无缓存

    变化:*



    失败:Opera 12.15

    成功:Chrome 28、FireFox 23、IE8、Safari 5.1.7

  2. 缓存控制:私有、无缓存、无存储、必须重新验证、最大年龄=0、代理重新验证, s-maxage=0

    到期时间:1991 年 10 月 12 日星期六 05:00:00 GMT

    编译指示:无缓存

    变化:*



    失败:Opera 12.15

    成功:Chrome 28、FireFox 23、IE8、Safari 5.1.7

  3. 缓存控制:私有、无缓存、无存储、必须重新验证、最大年龄=0、代理重新验证, s-maxage=0

    过期:0

    编译指示:无缓存

    变化:*

    失败:Safari 5.1.7、Opera 12.15

    成功:Chrome 28、FireFox 23、IE8

  4. 缓存控制:私有、无缓存、无存储、必须重新验证、max-age=0、代理重新验证、s-maxage= 0

    到期时间:1991 年 10 月 12 日星期六 05:00:00 GMT

    编译指示:无缓存

    变化:*

    失败:Safari 5.1.7、Opera 12.15

    成功:Chrome 28、FireFox 23、IE8

  5. 缓存控制:私有、无缓存、必须重新验证、max-age=0、代理重新验证、s-maxage=0

    过期:0

    编译指示:无缓存

    变化:*



    失败:Chrome 28、FireFox 23、Safari 5.1.7、Opera 12.15

    成功:IE8

  6. 缓存控制:私有、无缓存、必须重新验证、max-age=0、代理重新验证、s-maxage=0

    到期时间:1991 年 10 月 12 日星期六 05:00:00 GMT

    编译指示:无缓存

    变化:*



    失败:Chrome 28、FireFox 23、Safari 5.1.7、Opera 12.15

    成功:IE8

  7. 缓存控制:私有、无缓存、必须重新验证、max-age=0、代理重新验证、s-maxage=0

    过期:0

    编译指示:无缓存

    变化:*



    失败:Chrome 28、FireFox 23、Safari 5.1.7、Opera 12.15

    成功:IE8

  8. 缓存控制:私有、无缓存、必须重新验证、max-age=0、代理重新验证、s-maxage=0

    过期时间:1991 年 10 月 12 日星期六 05:00:00 GMT

    编译指示:无缓存

    变化:*



    失败:Chrome 28、FireFox 23、Safari 5.1.7、Opera 12.15

    成功:IE8

  9. 缓存控制:无存储

    失败:Safari 5.1.7、Opera 12.15

    成功:Chrome 28、FireFox 23、IE8

  10. 缓存控制:无存储



    失败:Opera 12.15

    成功:Chrome 28、FireFox 23、IE8、Safari 5.1.7

  11. 缓存控制:无缓存

    失败:Chrome 28、FireFox 23、Safari 5.1.7、Opera 12.15

    成功:IE8

  12. 变化:*

    失败:Chrome 28、FireFox 23、IE8、Safari 5.1.7、Opera 12.15

    成功:无

  13. Pragma:无缓存

    失败:Chrome 28、FireFox 23、IE8、Safari 5.1.7、Opera 12.15

    成功:无

  14. 缓存控制:私有、无缓存、必须重新验证、max-age=0、代理重新验证、s-maxage=0

    过期时间:1991 年 10 月 12 日星期六 05:00:00 GMT

    编译指示:无缓存

    变化:*



    失败:Chrome 28、FireFox 23、Safari 5.1.7、Opera 12.15

    成功:IE8

  15. 缓存控制:私有、无缓存、必须重新验证、max-age=0、代理重新验证、s-maxage=0

    过期:0

    编译指示:无缓存

    变化:*



    失败:Chrome 28、FireFox 23、Safari 5.1.7、Opera 12.15

    成功:IE8

  16. 缓存控制:必须重新验证,max-age=0

    失败:Chrome 28、FireFox 23、Safari 5.1.7、Opera 12.15

    成功:IE8

  17. 缓存控制:必须重新验证

    过期:0

    失败:Chrome 28、FireFox 23、Safari 5.1.7、Opera 12.15

    成功:IE8

  18. 缓存控制:必须重新验证

    到期时间:1991 年 10 月 12 日星期六 05:00:00 GMT

    失败:Chrome 28、FireFox 23、Safari 5.1.7、Opera 12.15

    成功:IE8

  19. 缓存控制:私有、必须重新验证、代理重新验证、s-maxage=0

    编译指示:无缓存

    变化:*



    失败:Chrome 28、FireFox 23、IE8、Safari 5.1.7、Opera 12.15

    成功:无

HTTPS:

  1. 缓存控制:私有、max-age=0、proxy-revalidate、s-maxage=0

    过期:0



    失败:Chrome 28、FireFox 23、IE8、Safari 5.1.7、Opera 12.15

    成功:无

  2. 缓存控制:私有,max-age=0,代理重新验证,s-maxage=0

    到期时间:1991 年 10 月 12 日星期六 05:00:00 GMT



    失败:Chrome 28、FireFox 23、IE8、Safari 5.1.7、Opera 12.15

    成功:无

  3. 变化:*

    失败:Chrome 28、Safari 5.1.7、Opera 12.15

    成功:FireFox 23、IE8

  4. Pragma:无缓存

    失败:Chrome 28、Safari 5.1.7、Opera 12.15

    成功:FireFox 23、IE8

  5. 缓存控制:无缓存

    失败:Chrome 28、Safari 5.1.7、Opera 12.15

    成功:FireFox 23、IE8

  6. 缓存控制:私有、无缓存、max-age=0、代理重新验证、s-maxage=0

    失败:Chrome 28、Safari 5.1.7、Opera 12.15

    成功:FireFox 23、IE8

  7. 缓存控制:私有、无缓存、max-age=0、代理重新验证、s-maxage=0

    过期:0

    编译指示:无缓存

    变化:*

    失败:Chrome 28、Safari 5.1.7、Opera 12.15

    成功:FireFox 23、IE8

  8. 缓存控制:私有、无缓存、max-age=0、代理重新验证、s-maxage=0

    过期时间:1991 年 10 月 12 日星期六 05:00:00 GMT

    编译指示:无缓存

    变化:*

    失败:Chrome 28、Safari 5.1.7、Opera 12.15

    成功:FireFox 23、IE8

  9. 缓存控制:必须重新验证

    失败:Chrome 28、FireFox 23、IE8、Safari 5.1.7

    成功:Opera 12.15

  10. 缓存控制:私有、必须重新验证、代理重新验证、s-maxage=0



    失败:Chrome 28、FireFox 23、IE8、Safari 5.1.7

    成功:Opera 12.15

  11. 缓存控制:必须重新验证,max-age=0

    失败:Chrome 28、FireFox 23、Safari 5.1.7

    成功:IE8、Opera 12.15

  12. 缓存控制:私有、无缓存、必须重新验证、max-age=0、代理重新验证、s-maxage=0

    到期时间:1991 年 10 月 12 日星期六 05:00:00 GMT

    编译指示:无缓存

    变化:*



    失败:Chrome 28、Safari 5.1.7

    成功:FireFox 23、IE8、Opera 12.15

  13. 缓存控制:私有、无缓存、必须重新验证、max-age=0、代理重新验证、s-maxage=0

    过期:0

    编译指示:无缓存

    变化:*



    失败:Chrome 28、Safari 5.1.7

    成功:FireFox 23、IE8、Opera 12.15

  14. 缓存控制:无存储

    失败:Opera 12.15

    成功:Chrome 28、FireFox 23、IE8、Safari 5.1.7

  15. 缓存控制:私有、无缓存、无存储、max-age=0、代理重新验证、s-maxage =0

    过期:0

    编译指示:无缓存

    变化:*



    失败:Opera 12.15

    成功:Chrome 28、FireFox 23、IE8、Safari 5.1.7

  16. 缓存控制:私有、无缓存、无存储、max-age=0、代理重新验证、s-maxage =0

    到期时间:1991 年 10 月 12 日星期六 05:00:00 GMT

    编译指示:无缓存

    变化:*



    失败:Opera 12.15

    成功:Chrome 28、FireFox 23、IE8、Safari 5.1.7

  17. 缓存控制:私有、无缓存

    过期时间:1991 年 10 月 12 日星期六 05:00:00 GMT

    编译指示:无缓存

    变化:*

    失败:Chrome 28、Safari 5.1.7、Opera 12.15

    成功:FireFox 23、IE8

  18. 缓存控制:必须重新验证

    过期:0

    失败:Chrome 28、FireFox 23、Safari 5.1.7、

    成功:IE8、Opera 12.15

  19. 缓存控制:必须重新验证

    到期时间:1991 年 10 月 12 日星期六 05:00:00 GMT

    失败:Chrome 28、FireFox 23、Safari 5.1.7、

    成功:IE8、Opera 12.15

  20. 缓存控制:私有、必须重新验证、max-age=0、代理重新验证、s-maxage=0

    过期:0



    失败:Chrome 28、FireFox 23、Safari 5.1.7、

    成功:IE8、Opera 12.15

  21. 缓存控制:私有、必须重新验证、max-age=0、代理重新验证、s-maxage=0

    过期时间:1991 年 10 月 12 日星期六 05:00:00 GMT



    失败:Chrome 28、FireFox 23、Safari 5.1.7、

    成功:IE8、Opera 12.15

  22. 缓存控制:私有,必须重新验证

    到期时间:1991 年 10 月 12 日星期六 05:00:00 GMT

    编译指示:无缓存

    变化:*

    失败:Chrome 28、Safari 5.1.7

    成功:FireFox 23、IE8、Opera 12.15

  23. 缓存控制:无存储,必须重新验证

    失败:无

    成功:Chrome 28、FireFox 23、IE8、Safari 5.1.7、Opera 12.15

As @Kornel stated, what you want is not to deactivate the cache, but to deactivate the history buffer. Different browsers have their own subtle ways to disable the history buffer.

In Chrome (v28.0.1500.95 m) we can do this only by Cache-Control: no-store.

In FireFox (v23.0.1) any one of these will work:

  1. Cache-Control: no-store

  2. Cache-Control: no-cache (https only)

  3. Pragma: no-cache (https only)

  4. Vary: * (https only)

In Opera (v12.15) we only can do this by Cache-Control: must-revalidate (https only).

In Safari (v5.1.7, 7534.57.2) any one of these will work:

  1. Cache-Control: no-store

    <body onunload=""> in html

  2. Cache-Control: no-store (https only)

In IE8 (v8.0.6001.18702IC) any one of these will work:

  1. Cache-Control: must-revalidate, max-age=0

  2. Cache-Control: no-cache

  3. Cache-Control: no-store

  4. Cache-Control: must-revalidate

    Expires: 0

  5. Cache-Control: must-revalidate

    Expires: Sat, 12 Oct 1991 05:00:00 GMT

  6. Pragma: no-cache (https only)

  7. Vary: * (https only)

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 only)

Note that https is needed because Opera wouldn't deactivate history buffer for plain http pages. If you really can't get https and you are prepared to ignore Opera, the best you can do is this:

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

Below shows the raw logs of my tests:

HTTP:

  1. 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="">

    Fail: Opera 12.15

    Success: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  2. 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="">

    Fail: Opera 12.15

    Success: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  3. Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0

    Expires: 0

    Pragma: no-cache

    Vary: *

    Fail: Safari 5.1.7, Opera 12.15

    Success: Chrome 28, FireFox 23, IE8

  4. 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: *

    Fail: Safari 5.1.7, Opera 12.15

    Success: Chrome 28, FireFox 23, IE8

  5. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0

    Expires: 0

    Pragma: no-cache

    Vary: *

    <body onunload="">

    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15

    Success: IE8

  6. 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="">

    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15

    Success: IE8

  7. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0

    Expires: 0

    Pragma: no-cache

    Vary: *

    <body onunload="">

    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15

    Success: IE8

  8. 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="">

    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15

    Success: IE8

  9. Cache-Control: no-store

    Fail: Safari 5.1.7, Opera 12.15

    Success: Chrome 28, FireFox 23, IE8

  10. Cache-Control: no-store

    <body onunload="">

    Fail: Opera 12.15

    Success: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  11. Cache-Control: no-cache

    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15

    Success: IE8

  12. Vary: *

    Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15

    Success: none

  13. Pragma: no-cache

    Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15

    Success: none

  14. 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="">

    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15

    Success: IE8

  15. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0

    Expires: 0

    Pragma: no-cache

    Vary: *

    <body onunload="">

    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15

    Success: IE8

  16. Cache-Control: must-revalidate, max-age=0

    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15

    Success: IE8

  17. Cache-Control: must-revalidate

    Expires: 0

    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15

    Success: IE8

  18. Cache-Control: must-revalidate

    Expires: Sat, 12 Oct 1991 05:00:00 GMT

    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15

    Success: IE8

  19. Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0

    Pragma: no-cache

    Vary: *

    <body onunload="">

    Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15

    Success: none

HTTPS:

  1. Cache-Control: private, max-age=0, proxy-revalidate, s-maxage=0

    Expires: 0

    <body onunload="">

    Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15

    Success: none

  2. Cache-Control: private, max-age=0, proxy-revalidate, s-maxage=0

    Expires: Sat, 12 Oct 1991 05:00:00 GMT

    <body onunload="">

    Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15

    Success: none

  3. Vary: *

    Fail: Chrome 28, Safari 5.1.7, Opera 12.15

    Success: FireFox 23, IE8

  4. Pragma: no-cache

    Fail: Chrome 28, Safari 5.1.7, Opera 12.15

    Success: FireFox 23, IE8

  5. Cache-Control: no-cache

    Fail: Chrome 28, Safari 5.1.7, Opera 12.15

    Success: FireFox 23, IE8

  6. Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0

    Fail: Chrome 28, Safari 5.1.7, Opera 12.15

    Success: FireFox 23, IE8

  7. Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0

    Expires: 0

    Pragma: no-cache

    Vary: *

    Fail: Chrome 28, Safari 5.1.7, Opera 12.15

    Success: FireFox 23, IE8

  8. 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: *

    Fail: Chrome 28, Safari 5.1.7, Opera 12.15

    Success: FireFox 23, IE8

  9. Cache-Control: must-revalidate

    Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7

    Success: Opera 12.15

  10. Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0

    <body onunload="">

    Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7

    Success: Opera 12.15

  11. Cache-Control: must-revalidate, max-age=0

    Fail: Chrome 28, FireFox 23, Safari 5.1.7

    Success: IE8, Opera 12.15

  12. 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="">

    Fail: Chrome 28, Safari 5.1.7

    Success: FireFox 23, IE8, Opera 12.15

  13. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0

    Expires: 0

    Pragma: no-cache

    Vary: *

    <body onunload="">

    Fail: Chrome 28, Safari 5.1.7

    Success: FireFox 23, IE8, Opera 12.15

  14. Cache-Control: no-store

    Fail: Opera 12.15

    Success: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  15. Cache-Control: private, no-cache, no-store, max-age=0, proxy-revalidate, s-maxage=0

    Expires: 0

    Pragma: no-cache

    Vary: *

    <body onunload="">

    Fail: Opera 12.15

    Success: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  16. 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="">

    Fail: Opera 12.15

    Success: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  17. Cache-Control: private, no-cache

    Expires: Sat, 12 Oct 1991 05:00:00 GMT

    Pragma: no-cache

    Vary: *

    Fail: Chrome 28, Safari 5.1.7, Opera 12.15

    Success: FireFox 23, IE8

  18. Cache-Control: must-revalidate

    Expires: 0

    Fail: Chrome 28, FireFox 23, Safari 5.1.7,

    Success: IE8, Opera 12.15

  19. Cache-Control: must-revalidate

    Expires: Sat, 12 Oct 1991 05:00:00 GMT

    Fail: Chrome 28, FireFox 23, Safari 5.1.7,

    Success: IE8, Opera 12.15

  20. Cache-Control: private, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0

    Expires: 0

    <body onunload="">

    Fail: Chrome 28, FireFox 23, Safari 5.1.7,

    Success: IE8, Opera 12.15

  21. Cache-Control: private, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0

    Expires: Sat, 12 Oct 1991 05:00:00 GMT

    <body onunload="">

    Fail: Chrome 28, FireFox 23, Safari 5.1.7,

    Success: IE8, Opera 12.15

  22. Cache-Control: private, must-revalidate

    Expires: Sat, 12 Oct 1991 05:00:00 GMT

    Pragma: no-cache

    Vary: *

    Fail: Chrome 28, Safari 5.1.7

    Success: FireFox 23, IE8, Opera 12.15

  23. Cache-Control: no-store, must-revalidate

    Fail: none

    Success: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15

甜柠檬 2024-07-11 12:17:38

简介

适用于所有提到的客户端(和代理)的正确的最小标头集:

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

Cache-Control 符合客户端和代理的 HTTP 1.1 规范(并且某些客户端在 Expires 旁边隐式需要)。 Pragma 是史前客户端的 HTTP 1.0 规范。 过期是客户端和代理的 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)无关紧要。 最后修改时间大多数其他答案中包含的 header 在您实际上想要缓存请求时才有意义,因此您根本不需要指定它。

怎么设置呢?

使用 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 Web API:

// `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()); 

使用 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.NET Core v3

// using Microsoft.Net.Http.Headers
Response.Headers[HeaderNames.CacheControl] = "no-cache, no-store, must-revalidate";
Response.Headers[HeaderNames.Expires] = "0";
Response.Headers[HeaderNames.Pragma] = "no-cache";

使用 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:

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

使用 Python/Flask:

response = make_response(render_template(...))
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/Pyramid:

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

使用 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.

使用 Clojure(需要 Ring utils):

(require '[ring.util.response :as r])
(-> response
  (r/header "Cache-Control" "no-cache, no-store, must-revalidate")
  (r/header "Pragma" "no-cache")
  (r/header "Expires" 0))

使用 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>

使用 Firebase 托管 firebase.json

"headers": [
    { "key": "Cache-Control", "value": "no-cache, no-store, must-revalidate" },
    { "key": "Pragma", "value": "no-cache" },
    { "key": "Expires", "value": "0" }
]

使用 HTML:

<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 标记,则 HTTP 响应标头中指定的标记将优先于 HTML 元标记。 仅当通过 file:// URL 从本地磁盘文件系统查看页面时,才会使用 HTML 元标记。 另请参阅 W3 HTML 规范第 5.2.2 章。 当您不以编程方式指定它们时请注意这一点,因为网络服务器可以包含一些默认值。

一般来说,您最好指定 HTML 元标记,以避免初学者混淆并依赖硬 HTTP 响应标头。 此外,特别是那些 标签是无效< /a> 在 HTML5 中。 仅 HTML5 规范中列出的 http-equiv 是允许的。

验证实际的 HTTP 响应标头

要验证其中之一,您可以在 Web 浏览器的开发人员工具集的 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 无法打开该网站。 请求的站点不可用或找不到

Introduction

The correct minimum set of headers that works across all mentioned clients (and proxies):

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

The Cache-Control is per the HTTP 1.1 spec for clients and proxies (and implicitly required by some clients next to Expires). The Pragma is per the HTTP 1.0 spec for prehistoric clients. The Expires is per the HTTP 1.0 and 1.1 specs for clients and proxies. In HTTP 1.1, the Cache-Control takes precedence over Expires, so it's after all for HTTP 1.0 proxies only.

If you don't care about IE6 and its broken caching when serving pages over HTTPS with only no-store, then you could omit Cache-Control: no-cache.

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

If you don't care about IE6 nor HTTP 1.0 clients (HTTP 1.1 was introduced in 1997), then you could omit Pragma.

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

If you don't care about HTTP 1.0 proxies either, then you could omit Expires.

Cache-Control: no-store, must-revalidate

On the other hand, if the server auto-includes a valid Date header, then you could theoretically omit Cache-Control too and rely on Expires only.

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

But that may fail if e.g. the end-user manipulates the operating system date and the client software is relying on it.

Other Cache-Control parameters such as max-age are irrelevant if the abovementioned Cache-Control parameters are specified. The Last-Modified header as included in most other answers here is only interesting if you actually want to cache the request, so you don't need to specify it at all.

How to set it?

Using PHP:

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

Using Java Servlet, or 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.

Using 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.

Using ASP.NET Web API:

// `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()); 

Using 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.

Using ASP.NET Core v3

// using Microsoft.Net.Http.Headers
Response.Headers[HeaderNames.CacheControl] = "no-cache, no-store, must-revalidate";
Response.Headers[HeaderNames.Expires] = "0";
Response.Headers[HeaderNames.Pragma] = "no-cache";

Using 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.

Using Ruby on Rails:

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

Using Python/Flask:

response = make_response(render_template(...))
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.

Using 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.

Using Python/Pyramid:

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

Using 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.

Using Clojure (require Ring utils):

(require '[ring.util.response :as r])
(-> response
  (r/header "Cache-Control" "no-cache, no-store, must-revalidate")
  (r/header "Pragma" "no-cache")
  (r/header "Expires" 0))

Using Apache .htaccess file:

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

Using Firebase Hosting firebase.json:

"headers": [
    { "key": "Cache-Control", "value": "no-cache, no-store, must-revalidate" },
    { "key": "Pragma", "value": "no-cache" },
    { "key": "Expires", "value": "0" }
]

Using HTML:

<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 meta tags vs HTTP response headers

Important to know is that when an HTML page is served over an HTTP connection, and a header is present in both the HTTP response headers and the HTML <meta http-equiv> tags, then the one specified in the HTTP response header will get precedence over the HTML meta tag. The HTML meta tag will only be used when the page is viewed from a local disk file system via a file:// URL. See also W3 HTML spec chapter 5.2.2. Take care with this when you don't specify them programmatically because the webserver can namely include some default values.

Generally, you'd better just not specify the HTML meta tags to avoid confusion by starters and rely on hard HTTP response headers. Moreover, specifically those <meta http-equiv> tags are invalid in HTML5. Only the http-equiv values listed in HTML5 specification are allowed.

Verifying the actual HTTP response headers

To verify the one and the other, you can see/debug them in the HTTP traffic monitor of the web browser's developer toolset. You can get there by pressing F12 in Chrome/Firefox23+/IE9+, and then opening the "Network" or "Net" tab panel, and then clicking the HTTP request of interest to uncover all detail about the HTTP request and response. The below screenshot is from Chrome:

Chrome developer toolset HTTP traffic monitor showing HTTP response headers on stackoverflow.com

I want to set those headers on file downloads too

First of all, this question and answer are targeted on "web pages" (HTML pages), not "file downloads" (PDF, zip, Excel, etc). You'd better have them cached and make use of some file version identifier somewhere in the URI path or query string to force a redownload on a changed file. When applying those no-cache headers on file downloads anyway, then beware of the IE7/8 bug when serving a file download over HTTPS instead of HTTP. For detail, see IE cannot download foo.jsf. IE was not able to open this internet site. The requested site is either unavailable or cannot be found.

三人与歌 2024-07-11 12:17:38

这些指令不会减轻任何安全风险。 它们的真正目的是迫使用户刷新不稳定的信息,而不是阻止用户保留信息。 请参阅这个类似的问题。 至少,不能保证任何路由器、代理等也不会忽略缓存指令。

从更积极的角度来看,有关计算机物理访问、软件安装等的策略将使您在安全性方面领先于大多数公司。 如果这些信息的消费者是公众,那么您真正能做的唯一一件事就是帮助他们了解,一旦信息到达他们的机器,该机器就是他们的责任,而不是你的。

These directives does not mitigate any security risk. They are really intended to force UA's to refresh volatile information, not keep UA's from being retaining information. See this similar question. At the very least, there is no guarantee that any routers, proxies, etc. will not ignore the caching directives as well.

On a more positive note, policies regarding physical access to computers, software installation, and the like will put you miles ahead of most firms in terms of security. If the consumers of this information are members of the public, the only thing you can really do is help them understand that once the information hits their machine, that machine is their responsibility, not yours.

萌逼全场 2024-07-11 12:17:38

对于 ASP.NET Core,创建一个简单的中间件类:

public class NoCacheMiddleware
{
    private readonly RequestDelegate m_next;

    public NoCacheMiddleware( RequestDelegate next )
    {
        m_next = next;
    }

    public async Task Invoke( HttpContext httpContext )
    {
        httpContext.Response.OnStarting( ( state ) =>
        {
            // ref: http://stackoverflow.com/questions/49547/making-sure-a-web-page-is-not-cached-across-all-browsers
            httpContext.Response.Headers.Append( "Cache-Control", "no-cache, no-store, must-revalidate" );
            httpContext.Response.Headers.Append( "Pragma", "no-cache" );
            httpContext.Response.Headers.Append( "Expires", "0" );
            return Task.FromResult( 0 );
        }, null );

        await m_next.Invoke( httpContext );
    }
}

然后使用 Startup.cs 注册它

app.UseMiddleware<NoCacheMiddleware>();

,确保将其添加到之后的某个位置

app.UseStaticFiles();

For ASP.NET Core, create a simple middleware class:

public class NoCacheMiddleware
{
    private readonly RequestDelegate m_next;

    public NoCacheMiddleware( RequestDelegate next )
    {
        m_next = next;
    }

    public async Task Invoke( HttpContext httpContext )
    {
        httpContext.Response.OnStarting( ( state ) =>
        {
            // ref: http://stackoverflow.com/questions/49547/making-sure-a-web-page-is-not-cached-across-all-browsers
            httpContext.Response.Headers.Append( "Cache-Control", "no-cache, no-store, must-revalidate" );
            httpContext.Response.Headers.Append( "Pragma", "no-cache" );
            httpContext.Response.Headers.Append( "Expires", "0" );
            return Task.FromResult( 0 );
        }, null );

        await m_next.Invoke( httpContext );
    }
}

then register it with Startup.cs

app.UseMiddleware<NoCacheMiddleware>();

Make sure you add this somewhere after

app.UseStaticFiles();
完美的未来在梦里 2024-07-11 12:17:38

IE6 内容中存在一个错误,

即使您使用“Cache-Control:no-cache”,“Content-Encoding:gzip”也始终会被缓存。

http://support.microsoft.com/kb/321722

您可以为 IE6 用户禁用 gzip 压缩(检查用户代理中的“MSIE 6”)

There's a bug in IE6

Content with "Content-Encoding: gzip" is always cached even if you use "Cache-Control: no-cache".

http://support.microsoft.com/kb/321722

You can disable gzip compression for IE6 users (check the user agent for "MSIE 6")

吃不饱 2024-07-11 12:17:38

在响应中使用 pragma header 是一个妻子的故事。 RFC2616仅将其定义为请求标头

http://www.mnot.net/cache_docs/#PRAGMA

The use of the pragma header in the response is a wives tale. RFC2616 only defines it as a request header

http://www.mnot.net/cache_docs/#PRAGMA

忆梦 2024-07-11 12:17:38

经过一番研究,我们得出了以下似乎涵盖大多数浏览器的标头列表:

在 ASP.NET 中,我们使用以下代码片段添加了这些内容:

Response.ClearHeaders(); 
Response.AppendHeader("Cache-Control", "no-cache"); //HTTP 1.1
Response.AppendHeader("Cache-Control", "private"); // HTTP 1.1
Response.AppendHeader("Cache-Control", "no-store"); // HTTP 1.1
Response.AppendHeader("Cache-Control", "must-revalidate"); // HTTP 1.1
Response.AppendHeader("Cache-Control", "max-stale=0"); // HTTP 1.1 
Response.AppendHeader("Cache-Control", "post-check=0"); // HTTP 1.1 
Response.AppendHeader("Cache-Control", "pre-check=0"); // HTTP 1.1 
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0 
Response.AppendHeader("Expires", "Sat, 26 Jul 1997 05:00:00 GMT"); // HTTP 1.0 

发现自:http://forums.asp.net/t/1013531.aspx

After a bit of research we came up with the following list of headers that seemed to cover most browsers:

In ASP.NET we added these using the following snippet:

Response.ClearHeaders(); 
Response.AppendHeader("Cache-Control", "no-cache"); //HTTP 1.1
Response.AppendHeader("Cache-Control", "private"); // HTTP 1.1
Response.AppendHeader("Cache-Control", "no-store"); // HTTP 1.1
Response.AppendHeader("Cache-Control", "must-revalidate"); // HTTP 1.1
Response.AppendHeader("Cache-Control", "max-stale=0"); // HTTP 1.1 
Response.AppendHeader("Cache-Control", "post-check=0"); // HTTP 1.1 
Response.AppendHeader("Cache-Control", "pre-check=0"); // HTTP 1.1 
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0 
Response.AppendHeader("Expires", "Sat, 26 Jul 1997 05:00:00 GMT"); // HTTP 1.0 

Found from: http://forums.asp.net/t/1013531.aspx

梅倚清风 2024-07-11 12:17:38

不确定我的答案听起来是否简单而愚蠢,也许您很久以前就已经知道了,但由于阻止某人使用浏览器后退按钮查看您的历史页面是您的目标之一,您可以使用:

window.location.replace("https://www.example.com/page-not-to-be-viewed-in-browser-history-back-button.html");< /code>

当然,这可能无法在整个站点上实现,但至少对于某些关键页面,您可以这样做。 希望这可以帮助。

Not sure if my answer sounds simple and stupid, and perhaps it has already been known to you since long time ago, but since preventing someone from using browser back button to view your historical pages is one of your goals, you can use:

window.location.replace("https://www.example.com/page-not-to-be-viewed-in-browser-history-back-button.html");

Of course, this may not be possible to be implemented across the entire site, but at least for some critical pages, you can do that. Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文