Директива no-cache¶
Директива no-cache — это директива заголовка HTTP-ответа Cache-Control, которая предписывает кэширующим системам (включая браузеры, прокси-серверы и CDN) не использовать сохранённую копию ресурса для ответа на запрос без предварительной проверки её актуальности на исходном сервере. В отличие от директивы no-store, которая полностью запрещает кэширование, no-cache разрешает хранение копии, но обязывает каждый раз отправлять запрос на сервер для валидации (условный запрос с заголовками If-Modified-Since или If-None-Match). Если сервер подтверждает, что ресурс не изменился, он может ответить статусом 304 Not Modified, и кэш может использовать сохранённую копию.
¶Механизм работы
Директива no-cache реализует модель принудительной повторной проверки (forced revalidation). Когда кэш содержит ресурс с директивой no-cache, он не может отдать его пользователю, не проверив на сервере, не устарел ли он. Процесс выглядит следующим образом:
- Пользователь запрашивает ресурс (например, веб-страницу или изображение).
- Кэш (браузер или промежуточный прокси) находит сохранённую копию, но видит в её заголовках
Cache-Control: no-cache. - Кэш формирует условный запрос к серверу, добавляя заголовки:
If-Modified-Since— с датой последнего изменения ресурса из заголовкаLast-Modified.If-None-Match— с ETag-тегом ресурса.
- Сервер сравнивает эти значения с текущим состоянием ресурса. Если ресурс не изменился, сервер отвечает статусом
304 Not Modifiedбез тела ответа. - Кэш получает ответ
304, подтверждает актуальность своей копии и отдаёт её пользователю. - Если ресурс изменился, сервер отвечает полным ответом с новым содержимым и новыми заголовками кэширования.
Таким образом, no-cache не экономит трафик на запросы (они всегда отправляются), но может экономить трафик на передачу тела ответа, если ресурс не изменился.
¶Отличие от других директив
Директива no-cache часто путается с no-store и must-revalidate, однако их поведение принципиально различно.
| Директива | Разрешает хранение в кэше | Обязательная проверка при каждом запросе | Примечание |
|---|---|---|---|
no-cache | Да | Да | Кэш хранит копию, но всегда спрашивает сервер, актуальна ли она. |
no-store | Нет | Не применимо | Кэш не имеет права сохранять ни копию, ни её метаданные. Запрос всегда идёт на сервер. |
must-revalidate | Да | Только после истечения срока жизни (max-age) | Пока ресурс свежий (не превышен max-age), кэш может отдавать его без проверки. После истечения — обязательная проверка. |
max-age=0 | Да | Да (эквивалентно no-cache в некоторых реализациях) | Формально предписывает считать ресурс устаревшим немедленно. На практике поведение близко к no-cache, но может отличаться в деталях. |
Ключевое отличие от must-revalidate в том, что no-cache не использует время жизни (max-age). Ресурс считается устаревшим всегда, независимо от того, сколько времени прошло с момента его получения.
¶Применение
Директива no-cache используется в ситуациях, когда ресурс может меняться часто, но его полная передача при каждом запросе нежелательна из-за объёма данных. Она обеспечивает баланс между актуальностью и производительностью.
¶Динамические веб-страницы
Для страниц, содержимое которых генерируется динамически (например, лента новостей, курс валют, состояние корзины интернет-магазина), no-cache позволяет кэшировать HTML-код шаблона, но при этом гарантировать, что пользователь всегда видит свежие данные. Браузер будет отправлять условный запрос, и если содержимое не изменилось (например, за последние секунды), сервер ответит 304, сэкономив трафик.
¶API-ответы
REST API часто используют no-cache для конечных точек, возвращающих изменяемые данные (например, список товаров, статус заказа). Это позволяет мобильным приложениям и SPA (Single Page Application) кэшировать ответы локально, но при каждом обращении проверять их актуальность. Это снижает нагрузку на сервер по сравнению с no-store и уменьшает задержки для пользователя при неизменных данных.
¶Изображения и медиафайлы
Для изображений, которые могут быть заменены (например, аватар пользователя, баннер), no-cache позволяет браузеру сохранить файл в кэше, но при каждой загрузке страницы проверять, не изменился ли он. Если аватар остался прежним, сервер отвечает 304, и браузер использует локальную копию.
¶Синтаксис и использование
Директива no-cache может применяться как в заголовке ответа сервера, так и в заголовке запроса клиента.
¶В ответе сервера
Сервер включает директиву в заголовок Cache-Control:
`` Cache-Control: no-cache ``
Также можно указать дополнительные параметры, например, no-cache для конкретных полей заголовка (хотя эта возможность редко поддерживается):
`` Cache-Control: no-cache="Set-Cookie" ``
¶В запросе клиента
Браузер или другое клиентское приложение может отправить директиву no-cache в запросе, чтобы указать промежуточным кэшам не отдавать сохранённую копию без проверки:
`` Cache-Control: no-cache ``
Это часто используется при принудительном обновлении страницы (Ctrl+F5 в большинстве браузеров). В этом случае браузер добавляет Cache-Control: no-cache и Pragma: no-cache в запрос, чтобы гарантировать получение свежей версии с сервера.
¶Взаимодействие с другими заголовками
Директива no-cache часто используется совместно с заголовками для условных запросов:
Last-Modified— указывает дату и время последнего изменения ресурса. Используется в условном запросеIf-Modified-Since.ETag— уникальный идентификатор версии ресурса (обычно хеш содержимого). Используется в условном запросеIf-None-Match.
Если сервер не поддерживает условные запросы или не возвращает эти заголовки, то no-cache фактически работает как no-store, так как кэш не сможет выполнить проверку и будет вынужден каждый раз запрашивать полный ответ.
¶Критика и ограничения
- Отсутствие экономии на запросах:
no-cacheне уменьшает количество запросов к серверу. Каждый запрос ресурса приводит к обращению к серверу, что может быть критично для высоконагруженных систем. - Зависимость от серверной логики: эффективность
no-cacheнапрямую зависит от правильной реализации условных запросов на стороне сервера. Если сервер не генерируетETagилиLast-Modified, или делает это некорректно, директива теряет смысл. - Путаница с
no-store: многие разработчики ошибочно используютno-cache, когда хотят полностью запретить кэширование, что приводит к избыточным проверкам и потенциальным проблемам с производительностью. Для полного запрета кэширования следует использоватьno-store. - Поведение в старых браузерах и прокси: некоторые старые реализации HTTP/1.0 не поддерживают
Cache-Controlи полагаются на заголовокPragma: no-cache, который не имеет строго определённого поведения для ответов сервера.
¶Источники
- RFC 7234 — Hypertext Transfer Protocol (HTTP/1.1): Caching
- RFC 9111 — HTTP Caching (обновлённая версия)
- Документация Mozilla Developer Network (MDN) по заголовку Cache-Control
- HTTP: The Definitive Guide (David Gourley, Brian Totty)
