2010-06-09 1 views
11

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

Как сообщить хром и сафари, чтобы получить файлы из кеша?

chrome NOK 
safari NOK 
firefox OK 
ie  OK 

Также см. Full page reload on Post/Redirect/Get ignoring cache control на форуме поддержки 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/

Заголовки:

заголовкам я посылаю с изображением являются:

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 часов. Нет Вари: * или что-то в этом роде.

Обновление: Такое поведение является в настоящее время также присутствует в Safari Mobile на прошивкой 4. horible регрессии в скорости загрузки страницы.

Обновление: Существует ошибка об этой проблеме в webkit bugzilla. Bug 38690 - Submitting a POST that leads to a server redirect causes all cached items to redownload

Update: Проблема сохраняется на прошивке 4.0.1

Update: Проблема сохраняется на прошивке 4,1

Update: Проблемы сохраняется на прошивке 4.2

Обновление: Проблемы сохраняется на прошивке 4.2.1 и в Chrome, начиная с версии 6 до 9.

Update: Существует отчет об ошибке по этому вопросу в проекте Chromium.(Вы можете звезда его, чтобы показать вам все равно) Issue 68621: Post/Redirect/Get ignoring cache instructions

Update: Проблема сохраняется в Chrome, начиная с версии 6 до 10. Сейчас это 9 месяцев ошибка.

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

+0

Это проблема webkit, а не конкретная проблема с самим Chrome. –

+0

@ Дань, я знаю, но я ожидаю, что ребята из Google исправит это в одном из своих многочисленных релизов. Доступен патч, но он еще не включен в хром. –

+0

Я думал, что патч вызвал регресс, и почему он не был принят? –

ответ

1

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

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

В файлах ресурсов ресурсов разработчика Chrome, обновленных как у этого, будет время ожидания, но время загрузки 0 мс.

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

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

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

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

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

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

+1

Пользователь не нажимал F5. Браузер ведет себя так, как если бы F5 был нажат после сообщения/переадресации/получения. Я не хочу кэшировать перенаправление, просто статические изображения. –

+0

@ Kristof Neirynck - Ahh, поэтому пост возвращает перенаправление, а страница пингует все статическое содержимое с 304s, но если вы прямо ссылаетесь на него, вы получаете статический контент локально кэшированный? Это похоже на ошибку. Проверьте заголовки ответов на статическом содержимом - некоторые из них (например, Vary: *) вызывают проблемы с кешированием клиентов в некоторых браузерах. Вы можете найти обходной путь там. – Keith

0

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

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

Это справедливо только если содержание страницы не изменяется

+0

Я не толкаю F5. Я делаю пост-перенаправление. –

0

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

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

решение было найдено, после многих дней разочарования в комментарии на this open WebKit bug:

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