Соотнесите политику с ресурсом, а не с сервером
Сделайте инвентаризацию репрезентативных URL перед изменением заголовков: главная, контентная страница, application shell, CSS, JavaScript, изображения, шрифты, API, вход, аккаунт, корзина и загрузки. Для каждого зафиксируйте, является ли ответ публичным или персонализированным, изменяется ли URL при изменении байтов и как быстро исправление должно дойти до посетителей.
Составьте матрицу политик на основе инвентаризации. Публичному контент-ресурсу с адресом, зависящим от содержимого, нужна иная политика, чем HTML по стабильному адресу. Ответы без Cache-Control всё ещё могут кэшироваться эвристически, поэтому явные правила легче тестировать.
Период, в течение которого сохранённый ответ может быть повторно использован; max-age задаёт его в секундах.
Используйте термины Cache-Control точно
Cache-Control указывает браузерам и общим кэшам, как хранить и повторно использовать ответ. max-age=N разрешает повторное использование, пока ответ свеж. s-maxage=N задаёт время свежести для общих кэшей и переопределяет max-age там; браузеры игнорируют s-maxage. public разрешает хранение в любом кэше; private разрешает кэширование в браузере, но препятствует хранению в общих кэшах.
no-cache допускает хранение, но требует валидации у origin перед повторным использованием. no-store означает, что кэши не должны сохранять ответ, но это не полная мера приватности. Применяйте must-revalidate, когда недопустимо выдавать устаревший контент после истечения срока; при недоступном origin тогда может вернуться 504, а не устаревшая замена.
Он удаляет возможность хранения вместо просто требования проверки; оставьте его для ответов, которые действительно нельзя сохранять.
Версионируйте неизменяемые активы перед назначением долгого срока жизни
URL версионированного ресурса содержит отпечаток содержимого или версию релиза, например app.4f2c.js. Когда байты ресурса меняются, публикуйте другой URL и обновляйте ссылку в HTML. Кэш увидит новый ресурс, и посетители получат новый файл без необходимости инвалидировать каждый браузер.
Для представления, которое не будет меняться в течение срока свежести, практичным паттерном является Cache-Control: max-age=31536000, immutable. immutable подсказывает поддерживающим клиентам не выполнять условную повторную валидацию пока ресурс свеж. Не применяйте его и годичный max-age к изменяемому файлу с тем же URL. Сохраняйте предыдущие fingerprinted-версии активов, пока кэшированный HTML может на них ссылаться.
HTML выбирает URL активов, поэтому последовательность релизов должна сохранять поколение, на которое есть ссылки.
Держите HTML актуальным через валидацию, а не через долгое кэширование
HTML обычно имеет стабильный, удобочитаемый URL и изменяется вместе с содержимым, ссылками на активы, feature-флагами или уведомлениями безопасности. Консервативный публичный паттерн для HTML — Cache-Control: no-cache с ETag и Last-Modified, когда платформа может корректно их генерировать. Браузер сохраняет тело, но перед повторным использованием делает условный запрос; не изменившийся ответ может вернуть 304 Not Modified без тела.
ETag идентифицирует версию ресурса. При устаревшем ответе браузер может отправить его в If-None-Match; если он совпадает, сервер отвечает 304, иначе отправляет новую репрезентацию. Руководства RFC рекомендуют, когда возможно, включать и ETag, и Last-Modified в 200-ответ. no-cache не гарантирует валидацию при навигации «Назад» или «Вперёд», так как браузер может восстановить снимок истории сеанса.
ETag должен меняться при изменении представления; протестируйте его между origin-ами и развертываниями.
Разделяйте публичную доставку и персонализованные/чувствительные ответы
Общий кэш, например CDN, может переиспользовать один ответ для нескольких пользователей. Не допускайте повторного использования аккаунт-специфичного HTML или API-данных между разными пользователями. Для персонализированного контента, который может храниться в браузере, разумная стартовая политика — private, no-cache: она запрещает общее хранение и требует валидации. Наличие Set-Cookie заголовка само по себе не останавливает кэширование.
Для ответов, которые не должны сохраняться, используйте no-store и пересмотрите код приложения, правила CDN, сервис-воркеры, браузерные хранилища, логи и страницы ошибок. Самих заголовков недостаточно для реализации программы приватности, соответствия или безопасности платежей. Привлеките квалифицированных специалистов по безопасности, приватности и платежам для оценки чувствительных потоков и применимых требований.
Тестируйте вход, выход, переключение аккаунтов и изменение прав с тёплыми браузерными и CDN-кэшами.
Разворачивайте изменения кэша как обратимый релиз
Зафиксируйте базовые заголовки и поведение тела для прямых и повторных запросов. В staging разверните сначала версионированные активы, затем HTML, ссылающийся на них, и протестируйте старый кэшированный HTML против нового origin. Проверьте прямой путь к origin и путь через CDN, если оба существуют. В DevTools Network заголовки должны показывать заданную политику и ожидаемое поведение при повторных запросах.
Ведите манифест релиза с URL активов, правилами заголовков и версией конфигурации. Если релиз сочетает несовместимые клиентские файлы, восстановите совместимый HTML и поведение приложения, но не перезаписывайте опубликованный fingerprinted-файл. Перенастройте HTML на известное рабочее поколение и сохраняйте оба поколения, пока кэшированный HTML может к ним обращаться. Удаление из общего кэша (purge) не может заставить все браузеры сбросить свежую копию.
Преобразуйте ошибки тестов заголовков, 404 для активов и несовпадения версий в пункты чеклиста для следующего релиза.
