Примечание: ниже находится перевод заметки "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.