Каковы оптимальные HTTP-заголовки, связанные с кэшем, для содержимого, которое может измениться?

У нас есть несколько файлов, которые обслуживаются через HTTP и которые время от времени меняются.

Какие заголовки HTTP, связанные с кэшированием, мы должны вернуть в ответе HTTP, чтобы оптимизировать скорость загрузки браузера, в то же время заставляя браузер проверять наличие последней версии файла?

Мы уже устанавливаем заголовок "Истекает" с датой в прошлом (кажется, на данный момент существует консенсус).

Но тогда некоторые люди рекомендуют установить этот заголовок:

Cache-Control: no-cache, no-store, must-revalidate

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

Если я просто использую:

Cache-Control: no-cache

Затем браузер (по крайней мере, Firefox 14 и Chrome 20) хранит локальную копию, отправляет If-Modified-Since а также If-None-Match заголовки, и сервер возвращает код 304, а содержимое файла не загружается. Это оптимальное поведение для этих файлов, которое может измениться в любое время.

Проблема в том, что я не знаю, достаточно ли просто установки "no-cache", чтобы заставить все браузеры (включая старые, но все еще используемые версии) и прокси-серверы повторно проверять свою локально кэшированную копию с сервером.

Наконец, как насчет Pragma: no-cache заголовок? Должен ли он быть включен в HTTP-ответ тоже?

3 ответа

Документация разработчиков Google содержит отличную документацию по кешированию и предоставляет несколько полезных шаблонов для использования.

Например, у него есть блок-схема для определения оптимальной политики управления кэшем.

Кроме того, он определяет хороший шаблон для добавления отпечатка пальца к файлам и установки срока действия на более длительное время, например, на год.

  • Локально кэшированные ответы используются до истечения срока действия ресурса
  • Внедрение отпечатка содержимого файла в URL-адрес позволяет нам заставить клиента обновиться до новой версии ответа.
  • Каждое приложение должно определить свою собственную иерархию кэша для оптимальной производительности

Возможность определения политик кэширования для каждого ресурса позволяет нам определять "иерархии кэширования", которые позволяют нам контролировать не только продолжительность каждого кэширования, но также и скорость, с которой посетители видят новые версии. Например, давайте проанализируем приведенный выше пример:

  • HTML-код помечен как "без кэширования", что означает, что браузер всегда будет повторно проверять документ при каждом запросе и извлекать последнюю версию, если содержимое изменится. Кроме того, в разметке HTML мы встраиваем отпечатки пальцев в URL для ресурсов CSS и JavaScript: если содержимое этих файлов изменится, то изменится и HTML-код страницы, и будет загружена новая копия ответа HTML.
  • CSS разрешено кэшировать браузерами и промежуточными кешами (например, CDN), и срок его действия истекает через 1 год. Обратите внимание, что мы можем использовать
    "далекое будущее истекает" 1 год безопасно, потому что мы встраиваем файл
    Отпечатайте его имя файла: если CSS обновлен, URL изменится
    также.
  • Срок действия JavaScript также истекает через 1 год, но он помечен как закрытый, возможно, потому что он содержит некоторые личные данные пользователя, которые
    CDN не должен кэшироваться.
  • Изображение кэшируется без версии или уникального отпечатка и истекает через 1 день.

Комбинация ETag, Cache-Control и уникальных URL-адресов позволяет нам предоставлять лучшее из всех миров: долгое время истечения срока действия, контроль над тем, где можно кэшировать ответ, и обновления по требованию.

Лучший способ, возможно, не на 100% соответствующий вашим потребностям:

Cache-Control:max-age=315360000, public
Expires:Tue, 23 Aug 2022 10:53:13 GMT

И дайте файлу "зависимое от содержимого имя файла", такое как stylesheet_v32.css. Как только содержимое изменится, измените имя файла + ссылку на, и браузер получит последнюю версию. Если имя файла остается, браузер не должен запрашивать его.

Это безопасно и согласованно во всех браузерах.

Надеется Cache-Control: no-cache и браузеры, сохраняющие его в любом случае, - это то, что я не хотел бы делать.

Я нашел два способа принудительно перепроверить кеш клиентом:

Cache-Control: max-age=0, must-revalidate
Expires: Thu, 01 Jan 1970 00:00:00 GMT

Это работает по крайней мере с Firefox. Я полагаю, что IE и Chrome также будут правильно реагировать. Он должен работать со старыми браузерами, использующими HTTP/1.0.

С HTTP 1.1 вы можете использовать ETag, В этом случае must-revalidate опция не нужна, потому что ETag достаточно, чтобы клиент реагировал так, как будто must-revalidate был здесь:

Cache-Control: max-age=0
ETag: 123
Expires: Thu, 01 Jan 1970 00:00:00 GMT

Это скажет клиенту создать кеш-версию данных с ETag 123 и перепроверять сервер каждый раз, когда ему нужна копия этих данных. Затем вы можете ответить с 304 Not Modified,

Два варианта, которые вы окончательно не можете использовать: no-cache а также no-store,

Если вы хотите предотвратить кэширование данных промежуточными кешами, обязательно добавьте private к Cache-Control опции.

В качестве интересной функции вы также можете использовать небольшой максимальный возраст, например, несколько минут, чтобы позволить клиенту кэшировать данные за это время, а затем отправить GET на который вы можете ответить 304:

Cache-Control: max-age=300
ETag: 123
Expires: Tue, 29 Mar 2015 15:05:00 GMT

В этом случае браузер не будет проверять новые данные в течение 5 минут. После этого он отправляет вам If-None-Match: 123,

Другие вопросы по тегам