Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 544059
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T10:36:53+00:00 2026-05-13T10:36:53+00:00

Our investigations have shown us that not all browsers respect the HTTP cache directives

  • 0

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.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T10:36:54+00:00Added an answer on May 13, 2026 at 10:36 am

    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.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Our application is a Java-GWT application that uses Guice-Persist and Guice-Servlet extensively. We have
I have been investigating a JSF upgrade on our existing web apps that are
Some of the users of our Ruby on Rails app have complained that page
Our organisation will not upgrade our hardware because they believe that VS2010 with Resharper
Our company produces cross-platform software and we have Bamboo instance which is building projects
Our Django project is getting huge. We have hundreds of apps and use a
We have a .NET application which our customers consider too large for mass deployment
We have a legacy VB6 app, which is critical to our business. We're working
We have really strange and inconsistent behavior with Linq-to-SQL here. Our application is installed
Following on from this initial investigations on Silverlight architectures, I have some new requirements

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.