correct HTTP cache validator examples
Build and deploy / deploy (push) Successful in 14s

This commit is contained in:
2026-07-31 10:35:30 +03:00
parent 238c1f7688
commit 368fa96733
2 changed files with 26 additions and 5 deletions
+10 -4
View File
@@ -74,6 +74,12 @@ const rfcValidation = {
note: 'условные запросы, ETag, If-None-Match и ответ 304 как повторная проверка сохранённого представления',
};
const rfcEntityTag = {
title: 'RFC 7232, раздел 2.3: ETag',
url: 'https://www.rfc-editor.org/rfc/rfc7232#section-2.3',
note: 'синтаксис entity-tag и связь валидатора с конкретным представлением ресурса',
};
const rfcVary = {
title: 'RFC 7234, раздел 4.1: Vary',
url: 'https://www.rfc-editor.org/rfc/rfc7234#section-4.1',
@@ -150,7 +156,7 @@ const practiceArticle = createRevision(
'curl -sS -D - -o /dev/null https://example.test/catalog',
'',
'# Затем подставить значение ETag из первого ответа.',
'curl -sS -D - -o /dev/null -H "If-None-Match: catalog-v42" https://example.test/catalog',
"curl -sS -D - -o /dev/null -H 'If-None-Match: \"catalog-v42\"' https://example.test/catalog",
]),
paragraph('Команда выше не доказывает, что ваш CDN использует те же правила, что и браузер. Она делает границу наблюдаемой: на origin или на тестовом домене можно увидеть, поддерживает ли представление условный запрос. Для CDN нужен второй контролируемый путь с той же конфигурацией кэширования. Сравнивать нужно не только код 200 или 304, но и ключевые заголовки на каждом слое.'),
heading('ETag нужен для повторной проверки, а не как украшение'),
@@ -175,7 +181,7 @@ const practiceArticle = createRevision(
'HTML, asset и API требуют разных контрактов, даже если проходят через один домен.',
]),
],
[rfcFreshness, rfcCacheControl, rfcValidation, mdnCaching, nginxHeaders],
[rfcFreshness, rfcCacheControl, rfcValidation, rfcEntityTag, mdnCaching, nginxHeaders],
);
const mechanismArticle = createRevision(
@@ -315,7 +321,7 @@ const fieldArticle = createRevision(
paragraph('Второй тип сбоя выглядит иначе: варианты различаются правильно, но после изменения перевода один из них долго остаётся старым. Здесь проверяем валидатор. Сохраняем ETag русского варианта, ждём или на тестовом стенде настраиваем короткий срок свежести, затем посылаем <code>If-None-Match</code> для того же языка. Если тело не менялось, допустим <code>304</code>; если менялось — ожидаем новый <code>200</code> и новый ETag. Нельзя проверять русский валидатор английским запросом: это уже другой вариант.'),
codeBlock([
'# Значение взять из ответа русского варианта, не подставлять личные токены.',
'curl -sS -D - -o /dev/null -H "Accept-Language: ru" -H "If-None-Match: catalog-ru-v18" https://www.example.test/catalog',
"curl -sS -D - -o /dev/null -H \"Accept-Language: ru\" -H 'If-None-Match: \"catalog-ru-v18\"' https://www.example.test/catalog",
]),
paragraph('Если ответ всегда 200, это не повод отключить кэш. Сначала выясняем, меняется ли ETag на каждом запросе из-за времени, случайного идентификатора или неустойчивого порядка данных. Валидатор должен описывать представление, а не шум вокруг него. Если сервер всегда 304 после реального изменения текста, наоборот, валидатор слишком грубый. Оба случая проверяются на маленьком контролируемом изменении, а не на общей очистке всей зоны.'),
heading('Матрица решения по наблюдению'),
@@ -349,7 +355,7 @@ const fieldArticle = createRevision(
'Небольшой повторяемый сценарий с headers и телом быстрее локализует сбой, чем очистка всего кэша.',
]),
],
[rfcCacheControl, rfcValidation, rfcVary, mdnCaching, mdnVary],
[rfcCacheControl, rfcValidation, rfcEntityTag, rfcVary, mdnCaching, mdnVary],
);
export const revisions = [practiceArticle, mechanismArticle, fieldArticle];