"Cache-Control: max-age=0, no-cache" но браузер обходит запрос сервера (и попадает в кэш)?


Я использую Chrome 40 (так что что-то хорошее и современное).

Cache-Control: max-age=0, no-cache устанавливается на всех страницах - поэтому я ожидаю, что браузер будет использовать что-то из своего кэша, только если он сначала проверил сервер и получил ответ 304 Not Modified.

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

Если я открываю ту же страницу, что и с помощью кнопки Назад, в новой вкладке, то он проверяет сервер (и получает ответ 303 See Other как все изменилось).

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

Я подумал, что могу использовать max-age=0, no-cache как более легкую альтернативу no-store, где я не хочу, чтобы пользователи видели устаревшие данные через кнопку назад (но где данные не являются ценными и поэтому могут быть кэшированы).

Мое понимание no-cache (см. здесь и здесь на SO) заключается в том, что браузер должен всегда пересмотрите все ответы. Так почему же Chrome не делает этого при использовании кнопки Назад?

Является ли no-store единственным вариантом?


200 ответ (из кэша) при нажатии кнопки назад:

Введите описание изображения здесь

303 ответ на запрос той же страницы в новой вкладке:

Введите описание изображения здесь

3 11

3 ответа:

Из http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1

No-cache

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

Если директива no-cache делает это укажите одно или несколько имен полей, после чего кэш может использовать ответ для удовлетворения последующего запроса с учетом любых других ограничений на кэширование. Однако указанные имена полей не должны передаваться в ответ на последующий запрос без успешной повторной проверки на исходном сервере. Это позволяет исходному серверу предотвратить повторное использование определенных полей заголовка в ответе, но при этом разрешить кэширование остальной части ответа.

Кроме того, что следует из названия, no-cache не требует, чтобы ответ не хранился в кэше. Он только указывает, что кэшированный ответ не должен повторно использоваться для обслуживания последующего запроса без повторной проверки, поэтому это сокращенное выражение для must-revalidate, max-age=0.

Это зависит от браузера, что квалифицировать как последующий запрос, и в моем понимании использование кнопки назад не делает. Это поведение варьируется в зависимости от различных браузеров.

no-store запрещает использование кэшированного ответа для всех запросов, и не только для последующих.

Обратите внимание, что даже с помощью no-store RFC фактически разрешает клиенту хранить ответ для использования в буферах истории. Это означает, что клиент все еще может использовать кэшированный ответ, даже если no-store был указан. Последнее поведение охватывает случаи, когда страница была записана с ее оригинальным заголовком в истории браузера. Другой пример использования-поведение различных мобильных браузеров, которые не будут отбрасывать предыдущую страницу до тех пор, пока следующая страница не будет удалена. полностью загружен, поскольку пользователь может захотеть прервать работу.

Для уточнения поведения кнопки назад: она не подчиняется никакому заголовку кэша, согласно http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.13

Агенты пользователей часто имеют механизмы истории, такие как кнопки "Назад" и списки истории, которые можно использовать для повторного отображения сущности, полученной ранее в сеансе. Механизмы истории и кэши различны. Особенно механизмы истории не должны пытаться показать семантически прозрачное представление о текущем состоянии ресурса. Скорее, механизм истории предназначен для точного отображения того, что пользователь видел в момент извлечения ресурса.

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

Это означает, что неуважение к любым заголовкам управления кэшем при использовании кнопки Назад является рекомендуемым поведением. Если Ваш браузер соблюдает заднюю дату истечения срока действия или применяет директиву no-store не только к кэшу браузера, но и к истории, он фактически уже отступает от этой рекомендации.

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

Похоже, что это известная "причуда" в Chrome с использованием кнопки Назад. Есть хорошее обсуждение этого вопроса в отчете об ошибке для него здесь:

Https://code.google.com/p/chromium/issues/detail?id=28035

К сожалению, похоже, что большинство людей вернулись к использованию no-store вместо этого.

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

Вы пробовали использовать полный старый набор заголовков без кэша?

<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />

Это, кажется, работает все время, если вы не запускаете" pushState " web.