Вопрос: Как управлять кэшированием веб-страниц во всех браузерах?


Наши исследования показали нам, что не все браузеры одинаково уважают директивы кэша http.

По соображениям безопасности мы не хотим, чтобы определенные страницы в нашем приложении были кэшированы, Когда-либо, через веб-браузер. Это должно работать, по крайней мере, для следующих браузеров:

  • Internet Explorer 6+
  • Firefox 1.5+
  • Safari 3+
  • Opera 9+
  • Хром

Наше требование исходило из теста безопасности. После выхода из нашего веб-сайта вы можете нажать кнопку «Назад» и просмотреть кешированные страницы.


1204


источник


Ответы:


Введение

Правильный минимальный набор заголовков, который работает со всеми указанными клиентами (и прокси):

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

Cache-Controlсоответствует спецификации HTTP 1.1 для клиентов и прокси (и неявно требуется некоторыми клиентами рядом с Expires). Pragmaсоответствует спецификации HTTP 1.0 для доисторических клиентов. Expiresсоответствует спецификациям HTTP 1.0 и 1.1 для клиентов и прокси. В HTTP 1.1, Cache-Controlимеет приоритет над Expires, так что это ведь только для прокси HTTP 1.0.

Если вас не волнует IE6 и его сломанное кэширование при обслуживании страниц через HTTPS только с no-store, то вы можете опустить 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

Но это может быть неудачным, если, например, enduser манипулирует датой операционной системы и клиентское программное обеспечение полагается на нее.

Другие Cache-Controlпараметры, такие как max-ageне имеют значения, если вышеупомянутое Cache-Controlпараметры указаны. Last-Modifiedзаголовок, который включен в большинство других ответов здесь только интересно, если вы на самом деле хочу для кэширования запроса, поэтому вам не нужно указывать его вообще.

Как его установить?

Использование 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:

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 или Python / Flask:

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

Использование Google 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.

Использование 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>

Использование HTML4:

<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-ответа

Важно знать, что когда HTML-страница обслуживается по HTTP-соединению, а заголовок присутствует в и то и другое заголовки ответа HTTP и HTML <meta http-equiv>теги, то тот, который указан в заголовке ответа HTTP, будет иметь приоритет над метатегами HTML. Метатег HTML будет использоваться только тогда, когда страница просматривается из локальной файловой системы на диске через file://URL. Смотрите также W3 HTML spec глава 5.2.2 , Позаботьтесь об этом, когда вы не укажете их программно, потому что веб-сервер может включать в себя некоторые значения по умолчанию.

Как правило, вам лучше просто не указать метатеги HTML, чтобы избежать путаницы со стороны стартеров и полагаться на жесткие заголовки HTTP-ответа. Более того, <meta http-equiv>теги инвалид в HTML5. Только http-equivзначения, перечисленные в Спецификация HTML5 разрешается.

Проверка фактических заголовков HTTP-ответа

Чтобы проверить это, вы можете увидеть / отладить их в HTTP-мониторе трафика инструментария разработчика webbrowser. Вы можете попасть туда, нажав F12 в Chrome / Firefox23 + / IE9 +, а затем откройте вкладку «Сеть» или «Нет», а затем щелкните интересующий HTTP-запрос, чтобы узнать все подробности о HTTP-запросе и ответе. ниже скриншота из Chrome:

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

Я хочу также настроить эти заголовки на загрузку файлов

Прежде всего, этот вопрос и ответ ориентированы на «веб-страницы» (HTML-страницы), а не «загрузки файлов» (PDF, zip, Excel и т. Д.). Вам лучше их кэшировать и использовать некоторый идентификатор версии файла где-нибудь в пути URI или в строке запроса, чтобы принудительно загрузить загруженный файл. При любом использовании этих заголовков без кеша на загрузку файлов, будьте осторожны с ошибкой IE7 / 8 при обслуживании загрузки файлов через HTTPS вместо HTTP. Подробные сведения см. IE не может загрузить foo.jsf. IE не смог открыть этот интернет-сайт. Запрошенный сайт либо недоступен, либо не может быть найден ,


2089



