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

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

<ul>
<li>Internet Explorer 6+</li>
<li>Firefox 1.5+</li>
<li>Safari 3+</li>
<li>Opera 9+</li>
<li>Chrome</li>
</ul>

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

[{'answer_id': 49548, 'author': 'Anders Sandvig', 'author_id': 1709, 'author_profile': 'https://Stackoverflow.com/users/1709', 'pm_score': 3, 'selected': False, 'text': "<p>Setting the modified http header to some date in 1995 usually does the trick.</p>\n\n<p>Here's an example:</p>\n\n<pre>\nExpires: Wed, 15 Nov 1995 04:58:08 GMT\nLast-Modified: Wed, 15 Nov 1995 04:58:08 GMT\nCache-Control: no-cache, must-revalidate\n</pre>\n"}, {'answer_id': 49549, 'author': 'Edward Wilde', 'author_id': 5182, 'author_profile': 'https://Stackoverflow.com/users/5182', 'pm_score': 5, 'selected': False, 'text': '<p>After a bit of research we came up with the following list of headers that seemed to cover most browsers:</p>\n<ul>\n<li><a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21" rel="noreferrer">Expires</a>: Sat, 26 Jul 1997 05:00:00 GMT</li>\n<li><a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9" rel="noreferrer">Cache-Control</a>: <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1" rel="noreferrer">no-cache</a>, private, <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4" rel="noreferrer">must-revalidate</a>, max-stale=0, post-check=0, pre-check=0 no-store</li>\n<li><a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.32" rel="noreferrer">Pragma</a>: no-cache</li>\n</ul>\n<p>In ASP.NET we added these using the following snippet:</p>\n<pre><code>Response.ClearHeaders(); \nResponse.AppendHeader(&quot;Cache-Control&quot;, &quot;no-cache&quot;); //HTTP 1.1\nResponse.AppendHeader(&quot;Cache-Control&quot;, &quot;private&quot;); // HTTP 1.1\nResponse.AppendHeader(&quot;Cache-Control&quot;, &quot;no-store&quot;); // HTTP 1.1\nResponse.AppendHeader(&quot;Cache-Control&quot;, &quot;must-revalidate&quot;); // HTTP 1.1\nResponse.AppendHeader(&quot;Cache-Control&quot;, &quot;max-stale=0&quot;); // HTTP 1.1 \nResponse.AppendHeader(&quot;Cache-Control&quot;, &quot;post-check=0&quot;); // HTTP 1.1 \nResponse.AppendHeader(&quot;Cache-Control&quot;, &quot;pre-check=0&quot;); // HTTP 1.1 \nResponse.AppendHeader(&quot;Pragma&quot;, &quot;no-cache&quot;); // HTTP 1.0 \nResponse.AppendHeader(&quot;Expires&quot;, &quot;Sat, 26 Jul 1997 05:00:00 GMT&quot;); // HTTP 1.0 \n</code></pre>\n<p>Found from: <a href="http://forums.asp.net/t/1013531.aspx" rel="noreferrer">http://forums.asp.net/t/1013531.aspx</a></p>\n'}, {'answer_id': 49550, 'author': 'Chris Dail', 'author_id': 5077, 'author_profile': 'https://Stackoverflow.com/users/5077', 'pm_score': 3, 'selected': False, 'text': '<p>The RFC for <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html" rel="noreferrer">HTTP 1.1</a> says the proper method is to add an HTTP Header for:</p>\n\n<p>Cache-Control: no-cache</p>\n\n<p>Older browsers may ignore this if they are not properly compliant to HTTP 1.1. For those you can try the header:</p>\n\n<p>Pragma: no-cache</p>\n\n<p>This is also supposed to work for HTTP 1.1 browsers.</p>\n'}, {'answer_id': 49557, 'author': 'Grey Panther', 'author_id': 1265, 'author_profile': 'https://Stackoverflow.com/users/1265', 'pm_score': 3, 'selected': False, 'text': '<p>The <a href="http://php.net/header" rel="nofollow noreferrer">PHP documentation for the header function</a> has a rather complete example (contributed by a third party):</p>\n\n<pre><code>    header(\'Pragma: public\');\n    header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");                  // Date in the past   \n    header(\'Last-Modified: \'.gmdate(\'D, d M Y H:i:s\') . \' GMT\');\n    header(\'Cache-Control: no-store, no-cache, must-revalidate\');     // HTTP/1.1\n    header(\'Cache-Control: pre-check=0, post-check=0, max-age=0\', false);    // HTTP/1.1\n    header ("Pragma: no-cache");\n    header("Expires: 0", false);\n</code></pre>\n'}, {'answer_id': 82613, 'author': 'petr k.', 'author_id': 15497, 'author_profile': 'https://Stackoverflow.com/users/15497', 'pm_score': 2, 'selected': False, 'text': "<p>I've had best and most consistent results across all browsers by setting \n    Pragma: no-cache</p>\n"}, {'answer_id': 83717, 'author': 'Dave Cheney', 'author_id': 6449, 'author_profile': 'https://Stackoverflow.com/users/6449', 'pm_score': 4, 'selected': False, 'text': '<p>The use of the pragma header in the response is a wives tale. RFC2616 only defines it as a request header</p>\n\n<p><a href="http://www.mnot.net/cache_docs/#PRAGMA" rel="noreferrer">http://www.mnot.net/cache_docs/#PRAGMA</a></p>\n'}, {'answer_id': 91512, 'author': 'Steven Oxley', 'author_id': 3831, 'author_profile': 'https://Stackoverflow.com/users/3831', 'pm_score': 3, 'selected': False, 'text': '<p>DISCLAIMER:  I strongly suggest reading @BalusC\'s answer.  After reading the following caching tutorial: <a href="http://www.mnot.net/cache_docs/" rel="nofollow noreferrer">http://www.mnot.net/cache_docs/</a> (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:</p>\n\n<hr />\n\n<p>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:</p>\n\n<pre><code>header(\'Cache-Control: no-store, private, no-cache, must-revalidate\');     // HTTP/1.1\nheader(\'Cache-Control: pre-check=0, post-check=0, max-age=0, max-stale = 0\', false);  // HTTP/1.1\nheader(\'Pragma: public\');\nheader(\'Expires: Sat, 26 Jul 1997 05:00:00 GMT\');                  // Date in the past  \nheader(\'Expires: 0\', false); \nheader(\'Last-Modified: \'.gmdate(\'D, d M Y H:i:s\') . \' GMT\');\nheader (\'Pragma: no-cache\');\n</code></pre>\n\n<p>That should work.  The problem was that when setting the same part of the header twice, if the <code>false</code> is not sent as the second argument to the header function, header function will simply overwrite the previous <code>header()</code> call.  So, when setting the <code>Cache-Control</code>, for example if one does not want to put all the arguments in one <code>header()</code> function call, he must do something like this:</p>\n\n<pre><code>header(\'Cache-Control: this\');\nheader(\'Cache-Control: and, this\', false);\n</code></pre>\n\n<p>See more complete documentation <a href="http://in.php.net/header" rel="nofollow noreferrer">here</a>.</p>\n'}, {'answer_id': 99183, 'author': 'Dustman', 'author_id': 16398, 'author_profile': 'https://Stackoverflow.com/users/16398', 'pm_score': 3, 'selected': False, 'text': '<p>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 <a href="https://stackoverflow.com/questions/64059/is-there-a-way-to-keep-a-page-from-rendering-once-a-person-has-logged-out-but-h">this similar question</a>. At the very least, there is no guarantee that any routers, proxies, etc. will not ignore the caching directives as well.</p>\n\n<p>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 <strong>their</strong> responsibility, not yours.</p>\n'}, {'answer_id': 301311, 'author': 'Harry', 'author_id': 4704, 'author_profile': 'https://Stackoverflow.com/users/4704', 'pm_score': 2, 'selected': False, 'text': '<p>In addition to the headers consider serving your page via <strong>https</strong>.  Many browsers will not cache https by default.</p>\n'}, {'answer_id': 2068353, 'author': 'Chris Vasselli', 'author_id': 251038, 'author_profile': 'https://Stackoverflow.com/users/251038', 'pm_score': 5, 'selected': False, 'text': '<p>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.</p>\n\n<p>After much research and testing, I found that the only two headers I really needed were:</p>\n\n<blockquote>\n  <p>Cache-Control: no-store<br>\n  Vary: *</p>\n</blockquote>\n\n<p>For an explanation of the Vary header, check out <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6" rel="noreferrer">http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6</a></p>\n\n<p>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 <a href="http://marketshare.hitslink.com/browser-market-share.aspx?qprid=2" rel="noreferrer">99%</a> of all browsers in use as of Jan \'10.</p>\n\n<p>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.</p>\n\n<p><strong>Update:</strong>  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 <a href="https://stackoverflow.com/questions/49547/making-sure-a-web-page-is-not-cached-across-all-browsers/2068407#2068407">answer</a>.  </p>\n'}, {'answer_id': 2068407, 'author': 'BalusC', 'author_id': 157882, 'author_profile': 'https://Stackoverflow.com/users/157882', 'pm_score': 13, 'selected': True, 'text': '<h1>Introduction</h1>\n<p>The correct minimum set of headers that works across all mentioned clients (and proxies):</p>\n<pre><code>Cache-Control: no-cache, no-store, must-revalidate\nPragma: no-cache\nExpires: 0\n</code></pre>\n<p>The <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9" rel="noreferrer"><code>Cache-Control</code></a> is per the HTTP 1.1 spec for clients and proxies (and implicitly required by some clients next to <code>Expires</code>). The <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.32" rel="noreferrer"><code>Pragma</code></a> is per the HTTP 1.0 spec for prehistoric clients. The <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21" rel="noreferrer"><code>Expires</code></a> is per the HTTP 1.0 and 1.1 specs for clients and proxies. In HTTP 1.1, the <code>Cache-Control</code> takes precedence over <code>Expires</code>, so it\'s after all for HTTP 1.0 proxies only.</p>\n<p>If you don\'t care about IE6 and its broken caching when serving pages over HTTPS with only <code>no-store</code>, then you could omit <code>Cache-Control: no-cache</code>.</p>\n<pre><code>Cache-Control: no-store, must-revalidate\nPragma: no-cache\nExpires: 0\n</code></pre>\n<p>If you don\'t care about IE6 nor HTTP 1.0 clients (HTTP 1.1 was introduced in 1997), then you could omit <code>Pragma</code>.</p>\n<pre><code>Cache-Control: no-store, must-revalidate\nExpires: 0\n</code></pre>\n<p>If you don\'t care about HTTP 1.0 proxies either, then you could omit <code>Expires</code>.</p>\n<pre><code>Cache-Control: no-store, must-revalidate\n</code></pre>\n<p>On the other hand, if the server auto-includes a valid <code>Date</code> header, then you could theoretically omit <code>Cache-Control</code> too and rely on <code>Expires</code> only.</p>\n<pre><code>Date: Wed, 24 Aug 2016 18:32:02 GMT\nExpires: 0\n</code></pre>\n<p>But that may fail if e.g. the end-user manipulates the operating system date and the client software is relying on it.</p>\n<p>Other <code>Cache-Control</code> parameters such as <code>max-age</code> are irrelevant if the abovementioned <code>Cache-Control</code> parameters are specified. The <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.29" rel="noreferrer"><code>Last-Modified</code></a> header as included in most other answers here is <em>only</em> interesting if you <strong>actually want</strong> to cache the request, so you don\'t need to specify it at all.</p>\n<h1>How to set it?</h1>\n<p>Using PHP:</p>\n<pre class="lang-php prettyprint-override"><code>header(&quot;Cache-Control: no-cache, no-store, must-revalidate&quot;); // HTTP 1.1.\nheader(&quot;Pragma: no-cache&quot;); // HTTP 1.0.\nheader(&quot;Expires: 0&quot;); // Proxies.\n</code></pre>\n<p>Using Java Servlet, or Node.js:</p>\n<pre class="lang-java prettyprint-override"><code>response.setHeader(&quot;Cache-Control&quot;, &quot;no-cache, no-store, must-revalidate&quot;); // HTTP 1.1.\nresponse.setHeader(&quot;Pragma&quot;, &quot;no-cache&quot;); // HTTP 1.0.\nresponse.setHeader(&quot;Expires&quot;, &quot;0&quot;); // Proxies.\n</code></pre>\n<p>Using ASP.NET-MVC</p>\n<pre class="lang-cs prettyprint-override"><code>Response.Cache.SetCacheability(HttpCacheability.NoCache);  // HTTP 1.1.\nResponse.Cache.AppendCacheExtension(&quot;no-store, must-revalidate&quot;);\nResponse.AppendHeader(&quot;Pragma&quot;, &quot;no-cache&quot;); // HTTP 1.0.\nResponse.AppendHeader(&quot;Expires&quot;, &quot;0&quot;); // Proxies.\n</code></pre>\n<p>Using ASP.NET Web API:</p>\n<pre class="lang-cs prettyprint-override"><code>// `response` is an instance of System.Net.Http.HttpResponseMessage\nresponse.Headers.CacheControl = new CacheControlHeaderValue\n{\n    NoCache = true,\n    NoStore = true,\n    MustRevalidate = true\n};\nresponse.Headers.Pragma.ParseAdd(&quot;no-cache&quot;);\n// We can\'t use `response.Content.Headers.Expires` directly\n// since it allows only `DateTimeOffset?` values.\nresponse.Content?.Headers.TryAddWithoutValidation(&quot;Expires&quot;, 0.ToString()); \n</code></pre>\n<p>Using ASP.NET:</p>\n<pre class="lang-cs prettyprint-override"><code>Response.AppendHeader(&quot;Cache-Control&quot;, &quot;no-cache, no-store, must-revalidate&quot;); // HTTP 1.1.\nResponse.AppendHeader(&quot;Pragma&quot;, &quot;no-cache&quot;); // HTTP 1.0.\nResponse.AppendHeader(&quot;Expires&quot;, &quot;0&quot;); // Proxies.\n</code></pre>\n<p>Using ASP.NET Core v3</p>\n<pre class="lang-c# prettyprint-override"><code>// using Microsoft.Net.Http.Headers\nResponse.Headers[HeaderNames.CacheControl] = &quot;no-cache, no-store, must-revalidate&quot;;\nResponse.Headers[HeaderNames.Expires] = &quot;0&quot;;\nResponse.Headers[HeaderNames.Pragma] = &quot;no-cache&quot;;\n</code></pre>\n<p>Using ASP:</p>\n<pre class="lang-vb prettyprint-override"><code>Response.addHeader &quot;Cache-Control&quot;, &quot;no-cache, no-store, must-revalidate&quot; \' HTTP 1.1.\nResponse.addHeader &quot;Pragma&quot;, &quot;no-cache&quot; \' HTTP 1.0.\nResponse.addHeader &quot;Expires&quot;, &quot;0&quot; \' Proxies.\n</code></pre>\n<p>Using Ruby on Rails:</p>\n<pre class="lang-ruby prettyprint-override"><code>headers[&quot;Cache-Control&quot;] = &quot;no-cache, no-store, must-revalidate&quot; # HTTP 1.1.\nheaders[&quot;Pragma&quot;] = &quot;no-cache&quot; # HTTP 1.0.\nheaders[&quot;Expires&quot;] = &quot;0&quot; # Proxies.\n</code></pre>\n<p>Using Python/Flask:</p>\n<pre class="lang-python prettyprint-override"><code>response = make_response(render_template(...))\nresponse.headers[&quot;Cache-Control&quot;] = &quot;no-cache, no-store, must-revalidate&quot; # HTTP 1.1.\nresponse.headers[&quot;Pragma&quot;] = &quot;no-cache&quot; # HTTP 1.0.\nresponse.headers[&quot;Expires&quot;] = &quot;0&quot; # Proxies.\n</code></pre>\n<p>Using Python/Django:</p>\n<pre class="lang-python prettyprint-override"><code>response[&quot;Cache-Control&quot;] = &quot;no-cache, no-store, must-revalidate&quot; # HTTP 1.1.\nresponse[&quot;Pragma&quot;] = &quot;no-cache&quot; # HTTP 1.0.\nresponse[&quot;Expires&quot;] = &quot;0&quot; # Proxies.\n</code></pre>\n<p>Using Python/Pyramid:</p>\n<pre class="lang-python prettyprint-override"><code>request.response.headerlist.extend(\n    (\n        (\'Cache-Control\', \'no-cache, no-store, must-revalidate\'),\n        (\'Pragma\', \'no-cache\'),\n        (\'Expires\', \'0\')\n    )\n)\n</code></pre>\n<p>Using Go:</p>\n<pre class="lang-default prettyprint-override"><code>responseWriter.Header().Set(&quot;Cache-Control&quot;, &quot;no-cache, no-store, must-revalidate&quot;) // HTTP 1.1.\nresponseWriter.Header().Set(&quot;Pragma&quot;, &quot;no-cache&quot;) // HTTP 1.0.\nresponseWriter.Header().Set(&quot;Expires&quot;, &quot;0&quot;) // Proxies.\n</code></pre>\n<p>Using Clojure (require Ring utils):</p>\n<pre class="lang-clj prettyprint-override"><code>(require \'[ring.util.response :as r])\n(-&gt; response\n  (r/header &quot;Cache-Control&quot; &quot;no-cache, no-store, must-revalidate&quot;)\n  (r/header &quot;Pragma&quot; &quot;no-cache&quot;)\n  (r/header &quot;Expires&quot; 0))\n</code></pre>\n<p>Using Apache <code>.htaccess</code> file:</p>\n<pre class="lang-xml prettyprint-override"><code>&lt;IfModule mod_headers.c&gt;\n    Header set Cache-Control &quot;no-cache, no-store, must-revalidate&quot;\n    Header set Pragma &quot;no-cache&quot;\n    Header set Expires 0\n&lt;/IfModule&gt;\n</code></pre>\n<p>Using HTML:</p>\n<pre class="lang-html prettyprint-override"><code>&lt;meta http-equiv=&quot;Cache-Control&quot; content=&quot;no-cache, no-store, must-revalidate&quot;&gt;\n&lt;meta http-equiv=&quot;Pragma&quot; content=&quot;no-cache&quot;&gt;\n&lt;meta http-equiv=&quot;Expires&quot; content=&quot;0&quot;&gt;\n</code></pre>\n<h1>HTML meta tags vs HTTP response headers</h1>\n<p>Important to know is that when an HTML page is served over an HTTP connection, and a header is present in <strong>both</strong> the HTTP response headers and the HTML <code>&lt;meta http-equiv&gt;</code> 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 <code>file://</code> URL. See also <a href="http://www.w3.org/TR/html4/charset.html#h-5.2.2" rel="noreferrer">W3 HTML spec chapter 5.2.2</a>. Take care with this when you don\'t specify them programmatically because the webserver can namely include some default values.</p>\n<p>Generally, you\'d better just <strong>not</strong> specify the HTML meta tags to avoid confusion by starters and rely on hard HTTP response headers. Moreover, specifically those <code>&lt;meta http-equiv&gt;</code> tags are <a href="http://validator.w3.org" rel="noreferrer"><strong>invalid</strong></a> in HTML5. Only the <code>http-equiv</code> values listed in <a href="http://w3c.github.io/html/document-metadata.html#pragma-directives" rel="noreferrer">HTML5 specification</a> are allowed.</p>\n<h1>Verifying the actual HTTP response headers</h1>\n<p>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 &quot;Network&quot; or &quot;Net&quot; tab panel, and then clicking the HTTP request of interest to uncover all detail about the HTTP request and response. The <a href="https://i.stack.imgur.com/fSnXH.png" rel="noreferrer">below screenshot</a> is from Chrome:</p>\n<p><img src="https://i.stack.imgur.com/fSnXH.png" alt="Chrome developer toolset HTTP traffic monitor showing HTTP response headers on stackoverflow.com" /></p>\n<h1>I want to set those headers on file downloads too</h1>\n<p>First of all, this question and answer are targeted on &quot;web pages&quot; (HTML pages), not &quot;file downloads&quot; (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 <a href="https://stackoverflow.com/q/5034454">IE cannot download foo.jsf. IE was not able to open this internet site. The requested site is either unavailable or cannot be found</a>.</p>\n'}, {'answer_id': 5493543, 'author': 'Kornel', 'author_id': 27009, 'author_profile': 'https://Stackoverflow.com/users/27009', 'pm_score': 8, 'selected': False, 'text': '<p>(hey, everyone: please don\'t just mindlessly copy&amp;paste all headers you can find)</p>\n<p>First of all, <a href="http://httpwg.org/specs/rfc7234.html#history.lists" rel="noreferrer">Back button history is <em>not a cache</em></a>:</p>\n<blockquote>\n<p>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.</p>\n</blockquote>\n<p>In the old HTTP spec, the wording was even stronger, explicitly telling browsers to disregard cache directives for back button history.</p>\n<p>Back is supposed to go back in time (to the time when the user <em>was</em> logged in). It does not navigate forward to a previously opened URL.</p>\n<p>However, in practice, the cache can influence the back button, in very specific circumstances:</p>\n<ul>\n<li>Page <em>must</em> be delivered over <strong>HTTPS</strong>, 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.</li>\n<li>You must send <code>Cache-Control: no-store, must-revalidate</code> (some browsers observe <code>no-store</code> and some observe <code>must-revalidate</code>)</li>\n</ul>\n<p>You <em>never</em> need any of:</p>\n<ul>\n<li><code>&lt;meta&gt;</code> with cache headers — it doesn\'t work at all. Totally useless.</li>\n<li><code>post-check</code>/<code>pre-check</code> — it\'s an IE-only directive that only applies to <em>cachable</em> resources.</li>\n<li>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.</li>\n</ul>\n<p>If you want, you could add:</p>\n<ul>\n<li><code>no-cache</code> or <code>max-age=0</code>, which will make resource (URL) &quot;stale&quot; and require browsers to check with the server if there\'s a newer version (<code>no-store</code> already implies this even stronger).</li>\n<li><code>Expires</code> with a date in the past for HTTP/1.0 clients (although <em>real</em> HTTP/1.0-only clients are completely non-existent these days).</li>\n</ul>\n<hr />\n<p>Bonus: <a href="http://httpwg.org/specs/rfc7234.html" rel="noreferrer">The new HTTP caching RFC</a>.</p>\n'}, {'answer_id': 5767046, 'author': 'Tobias', 'author_id': 591025, 'author_profile': 'https://Stackoverflow.com/users/591025', 'pm_score': 2, 'selected': False, 'text': '<p>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:</p>\n\n<pre><code>&lt;body onunload=""&gt; \n</code></pre>\n\n<p>This hack apparently breaks the back-forward cache in Safari: <a href="https://stackoverflow.com/questions/158319/cross-browser-onload-event-and-the-back-button">Is there a cross-browser onload event when clicking the back button?</a></p>\n'}, {'answer_id': 11043978, 'author': 'Joseph Connolly', 'author_id': 1409310, 'author_profile': 'https://Stackoverflow.com/users/1409310', 'pm_score': 6, 'selected': False, 'text': '<p>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)</p>\n\n<pre class="lang-xml prettyprint-override"><code>&lt;configuration&gt;\n&lt;system.webServer&gt;\n    &lt;httpProtocol&gt;\n        &lt;customHeaders&gt;\n            &lt;add name="Cache-Control" value="no-cache, no-store, must-revalidate" /&gt;\n            &lt;!-- HTTP 1.1. --&gt;\n            &lt;add name="Pragma" value="no-cache" /&gt;\n            &lt;!-- HTTP 1.0. --&gt;\n            &lt;add name="Expires" value="0" /&gt;\n            &lt;!-- Proxies. --&gt;\n        &lt;/customHeaders&gt;\n    &lt;/httpProtocol&gt;\n&lt;/system.webServer&gt;\n</code></pre>\n\n<p></p>\n\n<p>And here is the express / node.js way of doing the same:</p>\n\n<pre class="lang-js prettyprint-override"><code>app.use(function(req, res, next) {\n    res.setHeader(\'Cache-Control\', \'no-cache, no-store, must-revalidate\');\n    res.setHeader(\'Pragma\', \'no-cache\');\n    res.setHeader(\'Expires\', \'0\');\n    next();\n});\n</code></pre>\n'}, {'answer_id': 12527392, 'author': 'Albert', 'author_id': 1688314, 'author_profile': 'https://Stackoverflow.com/users/1688314', 'pm_score': 3, 'selected': False, 'text': "<p>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.  </p>\n"}, {'answer_id': 14724964, 'author': 'yongfa365', 'author_id': 1879111, 'author_profile': 'https://Stackoverflow.com/users/1879111', 'pm_score': 2, 'selected': False, 'text': '<pre><code>//In .net MVC\n[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]\npublic ActionResult FareListInfo(long id)\n{\n}\n\n// In .net webform\n&lt;%@ OutputCache NoStore="true" Duration="0" VaryByParam="*" %&gt;\n</code></pre>\n'}, {'answer_id': 17090962, 'author': 'Edson Medina', 'author_id': 465738, 'author_profile': 'https://Stackoverflow.com/users/465738', 'pm_score': 3, 'selected': False, 'text': '<p>There\'s a bug in IE6</p>\n\n<p>Content with "Content-Encoding: gzip" is always cached even if you use "Cache-Control: no-cache".</p>\n\n<p><a href="http://support.microsoft.com/kb/321722" rel="noreferrer">http://support.microsoft.com/kb/321722</a></p>\n\n<p>You can disable gzip compression for IE6 users (check the user agent for "MSIE 6")</p>\n'}, {'answer_id': 17197577, 'author': 'user2321638', 'author_id': 2321638, 'author_profile': 'https://Stackoverflow.com/users/2321638', 'pm_score': 3, 'selected': False, 'text': '<p>in my case i fix the problem in chrome with this</p>\n\n<pre><code>&lt;form id="form1" runat="server" autocomplete="off"&gt;\n</code></pre>\n\n<p>where i need to clear the content of a previus form data when the users click button back for security reasons</p>\n'}, {'answer_id': 18516720, 'author': 'Pacerier', 'author_id': 632951, 'author_profile': 'https://Stackoverflow.com/users/632951', 'pm_score': 7, 'selected': False, 'text': '<p>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.</p>\n\n<p>In Chrome (v28.0.1500.95 m) we can do this only by <code>Cache-Control: no-store</code>.</p>\n\n<p>In FireFox (v23.0.1) any one of these will work:</p>\n\n<ol>\n<li><p><code>Cache-Control: no-store</code></p></li>\n<li><p><code>Cache-Control: no-cache</code> (https only)</p></li>\n<li><p><code>Pragma: no-cache</code> (https only)</p></li>\n<li><p><code>Vary: *</code> (https only)</p></li>\n</ol>\n\n<p>In Opera (v12.15) we only can do this by <code>Cache-Control: must-revalidate</code> (https only).</p>\n\n<p>In Safari (v5.1.7, 7534.57.2) any one of these will work:</p>\n\n<ol>\n<li><p><code>Cache-Control: no-store</code>\n<br><code>&lt;body onunload=""&gt;</code> in html</p></li>\n<li><p><code>Cache-Control: no-store</code> (https only)</p></li>\n</ol>\n\n<p>In IE8 (v8.0.6001.18702IC) any one of these will work:</p>\n\n<ol>\n<li><p><code>Cache-Control: must-revalidate, max-age=0</code></p></li>\n<li><p><code>Cache-Control: no-cache</code></p></li>\n<li><p><code>Cache-Control: no-store</code></p></li>\n<li><p><code>Cache-Control: must-revalidate</code>\n<br><code>Expires: 0</code></p></li>\n<li><p><code>Cache-Control: must-revalidate</code>\n<br><code>Expires: Sat, 12 Oct 1991 05:00:00 GMT</code></p></li>\n<li><p><code>Pragma: no-cache</code> (https only)</p></li>\n<li><p><code>Vary: *</code> (https only)</p></li>\n</ol>\n\n<p><strong>Combining the above gives us this solution which works for Chrome 28, FireFox 23, IE8, Safari 5.1.7, and Opera 12.15:</strong> <code>Cache-Control: no-store, must-revalidate</code> (https only)</p>\n\n<p>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:</p>\n\n<pre><code>Cache-Control: no-store\n&lt;body onunload=""&gt;\n</code></pre>\n\n<p>Below shows the raw logs of my tests:</p>\n\n<p><strong>HTTP:</strong></p>\n\n<ol>\n<li><p><code>Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: 0</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Opera 12.15</sub>\n<br>Success: Chrome 28, FireFox 23, IE8, Safari 5.1.7</p></li>\n<li><p><code>Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: Sat, 12 Oct 1991 05:00:00 GMT</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Opera 12.15</sub>\n<br>Success: Chrome 28, FireFox 23, IE8, Safari 5.1.7</p></li>\n<li><p><code>Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: 0</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><sub>Fail: Safari 5.1.7, Opera 12.15</sub>\n<br>Success: Chrome 28, FireFox 23, IE8</p></li>\n<li><p><code>Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: Sat, 12 Oct 1991 05:00:00 GMT</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><sub>Fail: Safari 5.1.7, Opera 12.15</sub>\n<br>Success: Chrome 28, FireFox 23, IE8</p></li>\n<li><p><code>Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: 0</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: IE8</p></li>\n<li><p><code>Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: Sat, 12 Oct 1991 05:00:00 GMT</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: IE8</p></li>\n<li><p><code>Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: 0</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: IE8</p></li>\n<li><p><code>Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: Sat, 12 Oct 1991 05:00:00 GMT</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: IE8</p></li>\n<li><p><code>Cache-Control: no-store</code>\n<br><sub>Fail: Safari 5.1.7, Opera 12.15</sub>\n<br>Success: Chrome 28, FireFox 23, IE8</p></li>\n<li><p><code>Cache-Control: no-store</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Opera 12.15</sub>\n<br>Success: Chrome 28, FireFox 23, IE8, Safari 5.1.7</p></li>\n<li><p><code>Cache-Control: no-cache</code>\n<br><sub>Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: IE8</p></li>\n<li><p><code>Vary: *</code>\n<br><sub>Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: none</p></li>\n<li><p><code>Pragma: no-cache</code>\n<br><sub>Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: none</p></li>\n<li><p><code>Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: Sat, 12 Oct 1991 05:00:00 GMT</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: IE8</p></li>\n<li><p><code>Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: 0</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: IE8</p></li>\n<li><p><code>Cache-Control: must-revalidate, max-age=0</code>\n<br><sub>Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: IE8</p></li>\n<li><p><code>Cache-Control: must-revalidate</code>\n<br><code>Expires: 0</code>\n<br><sub>Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: IE8</p></li>\n<li><p><code>Cache-Control: must-revalidate</code>\n<br><code>Expires: Sat, 12 Oct 1991 05:00:00 GMT</code>\n<br><sub>Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: IE8</p></li>\n<li><p><code>Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: none</p></li>\n</ol>\n\n<p><strong>HTTPS:</strong></p>\n\n<ol>\n<li><p><code>Cache-Control: private, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: 0</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: none</p></li>\n<li><p><code>Cache-Control: private, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: Sat, 12 Oct 1991 05:00:00 GMT</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: none</p></li>\n<li><p><code>Vary: *</code>\n<br><sub>Fail: Chrome 28, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: FireFox 23, IE8</p></li>\n<li><p><code>Pragma: no-cache</code>\n<br><sub>Fail: Chrome 28, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: FireFox 23, IE8</p></li>\n<li><p><code>Cache-Control: no-cache</code>\n<br><sub>Fail: Chrome 28, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: FireFox 23, IE8</p></li>\n<li><p><code>Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><sub>Fail: Chrome 28, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: FireFox 23, IE8</p></li>\n<li><p><code>Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: 0</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><sub>Fail: Chrome 28, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: FireFox 23, IE8</p></li>\n<li><p><code>Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: Sat, 12 Oct 1991 05:00:00 GMT</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><sub>Fail: Chrome 28, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: FireFox 23, IE8</p></li>\n<li><p><code>Cache-Control: must-revalidate</code>\n<br><sub>Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7</sub>\n<br>Success: Opera 12.15</p></li>\n<li><p><code>Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7</sub>\n<br>Success: Opera 12.15</p></li>\n<li><p><code>Cache-Control: must-revalidate, max-age=0</code>\n<br><sub>Fail: Chrome 28, FireFox 23, Safari 5.1.7</sub>\n<br>Success: IE8, Opera 12.15</p></li>\n<li><p><code>Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: Sat, 12 Oct 1991 05:00:00 GMT</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Chrome 28, Safari 5.1.7</sub>\n<br>Success: FireFox 23, IE8, Opera 12.15</p></li>\n<li><p><code>Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: 0</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Chrome 28, Safari 5.1.7</sub>\n<br>Success: FireFox 23, IE8, Opera 12.15</p></li>\n<li><p><code>Cache-Control: no-store</code>\n<br><sub>Fail: Opera 12.15</sub>\n<br>Success: Chrome 28, FireFox 23, IE8, Safari 5.1.7</p></li>\n<li><p><code>Cache-Control: private, no-cache, no-store, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: 0</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Opera 12.15</sub>\n<br>Success: Chrome 28, FireFox 23, IE8, Safari 5.1.7</p></li>\n<li><p><code>Cache-Control: private, no-cache, no-store, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: Sat, 12 Oct 1991 05:00:00 GMT</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Opera 12.15</sub>\n<br>Success: Chrome 28, FireFox 23, IE8, Safari 5.1.7</p></li>\n<li><p><code>Cache-Control: private, no-cache</code>\n<br><code>Expires: Sat, 12 Oct 1991 05:00:00 GMT</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><sub>Fail: Chrome 28, Safari 5.1.7, Opera 12.15</sub>\n<br>Success: FireFox 23, IE8</p></li>\n<li><p><code>Cache-Control: must-revalidate</code>\n<br><code>Expires: 0</code>\n<br><sub>Fail: Chrome 28, FireFox 23, Safari 5.1.7, </sub>\n<br>Success: IE8, Opera 12.15</p></li>\n<li><p><code>Cache-Control: must-revalidate</code>\n<br><code>Expires: Sat, 12 Oct 1991 05:00:00 GMT</code>\n<br><sub>Fail: Chrome 28, FireFox 23, Safari 5.1.7, </sub>\n<br>Success: IE8, Opera 12.15</p></li>\n<li><p><code>Cache-Control: private, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: 0</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Chrome 28, FireFox 23, Safari 5.1.7, </sub>\n<br>Success: IE8, Opera 12.15</p></li>\n<li><p><code>Cache-Control: private, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0</code>\n<br><code>Expires: Sat, 12 Oct 1991 05:00:00 GMT</code>\n<br><code>&lt;body onunload=""&gt;</code>\n<br><sub>Fail: Chrome 28, FireFox 23, Safari 5.1.7, </sub>\n<br>Success: IE8, Opera 12.15</p></li>\n<li><p><code>Cache-Control: private, must-revalidate</code>\n<br><code>Expires: Sat, 12 Oct 1991 05:00:00 GMT</code>\n<br><code>Pragma: no-cache</code>\n<br><code>Vary: *</code>\n<br><sub>Fail: Chrome 28, Safari 5.1.7</sub>\n<br>Success: FireFox 23, IE8, Opera 12.15</p></li>\n<li><p><code>Cache-Control: no-store, must-revalidate</code>\n<br><sub>Fail: none</sub>\n<br>Success: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15</p></li>\n</ol>\n'}, {'answer_id': 21753925, 'author': 'Carlos Escalera Alonso', 'author_id': 3197362, 'author_profile': 'https://Stackoverflow.com/users/3197362', 'pm_score': 1, 'selected': False, 'text': '<p>To complete <a href="https://stackoverflow.com/users/157882">BalusC</a> -> <a href="https://stackoverflow.com/questions/49547/making-sure-a-web-page-is-not-cached-across-all-browsers/2068407#2068407">ANSWER</a>\nIf you are using perl you can use CGI to add HTTP headers.</p>\n\n<p>Using Perl:</p>\n\n<pre><code>Use CGI;    \nsub set_new_query() {\n        binmode STDOUT, ":utf8";\n        die if defined $query;\n        $query = CGI-&gt;new();\n        print $query-&gt;header(\n                        -expires       =&gt; \'Sat, 26 Jul 1997 05:00:00 GMT\',\n                        -Pragma        =&gt; \'no-cache\',\n                        -Cache_Control =&gt; join(\', \', qw(\n                                            private\n                                            no-cache\n                                            no-store\n                                            must-revalidate\n                                            max-age=0\n                                            pre-check=0\n                                            post-check=0 \n                                           ))\n        );\n    }\n</code></pre>\n\n<p>Using apache httpd.conf</p>\n\n<pre><code>&lt;FilesMatch "\\.(html|htm|js|css|pl)$"&gt;\nFileETag None\n&lt;ifModule mod_headers.c&gt;\nHeader unset ETag\nHeader set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"\nHeader set Pragma "no-cache"\nHeader set Expires "Wed, 11 Jan 1984 05:00:00 GMT"\n&lt;/ifModule&gt;\n</code></pre>\n\n<p>\n\n<p><strong>Note:</strong> When I tried to use the html META, browsers ignored them and cached the page.</p>\n'}, {'answer_id': 22468342, 'author': 'JK.', 'author_id': 325727, 'author_profile': 'https://Stackoverflow.com/users/325727', 'pm_score': 3, 'selected': False, 'text': '<p>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:</p>\n\n<ul>\n<li><a href="https://stackoverflow.com/q/10908115/325727">Something is forcing responses to have cache-control: private in IIS7</a></li>\n<li><a href="https://stackoverflow.com/q/6165218/325727">IIS7: Cache Setting Not Working... why?</a></li>\n<li><a href="https://stackoverflow.com/q/1556026/325727">IIS7 + ASP.NET MVC Client Caching Headers Not Working</a></li>\n<li><a href="https://stackoverflow.com/q/17491296/325727">Set cache-control for aspx pages</a></li>\n<li><a href="https://stackoverflow.com/q/22443932/325727">Cache-control: no-store, must-revalidate not sent to client browser in IIS7 + ASP.NET MVC</a></li>\n</ul>\n\n<p>And so on</p>\n\n<p>The accepted answer is correct in which headers must be set, but not in how they must be set.  This way works with IIS7:</p>\n\n<pre><code>Response.Cache.SetCacheability(HttpCacheability.NoCache);\nResponse.Cache.AppendCacheExtension("no-store, must-revalidate");\nResponse.AppendHeader("Pragma", "no-cache");\nResponse.AppendHeader("Expires", "-1");\n</code></pre>\n\n<p>The first line sets <code>Cache-control</code> to <code>no-cache</code>, and the second line adds the other attributes <code>no-store, must-revalidate</code></p>\n'}, {'answer_id': 23760017, 'author': 'user3253726', 'author_id': 3253726, 'author_profile': 'https://Stackoverflow.com/users/3253726', 'pm_score': 0, 'selected': False, 'text': '<p>I just want to point out that if someone wants to prevent caching ONLY dynamic content, adding those additional headers should be made programmatically.</p>\n\n<p>I edited configuration file of my project to append no-cache headers, but that also disabled caching static content, which isn\'t usually desirable.\nModifying response headers in code assures that images and style files will be cached.</p>\n\n<p>This is quite obvious, yet still worth mentioning.</p>\n\n<p>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. </p>\n\n<p>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.</p>\n\n<p>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:</p>\n\n<pre><code>filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);\nfilterContext.HttpContext.Response.Cache.AppendCacheExtension("no-store, must-revalidate");\n</code></pre>\n'}, {'answer_id': 24556984, 'author': 'Paul', 'author_id': 3802165, 'author_profile': 'https://Stackoverflow.com/users/3802165', 'pm_score': 0, 'selected': False, 'text': '<p>See this link to a Case Study on Caching:</p>\n\n<p><a href="http://securityevaluators.com/knowledge/case_studies/caching/" rel="nofollow noreferrer">http://securityevaluators.com/knowledge/case_studies/caching/</a></p>\n\n<p>Summary, according to the article, only <code>Cache-Control: no-store</code> 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.</p>\n'}, {'answer_id': 37332851, 'author': 'kspearrin', 'author_id': 1090359, 'author_profile': 'https://Stackoverflow.com/users/1090359', 'pm_score': 3, 'selected': False, 'text': '<p>For ASP.NET Core, create a simple middleware class:</p>\n\n<pre><code>public class NoCacheMiddleware\n{\n    private readonly RequestDelegate m_next;\n\n    public NoCacheMiddleware( RequestDelegate next )\n    {\n        m_next = next;\n    }\n\n    public async Task Invoke( HttpContext httpContext )\n    {\n        httpContext.Response.OnStarting( ( state ) =&gt;\n        {\n            // ref: http://stackoverflow.com/questions/49547/making-sure-a-web-page-is-not-cached-across-all-browsers\n            httpContext.Response.Headers.Append( "Cache-Control", "no-cache, no-store, must-revalidate" );\n            httpContext.Response.Headers.Append( "Pragma", "no-cache" );\n            httpContext.Response.Headers.Append( "Expires", "0" );\n            return Task.FromResult( 0 );\n        }, null );\n\n        await m_next.Invoke( httpContext );\n    }\n}\n</code></pre>\n\n<p>then register it with <code>Startup.cs</code></p>\n\n<pre><code>app.UseMiddleware&lt;NoCacheMiddleware&gt;();\n</code></pre>\n\n<p>Make sure you add this somewhere after</p>\n\n<pre><code>app.UseStaticFiles();\n</code></pre>\n'}, {'answer_id': 38884396, 'author': 'Richard Elkins', 'author_id': 6169583, 'author_profile': 'https://Stackoverflow.com/users/6169583', 'pm_score': 0, 'selected': False, 'text': '<p>I had no luck with <code>&lt;head&gt;&lt;meta&gt;</code> elements. Adding HTTP cache related parameters directly (outside of the HTML doc) does indeed work for me.</p>\n\n<p>Sample code in Python using web.py <code>web.header</code> calls follows. I purposefully redacted my personal irrelevant utility code.</p>\n\n<pre>\n\n    import web\n    import sys\n    import PERSONAL-UTILITIES\n\n    myname = "main.py"\n\n    urls = (\n        \'/\', \'main_class\'\n    )\n\n    main = web.application(urls, globals())\n\n    render = web.template.render("templates/", base="layout", cache=False)\n\n    class main_class(object):\n        def GET(self):\n            web.header("Cache-control","no-cache, no-store, must-revalidate")\n            web.header("Pragma", "no-cache")\n            web.header("Expires", "0")\n            return render.main_form()\n\n        def POST(self):\n            msg = "POSTed:"\n            form = web.input(function = None)\n            web.header("Cache-control","no-cache, no-store, must-revalidate")\n            web.header("Pragma", "no-cache")\n            web.header("Expires", "0")\n            return render.index_laid_out(greeting = msg + form.function)\n\n    if __name__ == "__main__":\n        nargs = len(sys.argv)\n        # Ensure that there are enough arguments after python program name\n        if nargs != 2:\n            LOG-AND-DIE("%s: Command line error, nargs=%s, should be 2", myname, nargs)\n        # Make sure that the TCP port number is numeric\n        try:\n            tcp_port = int(sys.argv[1])\n        except Exception as e:\n            LOG-AND-DIE ("%s: tcp_port = int(%s) failed (not an integer)", myname, sys.argv[1])\n        # All is well!\n        JUST-LOG("%s: Running on port %d", myname, tcp_port)\n        web.httpserver.runsimple(main.wsgifunc(), ("localhost", tcp_port))\n        main.run()\n\n</pre>\n'}, {'answer_id': 39047433, 'author': 'ObiHill', 'author_id': 310139, 'author_profile': 'https://Stackoverflow.com/users/310139', 'pm_score': 2, 'selected': False, 'text': '<p>Also, just for good measure, make sure you reset the <code>ExpiresDefault</code> in your <code>.htaccess</code> file if you\'re using that to enable caching.</p>\n\n<pre><code>ExpiresDefault "access plus 0 seconds"\n</code></pre>\n\n<p>Afterwards, you can use <code>ExpiresByType</code> to set specific values for the files you want to cache:</p>\n\n<pre><code>ExpiresByType image/x-icon "access plus 3 month"\n</code></pre>\n\n<p>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 <code>ExpiresDefault</code>.</p>\n'}, {'answer_id': 61744446, 'author': 'CodeMind', 'author_id': 2408266, 'author_profile': 'https://Stackoverflow.com/users/2408266', 'pm_score': -1, 'selected': False, 'text': '<p>you can use location block for set individual file instead of whole app get caching in IIS      </p>\n\n<pre><code> &lt;location path="index.html"&gt;\n    &lt;system.webServer&gt;\n      &lt;httpProtocol&gt;\n        &lt;customHeaders&gt;\n          &lt;add name="Cache-Control" value="no-cache" /&gt;\n        &lt;/customHeaders&gt;\n      &lt;/httpProtocol&gt;\n    &lt;/system.webServer&gt;\n  &lt;/location&gt;\n</code></pre>\n'}, {'answer_id': 62086019, 'author': 'Antonio Ooi', 'author_id': 2200913, 'author_profile': 'https://Stackoverflow.com/users/2200913', 'pm_score': -1, 'selected': False, 'text': '<p>Not sure if my answer sounds simple and stupid, and perhaps it has already been known to you since long time ago, but since <strong>preventing someone from using browser back button to view your historical pages</strong> is one of your goals, you can use:</p>\n\n<p><code>window.location.replace("https://www.example.com/page-not-to-be-viewed-in-browser-history-back-button.html");</code></p>\n\n<p>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.</p>\n'}, {'answer_id': 62340815, 'author': 'elle0087', 'author_id': 3061212, 'author_profile': 'https://Stackoverflow.com/users/3061212', 'pm_score': 0, 'selected': False, 'text': '<p>i have solved in this way.</p>\n\n<p>2 considerations:</p>\n\n<p>1) the server side events are not fired on back click, instead of javascript.</p>\n\n<p>2) i have 2 javascript to read/write cookies</p>\n\n<pre><code>function setCookie(name, value, days)\n{\n    var expires = "";\n    if (days)\n    {\n        var date = new Date();\n        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));\n        expires = "; expires=" + date.toUTCString();\n    }\n    document.cookie = name + "=" + (value || "") + expires + "; path=/";\n}\n\nfunction getCookie(name)\n{\n    var nameEQ = name + "=";\n    var ca = document.cookie.split(\';\');\n\n    for (var i = ca.length - 1; i &gt;= 0; i--)\n    {\n        var c = ca[i];\n        while (c.charAt(0) == \' \')\n        {\n            c = c.substring(1, c.length);\n        }\n\n        if (c.indexOf(nameEQ) == 0)\n        {\n            return c.substring(nameEQ.length, c.length);\n        }\n    }\n    return null;\n}\n</code></pre>\n\n<p>in my Page_Load i inserted this: (this is NOT fired on back click)</p>\n\n<pre><code>    protected void Page_Load(object sender, EventArgs e)\n    {\n       Page.RegisterClientScriptBlock("", "&lt;script&gt;setCookie(\'" + Session.SessionID + "\', \'" + Login + "\', \'100\');&lt;/script&gt;");\n    }\n</code></pre>\n\n<p>where \'Login\' is my id value that is -1 after logout (you could use something else, a boolean for example).</p>\n\n<p>then in my page i added this: (this IS fired on back click)</p>\n\n<pre><code>&lt;script type="text/javascript"&gt;\nif (getCookie(\'&lt;%= Session.SessionID %&gt;\') &lt; 0)\n        {\n            if (history.length &gt; 0)\n            {\n                history.go(+1);\n            }\n        }\n\n&lt;/script&gt;\n</code></pre>\n\n<p>nothing else.</p>\n\n<p>with this solution back click is enable on every page and disable only after logout on each page on the same browser.</p>\n'}]
['https://Stackoverflow.com/questions/49547', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/5182/']