Disabling browser caching for all browsers from ASP.NET
Asked Answered
E

6

89

I'm after a definitive reference to what ASP.NET code is required to disabled browsers from caching the page. There are many ways to affect the HTTP headers and meta tags and I get the impression different settings are required to get different browsers to behave correctly. It would be really great to get a reference bit of code commented to indicate which works for all browsers and which is required for particular browser, including versions.

There is a huge amount of information about this issue there but I have yet to find a good reference that describes the benefits of each method and whether a particular technique has been superseded by a higher level API.

I'm particularly interested in ASP.NET 3.5 SP1 but it would be good to get answers for earlier version as well.

This blog entry Two Important Differences between Firefox and IE Caching describes some HTTP protocol behaviour differences.

The following sample code illustrates the kind of thing I am interested in

public abstract class NoCacheBasePage : System.Web.UI.Page
{
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

        DisableClientCaching();
    }

    private void DisableClientCaching()
    {
        // Do any of these result in META tags e.g. <META HTTP-EQUIV="Expire" CONTENT="-1">
        // HTTP Headers or both?

        // Does this only work for IE?
        Response.Cache.SetCacheability(HttpCacheability.NoCache);

        // Is this required for FireFox? Would be good to do this without magic strings.
        // Won't it overwrite the previous setting
        Response.Headers.Add("Cache-Control", "no-cache, no-store");

        // Why is it necessary to explicitly call SetExpires. Presume it is still better than calling
        // Response.Headers.Add( directly
        Response.Cache.SetExpires(DateTime.UtcNow.AddYears(-1));
    }
}
Esculent answered 27/5, 2009 at 5:3 Comment(2)
I would attempt to answer if I didn't know how horribly impossible thy task is. Controlling the client's cache is like trying to use 10 foot long chopsticks to rearrange furniture.Freese
A whole lot of answers that cover just a part of the problem would still be very valuable. Please throw in your 2 cents worth.Esculent
H
100

This is what we use in ASP.NET:

// Stop Caching in IE
Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);

// Stop Caching in Firefox
Response.Cache.SetNoStore();

It stops caching in Firefox and IE, but we haven't tried other browsers. The following response headers are added by these statements:

Cache-Control: no-cache, no-store
Pragma: no-cache
Hexosan answered 27/5, 2009 at 22:39 Comment(6)
+1 This is working for me in Chrome, thanks a lot. I also use Response.Cache.SetAllowResponseInBrowserHistory(true); to avoid history to store an entry for each request of the same page.Pose
Apparently someone has discovered that using SetCacheability with NoCache also disables the ASP.NET output cache (server-side cache). They suggest to use the ServerAndNoCache option instead. codeclimber.net.nz/archive/2007/04/01/…Hyperacidity
To clarify the comments in the code snippet, the main method is SetCacheability. SetNoStore is an IE6 workaround. See Why both no-cache and no-store should be used in HTTP response?.Stockstill
FWIW ... Needed to add SetNoStore for IE10Pissed
For those reading this page who will be outputting dynamic PDFs over https and setting the cache headers like this, please beware the following IE8 and lower bug: #1039207Domesticate
This is the absolute right question on this topic! I have tried everything, action fiters onExecuting and onExecuted with all kind of combinations and nothing workes. But adding this on my rendering model worked like a charm!Circumbendibus
U
42

For what it's worth, I just had to handle this in my ASP.NET MVC 3 application. Here is the code block I used in the Global.asax file to handle this for all requests.

    protected void Application_BeginRequest()
    {
        //NOTE: Stopping IE from being a caching whore
        HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(false);
        HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        HttpContext.Current.Response.Cache.SetNoStore();
        Response.Cache.SetExpires(DateTime.Now);
        Response.Cache.SetValidUntilExpires(true);
    }
Ultramodern answered 14/4, 2011 at 14:6 Comment(8)
The HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(false) made the difference to prevent caching in bith IE and FireFoxPellmell
-1, setting in these Application_BeginRequest() causes the no-cache headers to be sent for items that you'll probably want cached (JavaScript files, images, etc). I haven't tried it yet, but the OP's location (setting the headers in the ASP page itself) is probably better.Plier
I did expect this answer to work as it is neatest way to set it in glabal.asax but no joy yetAnaphrodisiac
@Evan, Application_BeginRequest will only be called for requests that are sent from IIS to ASP.NET. Many times, static files like CSS, JS, Images, Fonts, etc. are extensions that are considered static files from IIS and not sent to the ASP.NET Runtime. If IIS is set up to send all requests to the ASP.NET runtime, then yes, this would apply to all requests, even if the files are static and should be cached.Ultramodern
@Adam, makes sense. I would undo my -1 but SO says my vote is locked in :-(Plier
OK, nit pick here... The HttpResponse object is being referenced 2 different ways: 1) HttpContext.Current.Response and 2) Response. It would probably be cleaner to pick one or the other.Meekins
I've found applying a global action filter to be more modular. Plus you can accommodate situations where MVC is serving up static files (like Bundled scripts and styles). https://mcmap.net/q/242716/-disable-browser-cache-for-all-actions-but-keep-it-for-bundlesMccandless
StriplingWarrior is right, this method also appears to affect bundles (which is not what most people would want). In local environment it will also affect static files like Evan Haas said, but on remote server, IIS will handle those (unless you set it differently for some reason). I've patched up a quick and dirty solution to this problem here https://mcmap.net/q/242716/-disable-browser-cache-for-all-actions-but-keep-it-for-bundlesOtes
A
2

I've tried various combinations and had them fail in FireFox. It has been a while so the answer above may work fine or I may have missed something.

What has always worked for me is to add the following to the head of each page, or the template (Master Page in .net).

<script language="javascript" type="text/javascript">
    window.onbeforeunload = function () {   
        // This function does nothing.  It won't spawn a confirmation dialog   
        // But it will ensure that the page is not cached by the browser.
    }  
</script>

This has disabled all caching in all browsers for me without fail.

Albania answered 22/11, 2011 at 7:21 Comment(2)
Not sure what this is supposed to do, but it does look like a big fat hack that is bound to fail in the next update of any of these browsers.Hyperacidity
It's explained at e.g. web.archive.org/web/20160112095216/http://www.hunlock.com/blogs/… -- in summary the onbeforeunload event was implemented to be used by banks and prevents the page being cached.Decoy
R
1

There are two approaches that I know of. The first is to tell the browser not to cache the page. Setting the Response to no cache takes care of that, however as you suspect the browser will often ignore this directive. The other approach is to set the date time of your response to a point in the future. I believe all browsers will correct this to the current time when they add the page to the cache, but it will show the page as newer when the comparison is made. I believe there may be some cases where a comparison is not made. I am not sure of the details and they change with each new browser release. Final note I have had better luck with pages that "refresh" themselves (another response directive). The refresh seems less likely to come from the cache.

Hope that helps.

Reduplication answered 27/5, 2009 at 16:3 Comment(0)
P
0

I'm going to test adding the no-store tag to our site to see if this makes a difference to browser caching (Chrome has sometimes been caching the pages). I also found this article very useful on documentation on how and why caching works and will look at ETag's next if the no-store is not reliable:

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

http://en.wikipedia.org/wiki/HTTP_ETag

Puerile answered 28/7, 2012 at 3:0 Comment(0)
D
0

See also How to prevent google chrome from caching my inputs, esp hidden ones when user click back? without which Chrome might reload but preserve the previous content of <input> elements -- in other words, use autocomplete="off".

Decoy answered 5/11, 2016 at 9:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.