Введение
Правильный минимальный набор заголовков, который работает на всех упомянутых клиентах (и прокси):
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
Но это может не сработать, если, например, конечный пользователь манипулирует датой операционной системы, а клиентское программное обеспечение полагается на нее.
Другие параметры 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-сервлета или 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:
headers["Cache-Control"] = "no-cache, no-store, must-revalidate" # HTTP 1.1.
headers["Pragma"] = "no-cache" # HTTP 1.0.
headers["Expires"] = "0" # Proxies.
Использование Python / Django:
response["Cache-Control"] = "no-cache, no-store, must-revalidate" # HTTP 1.1.
response["Pragma"] = "no-cache" # HTTP 1.0.
response["Expires"] = "0" # Proxies.
Использование Python / Pyramid:
request.response.headerlist.extend(
(
('Cache-Control', 'no-cache, no-store, must-revalidate'),
('Pragma', 'no-cache'),
('Expires', '0')
)
)
Использование Go:
responseWriter.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") // HTTP 1.1.
responseWriter.Header().Set("Pragma", "no-cache") // HTTP 1.0.
responseWriter.Header().Set("Expires", "0") // Proxies.
Использование 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>
Использование 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 будет использоваться только при просмотре страницы из файловой системы локального диска по URL-адресу file://
. Смотрите также W3 HTML спецификация глава 5.2.2 . Будьте осторожны, когда вы не указываете их программно, потому что веб-сервер может включать некоторые значения по умолчанию.
Как правило, лучше просто , а не указывать метатеги HTML, чтобы избежать путаницы со стороны начинающих, и полагаться на жесткие заголовки HTTP-ответов. Более того, именно эти теги <meta http-equiv>
являются недействительными в HTML5. Разрешены только значения http-equiv
, указанные в спецификации HTML5 .
Проверка фактических заголовков ответа HTTP
Для проверки того и другого вы можете увидеть / отладить их в мониторе HTTP-трафика набора инструментов разработчика веб-браузера. Для этого нажмите F12 в Chrome / Firefox23 + / IE9 +, а затем откройте панель вкладок «Сеть» или «Сеть», а затем щелкните интересующий HTTP-запрос, чтобы раскрыть все подробности о HTTP-запросе и ответе. ниже скриншот из Chrome:
Я хочу установить эти заголовки и при загрузке файлов
Прежде всего, этот вопрос и ответ нацелены на «веб-страницы» (HTML-страницы), а не на «загрузки файлов» (PDF, zip, Excel и т. Д.). Вам лучше кэшировать их и использовать некоторый идентификатор версии файла где-нибудь в пути URI или строку запроса, чтобы принудительно выполнить повторную загрузку измененного файла. В любом случае, применяя эти заголовки без кэширования к загрузке файлов, остерегайтесь ошибки IE7 / 8 при обработке загрузки файлов по HTTPS вместо HTTP. Подробнее см. IE не может загрузить foo.jsf. IE не смог открыть этот интернет-сайт. Запрашиваемый сайт либо недоступен, либо не найден .