Сделать IE для кеширования ресурсов, но всегда повторной проверки

Заголовок элемента управления кэшированием "no-cache, must-revalidate, private" позволяет браузерам кэшировать ресурс, но вызывает повторную проверку с условными запросами. Это работает, как и ожидалось, в FF, Safari и Chrome.

Однако IE7+8 не отправляет условный запрос, то есть в заголовке запроса отсутствует "If-Modified-Since", и, следовательно, сервер отвечает HTTP/200 вместо HTTP/304.

Вот полные заголовки ответа сервера:

Last-Modified: Wed, 16 Feb 2011 13:52:26 GMT
Content-type: text/html;charset=utf-8
Content-Length: 10835
Date: Wed, 16 Feb 2011 13:52:26 GMT
Connection: keep-alive
Cache-Control: no-cache, must-revalidate, private

Это похоже на ошибку IE, но я не нашел ничего связанного в Интернете, поэтому мне интересно, может ли отсутствие или существование другого заголовка вести себя IE странно?

Хорошее обсуждение разницы между no-cache и max-age: в чем разница между Cache-Control: max-age=0 и no-cache?

2 ответа

Решение

В конце концов я понял это. Вот объяснение и проверенное решение.

Следующий сайт подтверждает мои наблюдения: http://blog.httpwatch.com/2008/10/15/two-important-differences-between-firefox-and-ie-caching/

В нем говорится, что IE не хранит локально страницы с директивой no-cache и, следовательно, всегда отправляет безусловный запрос.

Есть также статья поддержки MS - https://support.microsoft.com/help/234067/ которая подтверждает это:

"Internet Explorer поддерживает заголовок HTTP 1.1 Cache-Control, который предотвращает любое кэширование определенного веб-ресурса, если указано значение no-cache..."

Такое поведение не является полностью неправильным - но это не то, что предназначено RFC 2616 (раздел 14.9.1). О "no-cache" говорится: "... кеш НЕ ДОЛЖЕН использовать ответ для удовлетворения последующего запроса без успешной повторной проверки с сервером происхождения". Таким образом, ответ МОЖЕТ быть кэширован, но ДОЛЖЕН повторно проверить его. Основные браузеры, кроме IE, кэшируют ответ и повторно проверяют его. Чтобы предотвратить сохранение запроса, существует директива Cache-Control 'no-store'.

Таким образом, IE обрабатывает "no-cache" как "no-store".

И вот решение для последовательного включения условных запросов для IE и других браузеров:

Не используйте no-cache, но вместо этого установите заголовок Expires в прошлое (или -1, что имеет тот же эффект). IE, как и другие крупные браузеры, будет отправлять условные запросы. (Обратите внимание, вы также должны знать об ошибке заголовка IE Vary, которая препятствует кешированию.)

Это критические поля заголовка:

Last-Modified: Wed, 16 Feb 2011 13:52:26 GMT
Expires: -1
Cache-Control: must-revalidate, private
  • Last-Modified (или ETag) необходим в качестве валидатора
  • Expires -1 говорит о том, что ресурс устарел и должен быть проверен заново
  • Cache-Control не должен содержать no-cache или no-store
   $last_modified = filemtime($_SERVER['SCRIPT_FILENAME']);

   session_cache_limiter(FALSE);

   header("Content-Type: text/css");
   header("Cache-Control: max-age=1, must-revalidate, private");
   header("Last-Modified: " . gmdate("D, d M Y H:i:s", $last_modified) . " GMT");

   if(isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]))
   {
      if(strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]) >= $last_modified)
      {
         header("HTTP/1.1 304 Not Modified");
         exit;
      }
   }
Другие вопросы по тегам