# Мониторинг по ETag: заголовок no-cache изменил результаты

Source: https://ipvolt.com/ru/blog/etag-monitoring-cache-control
Markdown: https://ipvolt.com/ru/blog/etag-monitoring-cache-control.md
Language: ru

[ipvolt — главная](https://ipvolt.com/ru.md) / [Блог](https://ipvolt.com/ru/blog.md) / Мониторинг по ETag: заголовок no-cache изменил результаты

Анализ
Опубликовано: 2026-09-11
Обновлено: 2026-09-11
Автор: ipvolt team
6 мин чтения

Живой тест через прокси показал, что один заголовок запроса превратил ответы 304 в полные загрузки. Измеренные байты, политики запросов и воспроизводимые данные.

Прежде чем покупать больше прокси-трафика для монитора контента, проверьте заголовки, которые ваш клиент реально отправляет. На нашем живом сайте добавление `Cache-Control: no-cache` превратило проверки неизменившихся страниц из ответов `304` без тела в полные загрузки с `200`, хотя запросы несли совпадающий ETag.

В контролируемом сравнении **12 условных запросов без этого переопределения передали ноль байт тела ответа; 12 запросов с ним передали 271 968 байт неизменившегося HTML.** Шесть начальных загрузок, нужных для получения ETag, стоили ещё 135 984 байта и включены в опубликованные записи.

Это вывод об одном развёрнутом сайте на Next.js 16.3.4 и конкретной политике запросов. Это не совет убирать требования к свежести из монитора. Полезное решение — менять ли политику клиента, выбрать ли более компактное представление или исследовать поведение ревалидации на сервере.

## Задача: следить за известным контентом, не скачивая его без нужды

Мы тестировали две существующие статьи ipvolt: [руководство по бенчмарку прокси](/ru/blog/what-a-proxy-benchmark-should-measure) и [объяснение ошибок прокси](/ru/blog/proxy-status-codes-407-429-502), каждую в виде HTML и Markdown. Наш монитор следил за заголовком статьи и двумя заданными заголовками разделов. Он также проверял медиатипы, а для HTML — заголовок страницы и канонический URL.

Эти проверки устанавливают, что отслеживаемая информация присутствует. Они не делают Markdown заменой вёрстке, поведению JavaScript или работающему сценарию регистрации. Точные утверждения приведены в [конфигурации исследования](https://ipvolt.com/downloads/content-monitoring/main-study.json).

Сбор шёл через аутентифицированные соединения стороннего прокси с выходом в США, Великобритании и Нидерландах. Начальный эксперимент также включал прямое контрольное соединение. Ответы проверки страны сообщали запрошенные страны на контрольных точках; во время начального прогона для США исходящий адрес менялся, поэтому это наблюдения за маршрутом, а не результаты надёжности фиксированного IP или целой страны. Провайдер соединения не указан; это не был тест доступного прокси-сервиса ipvolt.

Все три HTTP-эксперимента прошли 11 сентября 2026 года. Они выполнили **234 запроса и передали 2 975 066 байт тела ответов**, включая начальные загрузки, проверочные загрузки и неподтвердившиеся гипотезы. Каждый выполненный запрос завершился без транспортной ошибки curl. Дополнительные географические пробы и браузерное QA записаны отдельно в [заметке о методе](https://ipvolt.com/downloads/content-monitoring/method.json); они не входят в этот итог по HTTP-экспериментам.

## Меньшая первая загрузка не ответила на вопрос о кэшировании

Начальный эксперимент последовательно запрашивал gzip и измерял полученные байты тела. По двенадцати начальным наблюдениям на каждое представление размеры были такими:

| Представление статьи | Полученные байты тела на начальный запрос |
| --- | ---: |
| Бенчмарк, HTML | 26 521 |
| Бенчмарк, Markdown | 7 056–7 061 |
| Руководство по ошибкам, HTML | 18 807 |
| Руководство по ошибкам, Markdown | 5 081 |

Обе HTML-точки отдавали ETag. Ни одна из Markdown-точек в этом эксперименте не отдавала валидатор ETag или Last-Modified. Условные проверки HTML без переопределения Cache-Control возвращали `304`; раннер переиспользовал совпадающее, ранее принятое тело, вместо того чтобы трактовать пустой ответ как новый документ.

Разведочный прогон выполнил 144 запроса: 120 полных ответов `200` и 24 принятых ответа `304`. Он пропустил 36 условных слотов, потому что у Markdown не было валидатора или главная страница была помечена `no-store`. Пропущенные запросы не считаются ни успехами, ни нулевыми сетевыми наблюдениями.

Затем мы выполнили по пять последовательных проверок на каждое представление через каждый из трёх прокси-маршрутов. Каждая проверка явно отправляла `Cache-Control: no-cache`, а клиент сохранял подходящие валидаторы между проверками. Все 60 запросов вернули `200`, включая 24 повторные проверки HTML с совпадающим ETag. Ожидание, что повторная валидация HTML позволит не скачивать тело, при этой политике не подтвердилось.

## Выделяем заголовок, который изменил ответ

Для расследования мы зафиксировали URL, конфигурацию маршрута, Accept, язык, предпочтение gzip и точный исходный ETag. Для каждой из шести комбинаций маршрут/статья мы делали один исходный запрос и четыре условных. Порядок был A/B/B/A или B/A/A/B, где A не содержал переопределения Cache-Control, а B отправлял `no-cache`.

| Политика условного запроса | Попытки | Ответы | Полученные байты тела |
| --- | ---: | --- | ---: |
| Совпадающий If-None-Match; без переопределения Cache-Control | 12 | 12 × 304 | 0 |
| Тот же If-None-Match; Cache-Control: no-cache | 12 | 12 × 200 | 271 968 |

Все 24 условных наблюдения совпали с отслеживаемыми значениями и декодированным контентом исходного запроса. С учётом шести исходных запросов этот контролируемый эксперимент передал 407 952 байта тела за 30 запросов. Он использовал сбалансированный порядок, а не случайную выборку, и устанавливает наблюдаемое поведение этих конечных точек в течение этого короткого окна.

Реализация объясняет правдоподобный механизм. Мы сверили реально развёрнутые файлы зависимостей с локальной установкой Next.js 16.3.4: хеши соответствующих исходников совпали. Его хелпер ответа с ETag вызывает `fresh` перед возвратом `304`; встроенная проверка свежести возвращает false, когда запрос содержит `no-cache`, ещё до оценки совпадающего ETag. Отдельный локальный тест функции воспроизвёл ту же ветку. [Хелпер ответа Next.js](https://github.com/vercel/next.js/blob/v16.3.4/packages/next/src/server/send-payload.ts), [реализация fresh](https://github.com/jshttp/fresh/blob/v0.5.2/index.js).

Это поведение, специфичное для стека и согласующееся с живыми результатами. HTTP не определяет `no-cache` как универсальную инструкцию скачать полное тело. И получение `304` не доказывает, что запрос дошёл до origin-сервера, а не до ответившего кэша. [Кэширование HTTP](https://www.rfc-editor.org/rfc/rfc9111.html).

## Полезная оптимизация зависит от нужной вам свежести

Для эксперимента с пятью проверками, который явно использовал `no-cache`, фактические итоги были такими:

| Представление | Запросы, включая начальные загрузки | Полученные байты тела |
| --- | ---: | ---: |
| HTML | 30 | 679 920 |
| Markdown | 30 | 182 070 |
| Разница | Одинаковое число запросов | 497 850 |

**Markdown передал на 73,2% меньше байт тела ответов для отслеживаемого контента при этой политике.** Число запросов он не уменьшил. Это измеренные различия в объёме данных, а не измеренная экономия по счёту и не прогноз месячного трафика. Метрика размера загрузки в curl исключает заголовки и прочие сетевые накладные расходы. [Учёт объёма данных в curl](https://curl.se/libcurl/c/CURLINFO_SIZE_DOWNLOAD_T.html).

Есть и другой вариант, когда требования к свежести это позволяют: Markdown-ответы объявляли `public, max-age=300, must-revalidate`. Кэш может переиспользовать ещё свежее сохранённое представление, не делая запрос. Отсутствие валидаторов не делает его некэшируемым. Наши раннеры намеренно проверяли по сети; они не реализовывали такую политику планирования на основе свежести. [Свежесть и переиспользование](https://www.rfc-editor.org/rfc/rfc9111.html#section-4).

Используйте результат, чтобы выбрать следующее действие:

| Ваше требование к мониторингу | Действие, которое поддерживает этот случай |
| --- | --- |
| Переиспользование в пределах окна свежести сервера допустимо | Оцените локальный кэш с учётом свежести, прежде чем планировать очередную загрузку. |
| Нужно, чтобы отвечающий сервер или кэш валидировал каждую проверку | Протестируйте итоговые заголовки запроса на реальной конечной точке; не считайте, что ETag гарантирует ответ без тела. |
| Нужен отслеживаемый текст, а каждая проверка возвращает полное тело | Сравните сжатый HTML с текстовым или Markdown-представлением, содержащим те же факты. |
| Нужна отрендеренная вёрстка или интерактивный сценарий | Оставьте браузерные проверки; компактное текстовое представление эту задачу не покрывает. |

Не убирайте `no-cache` только ради воспроизведения строки с нулём байт. Две политики заголовков могут иметь разные последствия для свежести. Определите, что ваш монитор должен обнаруживать, а затем измерьте допустимую реализацию.

## Воспроизведите результат и адаптируйте проверку

Скачайте [офлайн-скрипт анализа](https://ipvolt.com/downloads/content-monitoring/reproduce.py) и [очищенные записи](https://ipvolt.com/downloads/content-monitoring/recordings.zip) в один каталог. Достаточно Python 3.10 или новее; эта команда не делает сетевых запросов:

```sh
python3 reproduce.py recordings.zip
```

Она пересчитывает число попыток, итоги по телу, сравнение заголовков и процент для Markdown. Сравните её вывод с [записанным результатом](https://ipvolt.com/downloads/content-monitoring/results.json). Набор данных включает отметки времени, политики запросов, выбранные заголовки ответов, проверки контента и хеши. Учётные данные, исходящие IP-адреса, нефильтрованные заголовки и сырые захваты тела остаются закрытыми; воспроизведение проверяет опубликованную арифметику, а не независимо аутентифицирует исторические ответы.

[Инструкция по скачиванию](https://ipvolt.com/downloads/content-monitoring/README.md) ссылается на точные программы сбора, конфигурации и 27 проходящих офлайн-тестов. Живым программам нужен curl 8.4 или новее; они сохраняют проверку TLS, ограничивают запросы и передачу тела и передают аутентификацию прокси конфиденциально через ввод curl. Их список разрешённых адресов ограничен публичным сайтом из этого случая; адаптируйте и список, и утверждения о контенте под ресурс, которым вы управляете.

Мы не наблюдали реального обновления контента и не измеряли задержку обнаружения. Декодированный контент оставался стабильным для каждой протестированной конечной точки; несколько потоков байт gzip различались при идентичном декодированном тексте. Это повод сравнивать именно тот контент, который важен вашему монитору, а не свидетельство того, что это исследование устранило операционные ложные срабатывания. Это один сайт, две статьи и короткое окно наблюдения — не рейтинг провайдеров и не универсальный бенчмарк кэширования.

*Метод: сбор и анализ с помощью агента, с отдельными проверками свидетельств, редактуры и поиска. Все сообщённые сетевые наблюдения были реально выполнены; офлайн-тесты работают на контролируемых фикстурах и помечены отдельно.*

[Сообщите мне, когда откроется доступ](/ru/blog/etag-monitoring-cache-control#waitlist-blog-end). Одно письмо, когда доступ откроется. Больше ничего.

## Источники

- [RFC 9110: If-None-Match and conditional requests](https://www.rfc-editor.org/rfc/rfc9110.html#section-13.1.2)
- [RFC 9111: request and response cache directives](https://www.rfc-editor.org/rfc/rfc9111.html)
- [curl: downloaded response-body size](https://curl.se/libcurl/c/CURLINFO_SIZE_DOWNLOAD_T.html)
- [Next.js 16.3.4: ETag response handling](https://github.com/vercel/next.js/blob/v16.3.4/packages/next/src/server/send-payload.ts)
- [fresh 0.5.2: request freshness evaluation](https://github.com/jshttp/fresh/blob/v0.5.2/index.js)

## Узнайте, когда откроется доступ к ipvolt.

Пока вы здесь

ipvolt в разработке. Оставьте email, и мы один раз напишем, когда откроется доступ.

Одно письмо, когда откроется доступ. Больше ничего.

[Получить ранний доступ](https://ipvolt.com/ru/blog/etag-monitoring-cache-control#waitlist-blog-end)

[Конфиденциальность](https://ipvolt.com/privacy)


## Похожие статьи

- [Настройка прокси в MostLogin: добавить, проверить, поделиться](https://ipvolt.com/ru/blog/mostlogin-proxy-setup.md) (Анализ, 17 сент. 2026 г., 7 мин чтения): Пошагово добавляем прокси в профили MostLogin: протокол, хост и порт, учётные данные, проверка IP, доступ команды, массовый импорт и ошибки, которые всё ломают.
- [Цены на Amazon: ваш оффер против Featured Offer](https://ipvolt.com/ru/blog/amazon-offer-vs-featured-offer.md) (Анализ, 16 сент. 2026 г., 6 мин чтения): Как сравнивать свой оффер на Amazon с Featured Offer: сопоставленный контекст, известная доставка и протестированная офлайн-модель, сохраняющая отсутствующие данные.
- [Обновления листингов Amazon: «принято» не значит «в продаже»](https://ipvolt.com/ru/blog/amazon-listing-update-reconciliation.md) (Анализ, 14 сент. 2026 г., 7 мин чтения): Как разбирать принятые обновления листингов Amazon: отдельно сверяем отправленные атрибуты, живые офферы, остатки и возможность покупки по практической матрице сверки.

## Связанные руководства

- [Прокси в curl: флаг -x, переменные окружения, SOCKS5, аутентификация](https://ipvolt.com/ru/guides/curl-proxy-setup.md): Как использовать прокси в curl: флаг -x, переменные http_proxy и https_proxy, SOCKS5 через socks5h, аутентификация на прокси и разбор ошибок CONNECT и 407.
- [Прокси в Python Requests: словарь proxies, аутентификация, SOCKS5](https://ipvolt.com/ru/guides/python-requests-proxy.md): Настройка прокси в Python Requests: словарь proxies, значения по умолчанию в Session, учётные данные, SOCKS5 через requests[socks], переменные окружения и ProxyError.
- [Диагностика таймаутов прокси: по одному этапу за раз](https://ipvolt.com/ru/guides/proxy-timeout-troubleshooting.md): Разделяем задержки DNS, TCP, CONNECT, TLS и ответа прокси с помощью таймингов curl, затем задаём дедлайны запросов и решаем, безопасен ли повтор.

## О ipvolt

Технический анализ от команды ipvolt.

Доступ к ipvolt пока не открыт.

[Читать оригинал на английском](https://ipvolt.com/blog/etag-monitoring-cache-control.md)