(эй, все: пожалуйста, не просто бездумно скопируйте и вставьте все заголовки, которые вы можете найти)

Прежде всего, История кнопки «Назад» не кеш :

Модель свежести (раздел 4.2) не обязательно относится к механизмам истории. То есть механизм истории может отображать предыдущее представление, даже если оно истекло.

В старой спецификации HTTP формулировка была еще более сильной, явно сообщая браузерам игнорировать директивы кэша для истории кнопки «Назад».

Возврат должен возвращаться во времени (к моменту, когда пользователь был вошел в систему). Он не перемещается вперед к ранее открытому URL-адресу.

Однако на практике кеш может влиять на кнопку «Назад» в особых обстоятельствах:

  • страница должен доставляться HTTPS , в противном случае это кэширование не будет надежным. Кроме того, если вы не используете HTTPS, ваша страница уязвима для воровства входа во многих других направлениях.
  • Вы должны отправить Cache-Control: no-store, must-revalidate(некоторые браузеры наблюдают no-storeи некоторые наблюдают must-revalidate)

Вы никогда нужен любой из:

  • <meta>с заголовками кеша - он вообще не работает. Совершенно бесполезно.
  • post-check/ pre-check- это директива только для IE, которая применяется только к кэшируемы Ресурсы.
  • Отправка одного и того же заголовка дважды или десятка частей. Некоторые фрагменты PHP фактически заменяют предыдущие заголовки, в результате чего отправляется только последний.

