Chrome не отправляет заголовок if-modified-since на сервер
У меня есть заголовки, которые сервер отправляет клиенту:
Cache-Control: private
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html
Date: Sun, 27 Nov 2011 11:10:38 GMT
ETag: "12341234"
Set-Cookie: connect.sid=e1u...7o; path=/; expires=Sun, 27 Nov 2011 11:40:38 GMT; httpOnly
Transfer-Encoding: chunked
Last-Modified: Sat, 26 Nov 2011 21:42:45 GMT
Я хочу, чтобы клиент проверял, изменился ли файл на сервере, и отправлял "200", если изменений нет, или "304", если файл изменился.
Firefox отправляет такие заголовки:
if-modified-since: Sat, 26 Nov 2011 21:42:45 GMT
if-none-match: "12341234"
Почему Chrome не отправляет такие же заголовки при обновлении страницы? Я ожидаю такое же поведение, как в .NET:
context.Response.Cache.SetCacheability(HttpCacheability.ServerAndPrivate)
5 ответ(ов)
После того как я провел полдня, пытаясь разобраться в этой проблеме, я нашел виновника. Если у вас открыт инспектор объектов в Chrome/дебаггер клиента/монитор сети (то, что появляется при нажатии F12), Chrome не будет отправлять заголовки запроса к кэшу. И точка. (Обновление: в более новых версиях Chrome есть галочка "Отключить кэш"). Даже если у вас не открыта вкладка "Сеть" (например, открыта консоль JavaScript), эта галочка все равно отключает весь кэш.
Это печально, потому что отладка с клиентской стороны заставляет вас оставлять панель сети открытой, чтобы видеть, какие заголовки отправляются и принимаются, и какие коды возвращаются. Без открытой панели сети вы не сможете узнать, кэшируется ли ваш контент с клиентской стороны.
Если вы заглянете в журналы доступа вашего сервера, вы заметите, что ваш сервер возвращает 304 (кэшированный контент) в тот момент, когда вы закрываете окно отладки на вашем клиенте Chrome. Надеюсь, это поможет.
Chrome 24.0.1312.57
Я нашёл одно объяснение такого поведения при использовании HTTPS и хотел бы поделиться своим открытием. Вы не уточнили, запрашиваете ли вы ресурсы по HTTP или HTTPS.
"Правило на самом деле довольно простое: любая ошибка с сертификатом означает, что страница не будет кешироваться."
Ссылка на источник: https://code.google.com/p/chromium/issues/detail?id=110649
Если вы используете самоподписанный сертификат, даже если вы скажете Chrome добавить исключение для него, чтобы страница загрузилась, ресурсы с этой страницы не будут кешироваться, и последующие запросы не будут содержать заголовок If-Modified-Since.
В моем опыте, для эффективного управления кэшированием вам нужно не только устанавливать заголовок "Cache-Control" со значением "Private". Вам необходимо также указать "Max-Age" или "Expires", чтобы заставить Chrome повторно проверять содержимое на сервере.
Имейте в виду, что повторная проверка начнется только после истечения указанных временных значений, поэтому их, возможно, придется установить на небольшое значение.
В дополнение к ответу (https://stackoverflow.com/a/14899869/362780):
Откройте инструменты разработчика (F12) > Параметры (Settings) > Общие (General) > Отключить кэш (Disable cache) (включено, пока открыты инструменты разработчика) - > снимите отметку с этого пункта.
Браузеры действительно проявляют много противоречивого поведения, когда речь идет о кэшировании. Можно ожидать, что если ответ включает дату последнего изменения (last-modified-date), браузер будет заново проверять этот заголовок перед повторным использованием кэша. Но на практике ни один из основных браузеров этого не делает.
Идеальные настройки для вашей ситуации зависят от того, когда вы хотите, чтобы браузер проводил повторную проверку (реалидацию). Для более подробной информации смотрите ссылку ниже.
Не только поведение браузеров может быть неинтуитивным, но и разные браузеры могут вести себя по-разному в одной и той же ситуации, например, когда пользователь нажимает кнопку обновления.
Вы можете ознакомиться с тем, как разные браузеры (Internet Explorer, Edge, Safari, Firefox, Chrome) реагируют на различные директивы кэширования (Etag, last-modified, must-revalidate, expires, max-age, no-cache, no-store) по следующей ссылке: https://gertjans.home.xs4all.nl/javascript/cache-control.html.
Ошибка: запрос слишком велик
Node.js сервер и HTTP/2 (2.0) с использованием Express.js
Как создать HTTP-запрос с куки?
Как задать переменные окружения из файла package.json?
Самый быстрый способ скопировать файл в Node.js