Код 304 Not Modified: страница не изменилась
Код 304 Not Modified не ошибка. Так сервер отвечает на условный запрос и сообщает, что ресурс не менялся с момента последней загрузки, поэтому тело ответа не передаётся и браузер берёт копию из своего кеша.
Обновлено 11 октября 2026 г.
Что значит код 304
RFC 9110 (раздел 15.4.5) описывает 304 как ответ на условный GET или HEAD, когда ресурс не изменился. Условным запрос становится, если клиент прислал заголовок If-None-Match (со значением ETag) или If-Modified-Since (с датой последней загрузки). Сервер сравнивает и, если версия актуальна, отвечает 304 без тела. Это экономит трафик и ускоряет загрузку.
GET /style.css HTTP/1.1
Host: example.com
If-None-Match: "5e3f-6a1b"
If-Modified-Since: Tue, 06 Oct 2026 10:00:00 GMT
HTTP/1.1 304 Not Modified
ETag: "5e3f-6a1b"
Cache-Control: max-age=2592000В 304-ответе нет тела, но сервер должен повторить заголовки, влияющие на кеширование (ETag, Cache-Control, Expires, Vary), чтобы клиент мог обновить сохранённую копию.
Как устроено кеширование: Cache-Control, ETag, Last-Modified
| Заголовок | Что делает |
|---|---|
Cache-Control: max-age=N | пока копия «свежая» (N секунд), браузер вообще не обращается к серверу |
ETag | идентификатор версии ресурса; браузер возвращает его в If-None-Match |
Last-Modified | дата изменения; браузер возвращает её в If-Modified-Since, точность до секунды |
Vary | по каким заголовкам запроса отличаются версии ответа (например, Accept-Encoding) |
Порядок такой: пока срок хранения не истёк, запроса к серверу нет. Когда истёк, браузер отправляет условный запрос, и сервер отвечает либо 304 (копия остаётся и срок продлевается), либо 200 с новой версией. ETag надёжнее даты, потому что различает изменения внутри одной секунды и не зависит от часов. «Слабый» ETag (с префиксом W/) говорит о смысловой, а не побайтовой эквивалентности, и для условных GET этого достаточно.
Что делать посетителю
Ничего: 304 видят только в инструментах разработчика (вкладка Network), и пользователь получает обычную страницу. Если сайт показывает устаревшее содержимое, обновите страницу с очисткой кеша (Ctrl+F5 или Cmd+Shift+R) либо очистите кеш браузера для этого сайта.
Что делать владельцу сайта
Задача владельца обратная: сделать так, чтобы 304 отдавался там, где контент не менялся (статика, картинки, страницы с редким обновлением), и не отдавался там, где менялся.
location /static/ {
etag on; # включено по умолчанию
if_modified_since exact; # значение по умолчанию
expires 30d;
}FileETag MTime Size
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/webp "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
</IfModule>Директива FileETag MTime Size исключает из ETag inode файла, который различается на разных серверах и ломает условные запросы на кластере. Для динамических страниц и API валидатор нужно формировать в приложении:
app.get("/api/catalog", (req, res) => {
const etag = '"' + catalogVersion + '"';
if (req.headers["if-none-match"] === etag) {
return res.status(304).set("ETag", etag).end();
}
res.set("ETag", etag).json(getCatalog());
});Express по умолчанию сам считает ETag для ответов res.send и res.json и отвечает 304, если клиент прислал совпадающий If-None-Match, так что ручная логика нужна не всегда.
Когда 304 говорит о проблеме
- Контент изменился, а сервер всё равно отдаёт 304. Ищите кеш на уровне CDN, прокси или плагина кеширования, который не сбрасывается при обновлении.
- 304 на запрос без условных заголовков. Это нарушение протокола: сервер без
If-None-MatchиIf-Modified-Sinceдолжен вернуть 200 с телом. - ETag меняется на каждый запрос. Тогда 304 не срабатывает вообще, и клиент каждый раз скачивает файл заново.
304 и поисковые роботы
Google поддерживает условные запросы: Googlebot может присылать If-None-Match и If-Modified-Since, и ответ 304 говорит роботу, что страницу перескачивать не нужно. Для Google 304 означает, что содержимое осталось прежним, а страница не исчезает из индекса. Яндекс тоже обрабатывает If-Modified-Since: робот не перескачивает неизменённую страницу, и на большом сайте это снижает нагрузку на сервер. Важно только отдавать 304 честно: если страница изменилась, а сервер сообщает о неизменности, обновление в поиске задержится.
Как проверить
# смотрим валидаторы
curl -sI https://example.com/style.css | grep -iE "^(etag|last-modified|cache-control)"
# повторяем запрос с подставленным значением ETag из ответа выше
curl -sI -H 'If-None-Match: "5e3f-6a1b"' https://example.com/style.cssВторой запрос должен вернуть 304 Not Modified. Код главной страницы и цепочку редиректов проверит онлайн-инструмент. Браузерный способ: DevTools → Network, столбец Status.
Частые вопросы
Что значит ошибка 304 Not Modified?
Это не ошибка. Сервер сообщает, что ресурс не изменился с прошлой загрузки, и браузер использует копию из кеша.
Как убрать код 304?
Убирать его не нужно: он помогает экономить трафик. Если сайт показывает устаревшие данные, очистите кеш браузера, а на сервере проверьте настройки кеша CDN и плагинов.
Влияет ли 304 на SEO?
Положительно или нейтрально: роботу не нужно перескачивать неизменённые страницы, и он тратит ресурсы на обход нового контента. Главное, чтобы 304 не отдавался для изменившихся страниц.
Чем 304 отличается от 200?
При 200 сервер передаёт ресурс целиком, а при 304 только заголовки. Тело берётся из кеша клиента.