Подтвердить что ты не робот

Полная перезагрузка страницы в Post/Redirect/Get игнорировать управление кешем

У меня есть страница, которая загружает много изображений, css и javascript. Я добавил длинный заголовок Expires будущего и назначил Cache-Control публике на эти внешние зависимости, чтобы они были кэшированы. Но каждый раз, когда я делаю Post/Redirect/Get chrome, он пытается загрузить их снова. Такое поведение очень похоже на перезагрузку страницы. Я добавил ETags и обрабатываю заголовок If-None-Match, который помогает немного, но он по-прежнему генерирует слишком много бесполезных запросов.

Как сообщить chrome и safari для получения файлов из кеша?

chrome   NOK
safari   NOK
firefox  OK
ie       OK

Также см. Полная перезагрузка страницы Post/Redirect/Get игнорировать управление кешем на форуме поддержки google.

Разъяснение:

Я не хочу, чтобы браузер дважды запрашивал image1.png. Он должен быть кэширован.

200 GET  page1.html
200 GET  image1.png (Cache-Control: public, Expires and ETag)
302 POST action.asp (form submitted from page1.html, redirects)
200 GET  page2.html
304 GET  image1.png (If-None-Match)

Пример:

Я создал простой пример, чтобы проиллюстрировать проблему.

http://crydust.be/lab/prg/

Headers:

Заголовки, отправленные с изображением, следующие:

HTTP/1.1 200 OK
Date: Fri, 18 Jun 2010 11:30:22 GMT
Server: Apache
Cache-Control: public, max-age=86400
Expires: Sat, 19 Jun 2010 11:30:24 GMT
Etag: "123"
Content-Length: 866
Content-Type: image/png

Который должен сделать его кэшированным в течение 24 часов. Нет Vary: * или что-то в этом роде.

Update: Это поведение теперь также присутствует в Safari Mobile на iOS 4. Горит регрессия скорости загрузки страницы.

Update: В этой статье есть проблема с этой ошибкой в ​​webkit bugzilla. Ошибка 38690 - Отправка POST, которая приводит к перенаправлению сервера, заставляет все кэшированные элементы перезагружать

Update: Проблема сохраняется в iOS 4.0.1

Update: Проблема сохраняется в iOS 4.1

Update: Проблема сохраняется в iOS 4.2

Update: Проблема сохраняется в iOS 4.2.1 и в Chrome с версии 6 до 9.

Update: В проекте Chromium есть ошибка в этом вопросе. (вы можете показать его, чтобы показать вам заботу) Проблема 68621: Сообщение/Перенаправление/Не игнорируйте инструкции кэша

Update: Проблема сохраняется в Chrome с версии 6 до 10. Теперь это ошибка 9 месяцев.

Update: Проблема исправлена ​​с 2011-03-21 19:33:07 PST. Это отражено в поведении хрома 12 (канарейка).

4b9b3361

Ответ 1

Когда вы F5/обновляетесь в Chrome, Safari или IE8, все ресурсы GET запрашиваются снова, даже если они были кэшированы.

Если вы посмотрите запрос/ответ с помощью инструментов dev или Fiddler, вы увидите, что сервер отвечает статусом HTTP 304 и содержимым. Это говорит браузеру, что им не нужно загружать его снова и что они могут продолжать использовать кеш.

В инструментах вкладки "Ресурсы ресурсов Chrome" утилиты "Ресурсы ресурсов", обновленные как таковые, будут иметь время ожидания, но время загрузки 0 мс.

Если вы перезагрузите страницу, оставив и вернув, вы обнаружите, что эти кэшированные файлы не будут восстановлены снова, а сервер не будет проверен.

Это поведение F5/refresh для статического ресурса GET верное - это FX и IE6, которые делают это неправильно. Это также помогает с запутанной командой CTRL + F5, о которой большинство пользователей не знают.

Вы не можете кэшировать POST или страницы, которые возвращают временное перенаправление HTTP:

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

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

Вы должны иметь возможность кэшировать 301 постоянную переадресацию, но временные переадресации 302 или 303 не должны кэшироваться в соответствии со спецификацией HTTP.

Ответ 2

F5 перезагружает все ресурсы страниц в некоторых браузерах, поэтому они игнорируют заголовки кеша и снова запрашивают каждый ресурс.

Если вы хотите "кэшировать" страницы POST, вам нужно преобразовать эти страницы в статические ресурсы, т.е. создать файл .html из .php, например, а затем передать .html в качестве статического ресурса.

Это действительно ТОЛЬКО, если содержимое страницы не изменяется

Ответ 3

Исправление: cache-control: no-store

(Вы также можете использовать код состояния 307 вместо 302, который сохранит этот метод.)

Решение было найдено после многих дней разочарования - в комментарии этой открытой ошибки WebKit:

CachedRawResource теперь сохраняет цепочку перенаправления и имеет некоторую тривиальную логику для проверки правильности, но она нигде не близка к завершению (только проверяет cacheControlContainsNoStore()). И, конечно, у других типов ресурсов ничего нет.