Spec-Zone.ru › HTTP

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

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

Shared cache

Кэш, существующий между исходным сервером и клиентами (например, прокси, CDN). Он хранит один ответ и повторно использует его с несколькими пользователями — поэтому разработчики должны избегать хранения персонализированного контента для кэширования в общем кэше.

Private cache

Кэш, существующий в клиенте. Также называется локальным кэшем или кэшем браузера. Он может хранить и повторно использовать персонализированный контент для одного пользователя.

Store response

Хранение ответа в кэшах, когда ответ кэшируем. Однако кэшированный ответ не всегда повторно используется как есть. (Обычно, «кэш» означает хранение ответа.)

Reuse response

Повторное использование кэшированных ответов для последующих запросов.

Revalidate response

Спросить исходный сервер, является ли сохраненный ответ по-прежнему актуальным. Обычно перевалидация выполняется с помощью условного запроса.

Fresh response

Указывает, что ответ актуален. Это обычно означает, что ответ можно повторно использовать для последующих запросов, в зависимости от директив запроса.

Stale response

Указывает, что ответ является устаревшим. Это обычно означает, что ответ не может быть повторно использован как есть. Хранение кэша не обязано немедленно удалять устаревшие ответы, так как перевалидация может изменить ответ с устаревшего на актуальный вновь.

Age

Время с момента создания ответа. Это критерий для определения того, является ли ответ актуальным или устаревшим.

Директивы

В этом разделе перечислены директивы, которые влияют на кэширование — как директивы ответа, так и директивы запроса.

END_OF_DOCUMENT_MARKER

Директивы ответа

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.

END_OF_DOCUMENT_MARKER

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

См. также

  • Кэширование HTTP
  • Учебник по кэшированию для авторов и веб-мастеров
  • Рекомендации по кэшированию и ловушки max-age
  • Cache-Control для простых пользователей
  • RFC 9111 — Кэширование HTTP
  • RFC 5861 — Расширения HTTP Cache-Control для устаревших данных
  • RFC 8246 — Неизменяемые ответы HTTP

© 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API