Заголовки кэширования HTTP Cache-Control, ETag и max-age без предположений
Практическое руководство по заголовкам кэширования HTTP для разработчиков веб-сайтов: что на самом деле делают директивы Cache-Control, как ETags инициируют повторную проверку 304, как выбирать TTL, которые выдерживают развертывания, и ошибки, которые делают кэширование вредным, а не полезным.
Каждый HTTP-ответ, который вы отправляете, либо кэшируется, либо не кэшируется — и если вы не проявляете осознанности в этом вопросе, то браузер сам решает за вас. В результате обычно наблюдается смешанный подход: агрессивное кэширование для часто меняющихся ресурсов и полное отсутствие кэширования для редко меняющихся. Оба варианта вредят вашим пользователям.
Этот гайд даёт вам модель мышления, чтобы правильно настроить HTTP-заголовки кэширования в первый раз: что каждый директивный элемент управляет, как ETags инициируют перепроверку, и как выбрать TTL, которые выдерживают деплои без предоставления устаревшего контента.
Как работает кэширование в браузере
Когда браузер запрашивает ресурс, он сначала проверяет свой локальный кэш. Если в нём есть свежий кэшированный копии, он немедленно его предоставляет — без каких-либо сетевых запросов. Если кэшированная копия может быть устаревшей, браузер отправляет условный запрос на источник. Источник либо подтверждает, что ресурс не изменился (304 Not Modified), либо отправляет полный обновлённый ответ (200 OK).
CDN находятся в середине этого жизненного цикла. Они кэшируют ответы ближе к пользователям географически, и они соблюдают те же HTTP-заголовки кэширования — с несколькими CDN-специфичными расширениями, такими как s-maxage.
Три вопроса определяют поведение кэширования:
- Может ли этот ответ быть кэширован вообще? Управляемый
Cache-Control: no-storeилиprivate - На сколько времени он свежий? Управляемый
max-ageилиs-maxage - Как проверяется устаревание? Управляемый ETags или
Last-Modified
заголовки директивы Cache-Control
The Cache-Control заголовок является основным способом объявления политики кэширования. Множество директив разделяются запятыми. Вот что делает каждая из них:
max-age
max-age=N показывает кэшам (браузеру и CDN), на сколько секунд ответ остаётся свежим. Ответ с max-age=86400 считается свежим ровно в течение 24 часов с момента получения. После этого кэш должен перепроверить его перед тем, как снова его предоставить.
Для статических ресурсов с версионными именами файлов (например, main.abc123.js), годовой срок является распространённым: max-age=31536000. Для HTML-документов гораздо более короткий интервал — или вообще отсутствие кэширования — является более безопасным, поскольку HTML ссылается на эти версионные ресурсы.
s-maxage
s-maxage переопределяет max-age только для общих кэшей (CDN, прокси-серверы). Браузер игнорирует это. Это позволяет предоставлять пользователям долговременные кэшированные ответы, при этом сохраняя более свежие кэши на уровне CDN. Типичная схема — браузер кэширует на 1 час, а CDN — на 24 часа. Cache-Control: public, max-age=3600, s-maxage=86400 — браузер кэширует на 1 час, CDN кэширует на 24 часа.
no-cache
no-cache означает не «не кэшировать». Оно означает, что кэш должен перепроверить с источником перед предоставлением сохранённого ответа, даже если он ещё свеж. Ответ кэшируется, но каждый запрос требует одного круга для проверки его актуальности. Это подходит для контента, который часто меняется, но при этом получает выгоду от экономии пропускной способности за счёт ответа 304.
no-store
no-store является единственным директивным элементом, который фактически запрещает кэширование. Ни браузерный кэш, ни CDN, ни запись на диск. Используйте его для ответов, содержащих чувствительные данные пользователей — банковские выписки, медицинские записи, токены. Не используйте его по умолчанию, если вы не продумали вопрос кэширования ещё.
public и private
public является явным разрешением на кэширование в общих кэшах (CDN), даже если запрос имел Authorization заголовке. private ограничивает кэширование только для браузера пользователя — CDN не должны кэшировать его. Для аутентифицированных ответов, которые являются пользовательскими, private предотвращает то, что ответ одного пользователя будет предоставлен другому.
must-revalidate
must-revalidate предотвращает кэшированные ответы от предоставления устаревших данных, когда они не могут достичь источника. Без этого кэш может предоставить устаревший ответ, если сеть недоступна. С этим кэш не может предоставить ответ, если источник недоступен, и возвращает ошибку 504. Используйте это для контента, где предоставление устаревших данных хуже, чем ошибка.
ETags: точная перепроверка
ETag — это идентификатор, сгенерированный сервером для конкретной версии ресурса — можно представить это как отпечаток для тела ответа. Сервер отправляет его в ответ:
ETag: "abc123def456"
Когда кэшированная копия истекает, браузер отправляет условный GET с сохранённым ETag:
If-None-Match: "abc123def456"
Если ресурс не изменился, сервер отвечает с 304 Not Modified и пустым телом — экономя пропускную способность, при этом подтверждая свежесть. Если ресурс изменился, сервер отвечает с 200 OK и новым ETag.
Сильные и слабые ETags
А сильный ETag ("abc123") означает, что ответ идентичен по байтам. Сильный слабый ETag (W/"abc123") означает, что ответы семантически эквивалентны, но могут отличаться в мелких деталях, таких как пробелы или порядок заголовков. Слабые ETags могут генерироваться более эффективно, но не могут использоваться в запросах на диапазоны. Если у вас нет специфических причин для использования слабых ETags, используйте сильные.
Last-Modified: более старший аналог
Перед ETags серверы использовали Last-Modified временные метки для перепроверки. Сервер отправляет:
Last-Modified: Thu, 01 May 2026 12:00:00 GMT
Браузер перепроверяет с помощью:
If-Modified-Since: Thu, 01 May 2026 12:00:00 GMT
Сервер возвращает 304, если ресурс не изменился с того момента, как была отправлена метка.
Недостаток: временные метки имеют разрешение в одну секунду. Файл, изменённый дважды в той же секунде, будет восприниматься как неизменённый. ETags решают эту проблему и являются предпочтительными. Большинство современных фреймворков отправляют оба — браузер использует тот, который доступен, с предпочтением ETags.
Кэширование без нарушения деплоев
Длительный max-age на статическом ресурсе безопасен только в том случае, если URL меняется при изменении содержимого. Существуют два подхода:
Финишинг URL (рекомендуемый)
Включите хэш содержимого файла в имя файла: main.a1b2c3d4.js. Когда файл изменяется, хэш меняется, URL меняется, и браузер получает новый файл — полностью обходя кэш. Устаревший URL остаётся в кэше, но больше не запрашивается, когда HTML ссылается на новый URL.
Webpack, Vite и большинство современных бандлеров делают это автоматически. Эта схема позволяет безопасно установить Cache-Control: public, max-age=31536000, immutable — директива говорит браузеру не беспокоиться о перепроверке, даже если кэшированная запись технически устарела. immutable запроса (менее надёжный)
Добавление версии в URL как параметра запроса (
) технически создаёт другой URL, но некоторые CDN и прокси-серверы игнорируют параметры запроса при формировании ключей кэширования. Финишинг URL в пути является более надёжным и универсально поддерживаемым.main.js?v=1.2.3Общие ошибки, вредящие кэшированию
Кэширование ответов API, которые не должны кэшироваться
JSON-API, возвращающие данные, специфичные для пользователя или зависящие от времени, должны использовать
или как минимум Cache-Control: no-store . Общая ошибка — позволить CDN кэшировать ответ вроде private, no-cacheи предоставлять данные одного пользователя другому. Если ваш API не устанавливает заголовок /api/user/profile , некоторые CDN всё равно кэшируют его, используя гипотезы. Cache-Control Забывание о Vary: Accept-Encoding
Если ваш сервер предоставляет как сжатые, так и несжатые версии ресурса в зависимости от заголовка клиента
, кэш должен хранить отдельные копии для каждого варианта. Без Accept-Encoding , CDN может кэшировать версию gzip и предоставлять её клиенту, который не поддерживает gzip — или наоборот. Всегда устанавливайте его при условном сжатии. Vary: Accept-EncodingИспользование no-cache, когда вы имели в виду no-store
Разработчики часто пишут
когда они хотят полностью запретить кэширование, но Cache-Control: no-cache ещё хранит ответ — он просто требует перепроверки перед каждым использованием. Используйте no-cache когда вы действительно не хотите, чтобы ответ сохранялся в любом месте. no-store Установка max-age на HTML без стратегии кэширования
HTML-документы ссылается на версионные ресурсы. Если вы кэшируете свой HTML с длинным
, пользователи не получат новые имена файлов после деплоя — они будут продолжать работать с старым HTML, который ссылается на старые хэши. Установите короткий TTL (или max-age) на HTML, и оставьте длинные TTL для неизменяемых ресурсов, на которые ссылается HTML. no-cacheРассчитывайте срок действия до запуска
Выбор значения
проще, когда вы можете визуализировать, что это означает в реальном времени. Значение max-age на iotools.cloud позволяет ввести TTL в секундах и увидеть точную дату истечения срока. Полезно для проверки значений, таких как 86400 (24 часа), 2592000 (30 дней) или 31536000 (1 год), до того, как внести их в конфигурацию сервера или правила CDN. Калькулятор TTL / max-age HTTP-кэша Практический чек-лист политики кэширования
HTML-документы:
- — всегда перепроверяются, пользуются 304 при отсутствии изменений
Cache-Control: no-cacheВерсионные статические ресурсы (JS, CSS, изображения с хэшем в имени файла): - Не версионные статические ресурсы (шрифты, иконки):
Cache-Control: public, max-age=31536000, immutable - (1 неделя)
Cache-Control: public, max-age=604800Ответы API (общие, временные): - — короткий TTL в браузере, более длинный TTL в CDN
Cache-Control: public, max-age=60, s-maxage=300Ответы API (пользовательские): - Чувствительные данные:
Cache-Control: private, no-cache - Всегда устанавливайте
Cache-Control: no-store - при предоставлении сжатых ответов при условном сжатии
Vary: Accept-EncodingETags должны быть включены по умолчанию для любого ресурса, который вы кэшируете — они являются механизмом, обеспечивающим эффективное использование пропускной способности при перепроверке. Большинство веб-серверов (Nginx, Apache, Caddy) генерируют ETags автоматически, если вы не отключили их.
ETags должны быть включены по умолчанию для всех кэшируемых объектов — они обеспечивают эффективное использование пропускной способности при повторной проверке. Большинство веб-серверов (Nginx, Apache, Caddy) генерируют ETags автоматически, если вы не отключили их.
Вам также может понравиться
Установите наши расширения
Добавьте инструменты ввода-вывода в свой любимый браузер для мгновенного доступа и более быстрого поиска
恵 Табло результатов прибыло!
Табло результатов — это интересный способ следить за вашими играми, все данные хранятся в вашем браузере. Скоро появятся новые функции!
Подписаться на новости
все Новые поступления
всеОбновлять: Наш последний инструмент was added on Июн 26, 2026
