Cache-Control
Cache-Control
Поле заголовка HTTP Cache-Control содержит директивы (инструкции) — как в запросах, так и в ответах — которые управляют кэшированием в браузерах и общих кэшах (например, прокси, CDN).
| Тип заголовка | Заголовок запроса, Заголовок ответа |
|---|---|
| Запрещённое имя заголовка | нет |
| Заголовок ответа, разрешённый CORS | да |
Синтаксис
Директивы кэширования следуют приведенным ниже правилам валидации:
- Директивы кэширования не чувствительны к регистру. Однако рекомендуется использовать строчные буквы, так как некоторые реализации не распознают заглавные буквы.
- Несколько директив разделяются запятыми.
- У некоторых директив есть необязательный аргумент.
Директивы кэширования
В следующей таблице перечислены стандартные Cache-Control директивы:
| Запрос | Ответ |
|---|---|
max-age | max-age |
max-stale | - |
min-fresh | - |
| - | s-maxage |
no-cache | no-cache |
no-store | no-store |
no-transform | no-transform |
only-if-cached | - |
| - | must-revalidate |
| - | proxy-revalidate |
| - | must-understand |
| - | private |
| - | public |
| - | immutable |
| - | stale-while-revalidate |
stale-if-error | stale-if-error |
Примечание: Проверьте таблицу совместимости совместимости для их поддержки; агенты пользователя, которые их не распознают, должны игнорировать их.
Словарь
Этот раздел определяет термины, используемые в этом документе, некоторые из которых взяты из спецификации.
(HTTP) cache-
Реализация, которая хранит запросы и ответы для повторного использования в последующих запросах. Это может быть общий кэш или частный кэш.
-
Кэш, существующий между исходным сервером и клиентами (например, прокси, CDN). Он хранит один ответ и повторно использует его с несколькими пользователями — поэтому разработчики должны избегать хранения персонализированного контента для кэширования в общем кэше.
Private cache-
Кэш, существующий в клиенте. Также называется локальным кэшем или кэшем браузера. Он может хранить и повторно использовать персонализированный контент для одного пользователя.
Store response-
Хранение ответа в кэшах, когда ответ кэшируем. Однако кэшированный ответ не всегда повторно используется как есть. (Обычно, «кэш» означает хранение ответа.)
Reuse response-
Повторное использование кэшированных ответов для последующих запросов.
Revalidate response-
Спросить исходный сервер, является ли сохраненный ответ по-прежнему актуальным. Обычно перевалидация выполняется с помощью условного запроса.
Fresh response-
Указывает, что ответ актуален. Это обычно означает, что ответ можно повторно использовать для последующих запросов, в зависимости от директив запроса.
Stale response-
Указывает, что ответ является устаревшим. Это обычно означает, что ответ не может быть повторно использован как есть. Хранение кэша не обязано немедленно удалять устаревшие ответы, так как перевалидация может изменить ответ с устаревшего на актуальный вновь.
Age-
Время с момента создания ответа. Это критерий для определения того, является ли ответ актуальным или устаревшим.
Директивы
В этом разделе перечислены директивы, которые влияют на кэширование — как директивы ответа, так и директивы запроса.
Директивы ответа
max-age
Директива ответа max-age=N указывает, что ответ остаётся свежим до тех пор, пока не пройдёт N секунд после его генерации.
Cache-Control: max-age=604800
Указывает кешам, что они могут сохранить этот ответ и повторно использовать его для последующих запросов, пока он свеж.
Обратите внимание, что max-age — это не время, прошедшее с момента получения ответа; это время, прошедшее с момента генерации ответа на исходном сервере. Таким образом, если другие кеши — на маршруте ответа — хранят ответ в течение 100 секунд (указано с помощью поля заголовка ответа Age), кеш браузера вычтет 100 секунд из своего срока свежести.
Cache-Control: max-age=604800 Age: 100
s-maxage
Директива ответа s-maxage также указывает, как долго ответ остаётся свежим (аналогично max-age) — но она специфична для общих кешей, и они игнорируют max-age при её наличии.
Cache-Control: s-maxage=604800
no-cache
Директива ответа no-cache указывает, что ответ может быть сохранён в кешах, но он должен быть проверен на исходном сервере перед каждым повторным использованием, даже когда кеш отключён от исходного сервера.
Cache-Control: no-cache
Если вы хотите, чтобы кеши всегда проверяли обновления содержимого при повторном использовании сохранённого контента, используйте директиву no-cache. Это делается путем требования проверки каждого запроса в кешах с исходным сервером.
Обратите внимание, что no-cache не означает «не кешировать». no-cache позволяет кешам хранить ответ, но требует его проверки перед повторным использованием. Если вам нужно «не кешировать» в смысле «не хранить», используйте директиву no-store.
must-revalidate
Директива ответа must-revalidate указывает, что ответ может быть сохранён в кешах и может быть повторно использован, пока он свеж. Если ответ становится просроченным, он должен быть проверен на исходном сервере перед повторным использованием.
Обычно must-revalidate используется с max-age.
Cache-Control: max-age=604800, must-revalidate
HTTP позволяет кешам повторно использовать просроченные ответы, когда они отключены от исходного сервера. must-revalidate — способ предотвратить это: сохранённый ответ перепроверяется на исходном сервере или генерируется ответ 504 (Тайм-аут шлюза).
proxy-revalidate
Директива ответа proxy-revalidate эквивалентна must-revalidate, но только для общих кешей.
no-store
Директива ответа no-store указывает, что любые кеши (приватные или общие) не должны хранить этот ответ.
Cache-Control: no-store
private
Директива ответа private указывает, что ответ может быть сохранён только в приватном кеше (например, в локальных кешах браузеров).
Cache-Control: private
Для персонализированного контента следует добавлять директиву private, особенно для ответов, полученных после входа в систему, и для сессий, управляемых с помощью файлов cookie.
Если вы забудете добавить private к ответу с персонализированным контентом, этот ответ может быть сохранён в общем кеше и повторно использован для нескольких пользователей, что может привести к утечке личной информации.
public
Директива ответа public указывает, что ответ может быть сохранён в общем кеше. Ответы на запросы с полями заголовка Authorization не должны храниться в общем кеше; однако, директива public заставит такие ответы храниться в общем кеше.
Cache-Control: public
В общем случае, когда страницы защищены Basic Auth или Digest Auth, браузер отправляет запросы с заголовком Authorization. Это означает, что доступ к ответу контролируется для ограниченных пользователей (у которых есть учётные записи), и он принципиально не является кешируемым, даже если он имеет max-age.
Вы можете использовать директиву public чтобы снять это ограничение.
Cache-Control: public, max-age=604800
Обратите внимание, что s-maxage или must-revalidate также снимают это ограничение.
Если запрос не содержит заголовок Authorization, или вы уже используете s-maxage или must-revalidate в ответе, то вам не нужно использовать public.
must-understand
Директива ответа must-understand указывает, что кеш должен хранить ответ только в том случае, если он понимает требования к кешированию на основе кода состояния.
must-understand должно быть использовано вместе с no-store для поведения по умолчанию.
Cache-Control: must-understand, no-store
Если кеш не поддерживает must-understand, он будет проигнорирован. Если no-store также присутствует, ответ не хранится.
Если кеш поддерживает must-understand, он хранит ответ с пониманием требований к кешированию на основе его кода состояния.
no-transform
Некоторые промежуточные звенья преобразуют контент по разным причинам. Например, некоторые конвертируют изображения, чтобы уменьшить размер передачи.
no-transform указывает, что любое промежуточное звено (независимо от того, реализует ли оно кеш) не должно преобразовывать содержимое ответа.
Примечание: Google Web Light — это один из таких промежуточных элементов. Он преобразует изображения, чтобы минимизировать данные для кеша или медленного подключения, и поддерживает no-transform в качестве опции исключения.
immutable
Директива ответа immutable указывает, что ответ не будет обновляться, пока он свеж.
Cache-Control: public, max-age=604800, immutable
Современная лучшая практика для статических ресурсов — включать версии/хеши в их URL-адреса, но никогда не изменять сами ресурсы — а при необходимости обновлять ресурсы с новыми версиями, которые имеют новые номера/хеши версий, чтобы их URL были другими. Это называется шаблоном cache-busting.
<script src=https://example.com/react.0.0.0.js></script>
При перезагрузке страницы пользователем браузер отправляет условные запросы для проверки на исходном сервере. Однако нет необходимости перепроверять такие статические ресурсы даже при перезагрузке пользователем браузера, так как они никогда не изменяются. immutable сообщает кешу, что ответ является неизменяемым, пока он свеж, и избегает таких ненужных условных запросов на сервер.
Если вы используете шаблон cache-busting для ресурсов и применяете его к длинному max-age, вы также можете добавить immutable чтобы избежать перепроверки.
stale-while-revalidate
Директива ответа stale-while-revalidate указывает, что кеш может повторно использовать устаревший ответ, пока он перепроверяет его в кеше.
Cache-Control: max-age=604800, stale-while-revalidate=86400
В примере выше, ответ свеж в течение 7 дней (604800 секунд). Через 7 дней он становится просроченным, но кеш может повторно использовать его для любых запросов, сделанных в последующий день (86400 секунд), при условии, что он перепроверит ответ в фоновом режиме.
Перепроверка сделает кеш свежим снова, поэтому для клиентов он будет казаться всегда свежим за этот период — в результате задержка перепроверки скрыта от них.
Если за этот период не было запросов, кеш стал просроченным, и следующий запрос перепроверит его обычным образом.
stale-if-error
Директива ответа stale-if-error указывает, что кеш может повторно использовать просроченный ответ, когда исходный сервер отвечает ошибкой (500, 502, 503 или 504).
Cache-Control: max-age=604800, stale-if-error=86400
В примере выше, ответ свеж в течение 7 дней (604800 секунд). Через 7 дней он становится просроченным, но его можно использовать ещё 1 день (86400 секунд), если сервер отвечает ошибкой.
После определённого периода ответ стал просроченным обычным образом. Это означает, что клиент получит ответ об ошибке как есть, если исходный сервер отправит её.
Директивы запроса
no-cache
Директива запроса no-cache просит кеши проверить ответ с исходным сервером перед повторным использованием.
Cache-Control: no-cache
no-cache позволяет клиентам запрашивать наиболее актуальный ответ, даже если в кеше есть свежий ответ.
Браузеры обычно добавляют no-cache к запросам, когда пользователи перезагружают страницу.
no-store
Директива запроса no-store позволяет клиенту запросить, чтобы кеши воздержались от хранения запроса и соответствующего ответа — даже если ответ исходного сервера мог бы быть сохранён.
Cache-Control: no-store
Обратите внимание, что основные браузеры не поддерживают запросы с no-store.
max-age
Директива запроса max-age=N указывает, что клиент разрешает кэширование ответа, сгенерированного на сервере происхождения в течение N секунд — где N может быть любым неотрицательным целым числом (включая 0).
Cache-Control: max-age=3600
В приведенном выше случае, если ответ с Cache-Control: max-age=604800 был сгенерирован более чем 3 часа назад (расчёт производится с учётом max-age и заголовка Age), кэш не смог бы повторно использовать этот ответ.
Многие браузеры используют эту директиву для перезагрузки, как описано ниже.
Cache-Control: max-age=0
max-age=0 является обходным решением для no-cache, так как многие старые реализации кэша (HTTP/1.0) не поддерживают no-cache. В настоящее время браузеры по-прежнему используют max-age=0 для "перезагрузки" — для обратной совместимости — и альтернативно используют no-cache для принудительной перезагрузки.
Если значение max-age не является неотрицательным (например, -1) или не является целым числом (например, 3599.99), поведение кэширования не определено. Однако, в разделе спецификации HTTP «Вычисление срока актуальности» Calculating Freshness Lifetime указано:
Кэши рекомендуется рассматривать ответы с некорректной информацией о свежести как устаревшие.
Другими словами, для любого значения max-age, которое не является целым числом или не является неотрицательным, рекомендованным поведением кэша является обработка значения так, как если бы оно было 0.
max-stale
Директива запроса max-stale=N указывает, что клиент разрешает использование кэшированного ответа, который устарел не более чем на N секунд.
Cache-Control: max-stale=3600
В приведенном выше случае, если ответ с Cache-Control: max-age=604800 был сгенерирован более чем 3 часа назад (расчёт производится с учётом max-age и заголовка Age), кэш не смог бы повторно использовать этот ответ.
Клиенты могут использовать этот заголовок, когда сервер происхождения недоступен или работает слишком медленно, и могут принимать кэшированные ответы из кэшей, даже если они немного устарели.
Обратите внимание, что основные браузеры не поддерживают запросы с max-stale.
min-fresh
Директива запроса min-fresh=N указывает, что клиент разрешает использование кэшированного ответа, который актуален не менее чем на N секунд.
Cache-Control: min-fresh=600
В приведенном выше случае, если ответ с Cache-Control: max-age=3600 был сохранён в кэшах 51 минуту назад, кэш не смог бы повторно использовать этот ответ.
Клиенты могут использовать этот заголовок, когда пользователь требует не только актуальный ответ, но и его отсутствие обновления в течение определённого периода времени.
Обратите внимание, что основные браузеры не поддерживают запросы с min-fresh.
no-transform
Значение такое же, как у no-transform для ответа, но для запроса.
only-if-cached
Клиент указывает, что кэш должен получить уже кэшированный ответ. Если кэш хранит ответ, он используется.
Сценарии использования
Предотвращение сохранения
Если вы не хотите, чтобы ответ хранился в кэшах, используйте директиву no-store.
Cache-Control: no-store
Обратите внимание, что no-cache означает «можно сохранить, но не использовать до проверки» — поэтому это не для предотвращения сохранения ответа.
Cache-Control: no-cache
Теоретически, если директивы конфликтуют, должно быть выполнено наиболее ограничительное правило. Таким образом, приведенный ниже пример практически бессмыслен, поскольку private, no-cache, max-age=0 и must-revalidate конфликтуют с no-store.
# conflicted Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate # equivalent to Cache-Control: no-store
Кэширование статических ресурсов с "cache busting"
При создании статических ресурсов с механизмами версионирования/хеширования добавление версии/хеша в имя файла или строку запроса — хороший способ управления кэшированием.
Например:
<!-- index.html --> <script src="/assets/react.min.js"></script> <img src="/assets/hero.png" width="900" height="400" />
Версия библиотеки React изменится при обновлении библиотеки, а hero.png также изменится при редактировании изображения. Поэтому их сложно хранить в кэше с max-age.
В таком случае можно обратиться к требованиям кэширования, используя определённую, пронумерованную версию библиотеки и включив хеш изображения в URL.
<!-- index.html --> <script src="/assets/react.0.0.0min.js"></script> <img src="/assets/hero.png?hash=deadbeef" width="900" height="400" />
Можно добавить длинное значение max-age и immutable, так как содержимое никогда не будет изменяться.
# /assets/*
Cache-Control: max-age=31536000, immutable
При обновлении библиотеки или редактировании изображения новый контент должен иметь новый URL, а кэши не должны повторно использоваться. Это называется паттерном «cache busting».
Используйте no-cache, чтобы убедиться, что сам HTML-ответ не кэшируется. no-cache может вызвать перепроверку, и клиент правильно получит новую версию HTML-ответа и статических ресурсов.
# /index.html
Cache-Control: no-cache
Примечание: Если index.html контролируется базовой аутентификацией или аутентификацией по Digest, файлы в /assets не сохраняются в общем кэше. Если файлы /assets/ подходят для хранения в общем кэше, вам также нужен один из public, s-maxage или must-revalidate.
Содержание всегда актуальное
Для динамически генерируемого или часто обновляемого статического контента вы хотите, чтобы пользователь всегда получал самую последнюю версию.
Если вы не добавите заголовок Cache-Control, потому что ответ не предназначен для кэширования, это может привести к непредвиденному результату. Кэш может кэшировать его эвристически — поэтому, если у вас есть требования к кэшированию, всегда указывайте их явно в заголовке Cache-Control.
Добавление no-cache к ответу вызывает перепроверку на сервере, поэтому вы можете предоставлять актуальный ответ каждый раз — или, если у клиента уже есть новый, просто отвечайте 304 Not Modified.
Cache-Control: no-cache
Большинство кэшей HTTP/1.0 не поддерживают директивы no-cache, поэтому исторически max-age=0 использовалось как обходное решение. Но только max-age=0 может вызвать повторное использование устаревшего ответа, когда кэши отключены от сервера происхождения. must-revalidate решает эту проблему. Поэтому приведенный ниже пример эквивалентен no-cache.
Cache-Control: max-age=0, must-revalidate
Но сейчас вы можете просто использовать no-cache.
Очистка уже сохранённого кэша
К сожалению, нет директив кэша для удаления уже сохранённых ответов из кэшей.
Представьте, что клиенты/кэши хранят актуальный ответ для пути без запроса к серверу. Сервер ничего не может сделать с этим путём.
В качестве альтернативы Clear-Site-Data может очистить кэш браузера для сайта. Но будьте осторожны: это очищает каждый сохранённый ответ для сайта — и только в браузерах, а не для общего кэша.
Спецификации
| Спецификация |
|---|
| Кэширование HTTP # field.cache-control |
| Неизменяемые ответы HTTP # the-immutable-cache-control-extension |
Совместимость с браузерами
| Рабочий стол | Мобильный | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari на IOS | Samsung Internet | |
Cache-Control |
Да |
12 |
Да |
Да |
Да |
Да |
Да |
Да |
Да |
Да |
Да |
Да |
immutable |
Нет
См. Chromium ошибку 611416.
|
15-79 |
49 |
Нет |
Нет
См. Chromium ошибку 611416.
|
11 |
Нет
См. Chromium ошибку 611416.
|
Нет
См. Chromium ошибку 611416.
|
Нет |
Нет
См. Chromium ошибку 611416.
|
11 |
Нет
См. Chromium ошибку 611416.
|
stale-if-error |
Нет
См. Chromium ошибку 348877.
|
Нет
См. Chromium ошибку 348877.
|
Нет
См. Bugzilla ошибку 995651 комментарий 7.
|
Нет |
Нет
См. Chromium ошибку 348877.
|
Нет |
Нет
См. Chromium ошибку 348877.
|
Нет
См. Chromium ошибку 348877.
|
Нет
См. Bugzilla ошибку 995651 комментарий 7.
|
Нет
См. Chromium ошибку 348877.
|
Нет |
Нет
См. Chromium ошибку 348877.
|
stale-while-revalidate |
75 |
79 |
68 |
Нет |
Нет |
Нет |
75 |
75 |
68 |
Нет |
Нет |
11.0 |
См. также
© 2005–2022 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control