Примечание: ниже находится перевод заметки "F5 and XHR deep dive", в которой Steve Souders исследует кэширующее поведение XHR-запросов для различных браузеров. Мои комментарии далее курсивом.
Недавно в заметке Ajax Caching: Two Important Facts из блога HttpWatch было высказано следующее утверждение:
«любые данные, полученные при помощи Ajax, никогда не будут обновлены в IE прежде истечения срока действия кэша, даже если вы форсируете обновление (
Ctrl+F5
). Единственный путь обновить эти данные — это вручную удалить их из кэша.»
Это было весьма обескураживающе для меня, но это оказалось правдой. Если вы нажимаете Перезагрузку (F5), IE перезапросит все ресурсы (даже с неистекшим сроком действия кэша), за исключением XHR. Это может вызвать большое недоумение среди разработчиков при тестировании, но меня заинтересовало, какие еще проблемы существуют в этом направлении. Будет ли поведение аналогичным во всех остальных основных браузерах? Что произойдет, если срок давности кэша будет в прошлом, или заголовок Expires
вообще не будет выставлен? Будет ли какой-либо эффект от добавления Cache-Control max-age
(который переписывает заголовок Expires
)?
Для этого была создана специальная страниц для тестирования кэширования Ajax.
На тестовой странице располагается картинка, внешний скрипт и XMLHttpRequest. Срок действия кэша определяется выбором соответствующей ссылки.
Expires
в прошлом добавляет в ответ заголовки Expires
, который содержит дату на 30 дней ранее текущей, и Cache-Control
с max-age=0
.Expires
вообще не выставляет никаких заголовков Expires
или Cache-Control
.Expires
в будущем добавляет заголовки Expires
, который содержит дату на 30 больше текущей, и Cache-Control
с max-age=2592000
.Тест очень простой: просто перейдите по ссылке (например, Expires
в прошлом), дождитесь полной загрузки, а затем нажимайте F5
. В таблице 1 приведены результаты тестирования этой страницы в основных браузерах. В таблице записано перезапрашивался ли XHR-ресурс или был прочитан из кэша, а также если перезапрашивался, то с каким кодом HTTP-статуса.
Expires в прошлом | Без Expires | Expires в будущем | |
---|---|---|---|
Chrome 2 | 304 | 304 | 304 |
Firefox 3.5 | 304 | 304 | 304 |
IE 7 | 304 | кэш | кэш |
IE 8 | 304 | кэш | кэш |
Opera 10 | 304 | кэш | 304 |
Safari 4 | 200 | 200 | 200 |
Таблица 1. Если кэшируется XHR, что происходит при нажатии F5
?
Ниже приведены мои соображения на тему того, что происходит при нажатии F5
:
Expires
, или же Expires
выставлен в будущее. IE 7&8 не перезапрашивают XHR-ресурс, если нет Expires
или Expires
выставлен в будущее, даже при нажатии Ctrl-F5
. Opera 10 не перезапрашивает XHR-ресурс, если нет Expires
. (Эквивалента для Ctrl-F5
в Opera найти не удалось.)favicon.ico
во всех случаях. (Это выглядит весьма растратно.)If-Modified-Since
во всех случаях. В результате ответ всегда приходит со статус-кодом 200 и включает запрашиваемый ресурс полностью. Это верно как для XHR-ресурса, так и для картинок и внешних скриптов. (Это выглядит неоптимально и отличается от поведения других браузеров.)Ниже я постарался резюмировать свои рекомендации, что следует вынести как веб-разработчикам, так и производителям браузеров из этой ситуации:
Expires
вообще не выставлен.F5
).F5
.favicon.ico
при нажатии F5
.If-Modified-Since
для XHR-ресурсов при нажатии F5
.