Справочник

Код 304 Not Modified: что значит и как работает кэш

304 Not Modified — ресурс не изменился с прошлого раза, и браузер может показать копию из своего кэша. Это не ошибка, а экономия: сервер не пересылает файл заново. 304 приходит только в ответ на «условный» запрос, когда браузер уже хранит копию и спрашивает, не устарела ли она.

Обновлено 07.10.2026≈ 4 мин чтения
Содержание 9

Что означает код 304

Код 304 сервер отправляет в ответ на условный запрос GET или HEAD, если условие не выполнилось, то есть копия у клиента не устарела. Тела у такого ответа нет: клиент берёт данные из своего кэша, как если бы получил их с кодом 200. Заголовки ETag, Cache-Control, Expires, Date, Vary и Content-Location сервер обязан прислать с 304, если прислал бы их с ответом 200.

Как это работает

  1. При первом запросе сервер отдаёт файл с кодом 200 и сообщает его версию: метку в заголовке ETag и время последнего изменения в заголовке Last-Modified. ETag — это метка версии; как её вычислять, решает сервер.
  2. Браузер сохраняет файл в кэше. Когда файл снова нужен, браузер отправляет условный запрос: сохранённую метку — в заголовке If-None-Match, сохранённое время — в If-Modified-Since.
  3. Если файл не изменился, сервер отвечает 304 без тела, и браузер берёт копию из кэша. Если изменился — сервер отдаёт новую версию с кодом 200.

Если в запросе есть оба заголовка, сервер проверяет If-None-Match, а If-Modified-Since не учитывает.

Как nginx отвечает 304

Для файлов, которые nginx отдаёт сам, он присылает Last-Modified и ETag и отвечает 304 на условные запросы — настраивать ничего не нужно. Метку ETag nginx собирает из времени последнего изменения файла и его размера: это два шестнадцатеричных числа через дефис, например "65f1a2b3-1c2d".

  • Директива etag включает и выключает метку ETag для файлов; она есть с версии 1.3.3 и по умолчанию включена.
  • Директива if_modified_since задаёт, как сравнивать время из If-Modified-Since: по умолчанию оно должно точно совпадать со временем изменения файла.

Ответы PHP и приложений за proxy_pass nginx сам на 304 не меняет, если не хранит их в своём кэше: на условные запросы должна отвечать программа сайта.

Как проверить

Узнать метку ETag файла:

curl -I https://example.com/style.css

Отправить условный запрос — в ответ должен прийти 304. Подставьте вместо 65f1a2b3-1c2d метку из ответа на первую команду:

curl -I -H 'If-None-Match: "65f1a2b3-1c2d"' https://example.com/style.css

В браузере то же видно в инструментах разработчика на вкладке Network («Сеть»): у файлов, которые браузер проверил и взял из кэша, в колонке статуса стоит 304.

Почему браузер показывает старую версию файла

Если сервер прислал с файлом заголовки Cache-Control или Expires со сроком хранения, браузер до конца срока вовсе не спрашивает сервер и не получает даже 304 — сразу показывает копию из кэша. Чтобы посетители сразу получили новую версию, меняйте адрес файла при каждом обновлении — например, добавляйте номер версии: style.css?v=2.

304 и поиск Яндекса

По справке Яндекса, ответ 304 стоит отдавать, если документ не изменился с последнего визита робота. Это особенно полезно для статических ресурсов, которые редко меняются, часто запрашиваются и много весят: индексирование идёт быстрее, а трафика расходуется меньше.

Чем 304 отличается от соседних кодов

КодКогда возникает
200Ресурс отдан целиком
206Partial Content: отдана часть ресурса по запросу диапазона
304Ресурс не изменился, клиент берёт копию из кэша
301Тоже код из группы 3xx, но это перенаправление: ресурс переехал навсегда

Источники

Сверено 6 октября 2026 года.

Что почитать дальше

Проверено и обновлено: 07.10.2026