Кеш браузера без устаревших страниц

Разные правила для HTML и файлов с версией в имени.

После релиза читатель видит старый интерфейс, хотя на сервере лежат новые файлы. Часто это не ошибка доставки, а ожидаемое поведение кеша. Браузер использует ранее полученный ответ согласно его заголовкам.

HTML должен узнавать об обновлениях

Для небольшого блога разумная начальная политика — разрешать хранение HTML, но требовать проверки перед повторным использованием.

http
Cache-Control: no-cache

Название сбивает с толку: no-cache не запрещает сохранять ответ. Оно требует валидации перед использованием. При наличии подходящего валидатора сервер может ответить 304, и браузер использует сохранённое тело.

Долгий кеш — для неизменяемых URL

Если сборка выдаёт app.a1b2c3.js и новое содержимое всегда получает новое имя, файл можно кешировать надолго.

http
Cache-Control: public, max-age=31536000, immutable

Не применяйте это правило к app.js, который перезаписывается на каждом релизе. Иначе старый файл может оставаться свежим для браузера очень долго.

Для чувствительных данных

no-store запрещает хранение ответа кешами. private ограничивает хранение приватным кешем, например браузером, и не является запретом кеширования вообще. Выбирайте политику по содержимому ответа.

Проверить отдельно браузер и прокси

Посмотрите Cache-Control, ETag, Age и статус в панели Network. Отключённый кеш в инструментах разработчика меняет условия эксперимента. Сначала проверьте обычную загрузку, затем повторную.

Если перед сервером стоит прокси, у него может быть собственная политика кеширования. Проверяйте заголовки на публичном адресе, а не только напрямую на origin. Запишите ожидаемое поведение для HTML и ресурсов: это поможет разбирать следующий релиз без догадок.

Документация

MDN: HTTP caching ↗