Если вы хотите, вы можете добавить:

  • no-cacheили max-age=0, что сделает ресурс (URL) «устаревшим» и потребует от браузеров проверки с сервером, если есть более новая версия ( no-storeуже подразумевает это еще сильнее).
  • Expiresс датой в прошлом для клиентов HTTP / 1.0 (хотя реальный В настоящее время только клиенты HTTP / 1.0 полностью не существуют.

Бонус: Новый HTTP-кэширование RFC ,


202



Как заявила porneL, вы хотите не деактивировать кеш, а деактивировать буфер истории. У разных браузеров есть свои тонкие способы отключить буфер истории.

В Chrome (v28.0.1500.95 m) мы можем сделать это только Cache-Control: no-store,

В FireFox (v23.0.1) любой из них будет работать:

  1. Cache-Control: no-store

  2. 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
    <body onunload="">в html

  2. Cache-Control: no-store(только https)

В IE8 (v8.0.6001.18702IC) любой из них будет работать:

  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)

  7. Vary: *(только 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-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Ошибка: Opera 12.15
    Успех: 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="">
    Ошибка: Opera 12.15
    Успех: 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: *
    Ошибка: Safari 5.1.7, Opera 12.15
    Успех: 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: *
    Ошибка: Safari 5.1.7, Opera 12.15
    Успех: 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="">
    Ошибка: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Успех: 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="">
    Ошибка: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Успех: 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="">
    Ошибка: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Успех: 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="">
    Ошибка: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Успех: IE8

  9. Cache-Control: no-store
    Ошибка: Safari 5.1.7, Opera 12.15
    Успех: Chrome 28, FireFox 23, IE8

  10. Cache-Control: no-store
    <body onunload="">
    Ошибка: Opera 12.15
    Успех: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  11. Cache-Control: no-cache
    Ошибка: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Успех: IE8

  12. Vary: *
    Ошибка: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Успех: нет

  13. Pragma: no-cache
    Ошибка: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Успех: нет

  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="">
    Ошибка: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Успех: 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="">
    Ошибка: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Успех: IE8

  16. Cache-Control: must-revalidate, max-age=0
    Ошибка: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Успех: IE8

  17. Cache-Control: must-revalidate
    Expires: 0
    Ошибка: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Успех: IE8

  18. Cache-Control: must-revalidate
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Ошибка: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Успех: IE8

  19. Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Ошибка: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Успех: нет

HTTPS:

  1. Cache-Control: private, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    <body onunload="">
    Ошибка: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Успех: нет

  2. Cache-Control: private, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    <body onunload="">
    Ошибка: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Успех: нет

  3. Vary: *
    Ошибка: Chrome 28, Safari 5.1.7, Opera 12.15
    Успех: FireFox 23, IE8

  4. Pragma: no-cache
    Ошибка: Chrome 28, Safari 5.1.7, Opera 12.15
    Успех: FireFox 23, IE8

  5. Cache-Control: no-cache
    Ошибка: Chrome 28, Safari 5.1.7, Opera 12.15
    Успех: FireFox 23, IE8

  6. Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0
    Ошибка: Chrome 28, Safari 5.1.7, Opera 12.15
    Успех: FireFox 23, IE8

  7. Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    Ошибка: Chrome 28, Safari 5.1.7, Opera 12.15
    Успех: FireFox 23, IE8

  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: *
    Ошибка: Chrome 28, Safari 5.1.7, Opera 12.15
    Успех: FireFox 23, IE8

  9. Cache-Control: must-revalidate
    Ошибка: Chrome 28, FireFox 23, IE8, Safari 5.1.7
    Успех: Opera 12.15

  10. Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0
    <body onunload="">
    Ошибка: Chrome 28, FireFox 23, IE8, Safari 5.1.7
    Успех: Opera 12.15

  11. Cache-Control: must-revalidate, max-age=0
    Ошибка: Chrome 28, FireFox 23, Safari 5.1.7
    Успех: 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="">
    Ошибка: Chrome 28, Safari 5.1.7
    Успех: 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="">
    Ошибка: Chrome 28, Safari 5.1.7
    Успех: FireFox 23, IE8, Opera 12.15

  14. Cache-Control: no-store
    Ошибка: Opera 12.15
    Успех: 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="">
    Ошибка: Opera 12.15
    Успех: 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="">
    Ошибка: Opera 12.15
    Успех: 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: *
    Ошибка: Chrome 28, Safari 5.1.7, Opera 12.15
    Успех: FireFox 23, IE8

  18. Cache-Control: must-revalidate
    Expires: 0
    Ошибка: Chrome 28, FireFox 23, Safari 5.1.7,
    Успех: IE8, Opera 12.15

  19. Cache-Control: must-revalidate
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Ошибка: Chrome 28, FireFox 23, Safari 5.1.7,
    Успех: IE8, Opera 12.15

  20. Cache-Control: private, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    <body onunload="">
    Ошибка: Chrome 28, FireFox 23, Safari 5.1.7,
    Успех: IE8, Opera 12.15

  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="">
    Ошибка: Chrome 28, FireFox 23, Safari 5.1.7,
    Успех: IE8, Opera 12.15

  22. Cache-Control: private, must-revalidate
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    Ошибка: Chrome 28, Safari 5.1.7
    Успех: FireFox 23, IE8, Opera 12.15

  23. Cache-Control: no-store, must-revalidate
    Ошибка: нет
    Успех: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15


80



Я обнаружил, что все ответы на этой странице все еще были проблемы. В частности, я заметил, что ни один из них не остановит использование IE8 кэшированной версии страницы, когда вы обратились к ней, нажав кнопку «Назад».

После долгих исследований и испытаний я обнаружил, что единственными двумя заголовками, которые мне действительно нужны были:

Cache-Control: no-store
Vary: *

Для объяснения заголовка 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-адрес непосредственно в адресной строке. Это касается 99% всех браузеров, используемых с января 2010 года.

В IE6 и Opera 9-10 нажатие кнопки «Назад» по-прежнему вызывало загрузку кешированной версии. Во всех других браузерах, которые я тестировал, они получили новую версию с сервера. До сих пор я не нашел ни одного набора заголовков, которые заставят эти браузеры не возвращать кешированные версии страниц при нажатии кнопки «Назад».

Обновить: После написания этого ответа я понял, что наш веб-сервер идентифицирует себя как сервер HTTP 1.0. Заголовки, которые я перечислял, являются правильными, чтобы ответы с сервера HTTP 1.0 не кэшировались браузерами. Для сервера HTTP 1.1 посмотрите на BalusC. ответ ,


21



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();
});

21



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", "Mon, 26 Jul 1997 05:00:00 GMT"); // HTTP 1.0 

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


17



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


7



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.


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


6



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.


5