Сделать 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;
}
}