Вопрос по – Остановите браузер, чтобы сделать HTTP-запросы для изображений, которые должны оставаться в кэше - mod_expires

44

Прочитав много статей и несколько вопросов здесь, Мне наконец удалось активировать Apachemod_expires сказать браузеру, что он ДОЛЖЕН кэшировать изображения на 1 год.

<code><filesMatch "\.(ico|gif|jpg|png)$">
  ExpiresActive On
  ExpiresDefault "access plus 1 year"
  Header append Cache-Control "public"
</filesMatch>
</code>

И, к счастью, ответы сервера кажутся правильными:

<code>HTTP/1.1 200 OK 
Date: Fri, 06 Apr 2012 19:25:30 GMT 
Server: Apache 
Last-Modified: Tue, 26 Jul 2011 18:50:14 GMT 
Accept-Ranges: bytes 
Content-Length: 24884 
Cache-Control: max-age=31536000, public 
Expires: Sat, 06 Apr 2013 19:25:30 GMT
Connection: close
Content-Type: image/jpeg 
</code>

Ну, я думал, что это остановит браузер для загрузки и даже запросит сервер об изображениях в течение 1 года. Но это отчасти верно: причина если вы закроете и снова откроете браузер, браузер НЕ загружает изображения с сервера больше, но браузер все еще запрашивает у сервера HTTP-запрос для каждого изображения.

Как заставить браузер перестать делать HTTP-запросы для каждого изображения? Даже если за этими HTTP-запросами не следует загружаемое изображение, они все равно являются запросами, направляемыми на сервер что излишне увеличивает задержку и замедляет рендеринг страницы!

Я уже сказал браузеру, что он ДОЛЖЕН хранить изображения в кеше в течение 1 года! Почему браузер все еще запрашивает сервер для каждого изображения (даже если оно не загружает изображение)?!

Смотря на сетевые графики в FireBug (меню FireBug> Net> Images), я вижу различные способы кэширования (я, очевидно, начал с кеша браузера полностью пустым, я принудительно удалил кеш в браузере с помощью «Очистить всю историю»):

Когда страница загружается в первый раз, все изображения загружаются (и то же самое происходит, если я принудительно перезагружаю страницу, нажимая кнопку перезагрузки страницы в браузере).Это имеет смысл

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

Когда я закрываю браузер и снова открываю его на той же странице, глупый браузер в любом случае делает HTTP-запрос к серверу один раз за изображение: он НЕ загружает изображение, но все равно делает HTTP-запрос, это как запрос браузера сервер об образе (сервер отвечает с 200 OK). Это меня раздражает!

Я также прилагаю графики ниже, если вам интересно:

EDIT: только что протестировал и с FireFox 11.0, чтобы убедиться, что мой FireFox 3.6 не слишком старый. Происходит то же самое !!! Я также проверил сайт Google и сайт Stackoverflow, они оба отправляютCache-Control: max-age=... но браузер по-прежнему отправляет HTTP-запрос на сервер для каждого изображения после закрытия и повторного открытия браузера на той же странице, после ответа сервера браузер НЕ загружает изображение (как я объяснил выше), но все равно делает чертов запрос, увеличивающий время просмотра страницы.

EDIT2: и удалениеLast-Modified заголовок как предложеноВо, не решает проблему, это не имеет никакого значения.

Поведение по умолчанию - загрузка, если новее может быть? Tony Hopkinson
@ Тони Хопкинсон: извини, но я скучаю по тебе. Я хочу, чтобы браузер НЕ загружал изображение и даже не опрашивал сервер СНОВА в течение 1 года. Из моего теста кажется, что браузер не загружает изображение снова, но все равно запрашивает сервер. Я ожидаю, что браузер получит изображение из собственного кэша и больше не будет попадать на сервер в течение 1 года. Marco Demaio
@ Tont Hopkinson: но я говорю браузеруExpiresDefault "access plus 1 year" (то естьCache-Control: max-age=31536000) поэтому браузер не должен снова попадать на сервер, запрашивающий / ищущий такой ресурс, я уже сказал ему, чтобы он хранил его в кэше в течение 1 года с момента последнего доступа. Marco Demaio
Стоит отметить, что реальные запросы HTTP выполняются при обновлении браузера, независимо от того, какие заголовки были установлены. сервер по-прежнему будет отвечать 304, и по проводам будет проходить не так много байтов, но вы по-прежнему получаете задержку. при переходе по ссылкам и в противном случае навигация происходит по локальному кешу браузера (без http-запросов). просто что-то, что нужно знать при отладке. neo112
Вот почему то, что ты сделал, работает так, как ты и ожидал? Истекает срок действия удаляется из кэша браузера, не проверяйте, обновлен ли кэш в течение одного года .... Tony Hopkinson

Ваш Ответ

10   ответов
7

используя F5 или F5 + Ctrl, запрос отправляется. Однако если я закрою браузер и снова введу URL-адрес, запрос не будет отправлен. Я проверил, отправлял ли запрос запрос или нет, используя точки останова на начальном запросе на сервере, даже если запрос не отправляется, он все равно обнаруживается в Firebug как ожидание 7 мс, так что будьте осторожны с этим.

Это действительно сработало для меня! Если я принудительно обновлю, используя F5 или F5 + Ctrl, запрос будет отправлен. Однако если я закрою браузер и снова введу URL-адрес, запрос не будет отправлен. Я проверил, отправлял ли запрос запрос или нет, используя точки останова на начальном запросе на сервере, даже если запрос не отправляется, он все равно обнаруживается в Firebug как ожидание 7 мс, так что будьте осторожны с этим. Peter Lundsby
Это не работает, я имею в виду, что это не имеет никакого значения, так как парень правильно прокомментировал ту же статью, Дэвид Меррилис:"Does this work? I've removed both the Etag and Last-Modified headers, and added an expires header, but it always revalidates with 200 response." Marco Demaio
отредактируйте свой ответ, заменив предложение последним комментарием, и я приму ваш ответ. Я даже нашел, что это хорошо объясняет, что вы говорите: / Stackoverflow.com вопросы / 6797361 / ... Marco Demaio
Я выполнил редактирование, которое вы просили Peter Lundsby
6

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

Рассматривая ваши водопады более подробно (что сложно, потому что они немного маленькие и размытые), браузер, кажется, делает именно то, что должен - он Есть записи для изображений - но они просто загружаются из локального кэша не с исходного сервера - проверьте заголовок «Дата» в ответе (почему, как вы думаете, это занимает миллисекунды, а не секунды?). Вот почему они окрашены по-разному.

В точку. Firebug показывает запросы светло-серым цветом, если ответ уже кэширован. Для подтверждения перейдите в Firebug> Net> Запросить URL> Кэш. Посмотрите на счет выборки. Вы должны увидеть приращение этого поля. Sripathi Krishnan
@ symcbean: вы можете легко проверить это поведение, открыв этот сайт Stackoverflow (сервер отправляетCache-Control max-age=604800) поэтому изображение должно храниться в кэше в течение 7 дней. Хорошо, если вы переходите на сайт SO, вы увидите в своей «Firebug> Net», что изображениеhttp:...stackoverflow/img/tag-adobe.png даже не появляется в «Firebug> Net», я предполагаю, что это потому, что изображение взято из кэша. Но если вы закроете браузер и снова откроете его, в «Firebug> Net» вы увидите, что к серверу снова обращаются (серым цветом) по такому изображению, тогда изображение не загружается, но сервер все еще работает. Marco Demaio
@ Marco: если вы мне не верите / firebug, используйте wireshark, чтобы увидеть, что на самом деле отправляется на сервер. symcbean
@ symcbean: но как вы объясните, когда переходите по сайту, не закрывая браузер и не открывайте его снова, Firbug> Net даже не показывает эти жадные запросы? Marco Demaio
Ребята, спасибо, что нашли время ответить. Возможно, мой вопрос слишком длинный. ВЕРНО, что FF берет файл из кэша, но дело в том, что перед этим он связывается с сервером. Сервер отвечает 200 OK, FF не загружает файл и получает его из кэша. Я не удивлен, что FF получает файл из кеша, я удивлен, что FF связывается с 1-м сервером, я уже сказал FF, что срок действия файла не истекаеCache-Control: max-age=31536000, так почему FF продолжает связываться с сервером. Запрос к серверу для каждого изображения добавляет значительную задержку (даже если изображение не загружается Marco Demaio
27

RFC7234 для более подробной информации), указанное поведение:

Все современные браузеры будут отправлять HTTP-запросы на сервер для каждого отображаемого элемента страницы, независимо от состояния кэша. Это было дизайнерское решение, принятое по запросу веб-сервисов (особенно рекламных сетей), чтобы HTTP-серверы могли вести учет каждого отображения каждого элемента.

Если браузеры не отправляют эти запросы, сервер никогда не будет уведомлен о том, что пользователю было показано изображение. Для рекламных сетей это было бы катастрофично. Ранее рекламные сети «взламывали» свой путь, предлагая одно и то же рекламное изображение, используя случайно сгенерированные имена (например, «coke_ad_1_98719283719283.gif»). Однако для интернет-провайдеров эта практика вызвала огромный рост передачи данных, поскольку каждый из их пользователей повторно загружал эти идентичные рекламные изображения, минуя любые кеширующие / прокси-серверы, на которых работал их провайдер.

Так что перемирие было достигнуто: браузеры всегда отправляли HTTP-запросы, даже для не просроченных кэшированных элементов. Серверы будут отвечать с кодами состояния HTTP 304 («не изменено»). Это позволяет серверам регистрировать тот факт, что изображение было показано клиенту. В результате рекламные сетивообщ перестал использовать рандомизированные имена образов для обхода серверов сетевого кэша.

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

Вот почему вы мало что можете сделать, чтобы браузеры не отправляли HTTP-запросы для кэшированных элементов страницы.

Но если вы посмотрите на другие доступные решения на стороне клиента, которые пришли вместе с html5, есть возможность предотвратить загрузку ресурсов

Кэш Манифест (несмотря на свои ошибки) IndexedDB (приятные асинхронные функции, позволяет хранить большие двоичные объекты) Локальное хранилище (не асинхронно)
-1: это совершенно неправильно. Изображение отправлено с правильными заголовками контроля кэшНЕ БУДЕ будет запрашиваться современным браузером до истечения срока действия кэша, за некоторыми исключениями, такими как пользователь принудительно перезагружает страницу. Проблема с рекламой также легко решается, если браузеру не кэшировать изображение. Roman Starkov
... Что меня удивило, так это то, что сервер все равно интересовался, ответив 200 OK. Но, как объяснил Питер Лундсби (и в соответствии с этим Stackoverflow.com / вопросы / 6797361) это, вероятно, просто FireBug, показывающий запрос, но запрос выполняется в браузер CACHE, а не на сервер, поэтому отображается серым цветом. Marco Demaio
Джейсон, у тебя есть ссылки на дополнительную информацию? - Это было очень интересно, я искал что-то вроде этого. KajMagnus
Чтобы повторить то, что сказал @romkyns, если Google и многие другие разработчики не ошибаются при использовании переписывания серверов и номеров версий для предотвращения попаданий на сервер, этот ответ неверен. Chris Middleton
Почему 35 человек высказались против этой полной и легко проверяемой ерунды?вздо Mark Amery
14

Я бы порекомендовал действительно полезный аддон Firefox Живые HTTP-заголовки чтобы вы могли видеть, что на самом деле происходит в сети.

И чтобы быть уверенным, вы можете использовать ssh / putty на вашем сервере и делать что-то вроде

tail -f /var/log/apache2/access.log
Совершенно верно! Используя предложенный вами инструмент, я вижу, что HTTP-запросы не отправляются снова, как предполагалось. Большое спасибо! Я не знаю, почему "FireBug> Net" показывает все те запросы, которые вообще не выполняются !!! Marco Demaio
Это могло бы быть правдой в какое-то время - но моя версия firebug ясно показывает, что кэшированные запрашиваются как серо-белые штриховки. Нет ничего плохого в анализе логов apache, но ничего плохого и в firebug. Ben
4

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

https: //webmasters.stackexchange.com/questions/25342/headers-to-prevent-304-if-modified-since-head-request

0

что вы видите в Chrome, - это не запись реальных HTTP-запросов, а запись запросов активов. Chrome делает это, чтобы показать вам, что ресурс действительно запрашивается страницей. Тем не менее, это представление на самом деле не указывает, выполняется ли запрос. Если ресурс кэшируется, Chrome никогда не создаст базовый HTTP-запрос.

Вы также можете подтвердить это, наведя курсор на фиолетовые сегменты на временной шкале. Кэшированные ресурсы будут иметь(from cache) во всплывающей подсказке.

Чтобы увидеть реальные HTTP-запросы, вам нужно посмотреть на более низкий уровень. В некоторых браузерах это можно сделать с помощью плагина (например, Live HTTP Headers).

В действительности, чтобы убедиться, что запросы на самом деле не выполняются, вам нужно проверить журналы вашего сервера или использовать прокси-сервер отладки, такой как Чарльз или Фиддлер. Это будет работать на уровне HTTP, чтобы убедиться, что запросы на самом деле не выполняются.

11

од на страницу с кнопками «назад» и «вперед» обычно не инициирует новые HTTP-запросы, но, в частности, нажатие клавиши «F5» для «обновления» страницы заставит браузер дважды проверить свой кэш. Это зависит от браузера, но, по-видимому, является нормой для FF и Chrome (то есть для браузеров, которые могут легко отслеживать сетевой трафик). При нажатии клавиши F6 ввод должен фокусироваться на адресной строке URL-адреса, а затем «переходить» к ней, что должно перезагрузите страницу, но не перепроверяйте ресурсы на странице.

Обновит: уточнение поведения навигации вперед и назад. Это называется "Back Forward Cache" или BFCache в браузерах. Когда вы перемещаетесь с помощью кнопок «назад» / «вперед», вы должны точно показать вам, какой была страница, когда вы ее видели на своей временной шкале. При использовании «назад» и «вперед» запросы к серверу не выполняются, даже если в заголовке кэша сервера указано, что срок действия определенного элемента истек.

Если вы видите (200 OK BFCache) на панели вашей сети разработчиков, то сервер никогда не попадал - даже спрашивал if-Modified-Since.

http: //www.softwareishard.com/blog/firebug/firebug-tip-what-the-heck-is-bfcache

Термины «перезагрузка» и «обновление» использовались взаимозаменяемо в пользовательских интерфейсах браузеров в течение многих лет. Я уверен, что в Netscape Navigator 4 была кнопка «Перезагрузить», тогда как в IE 6 была кнопка «Обновить». В каждом случае кнопка отправляла HTTP-запрос на сервер. Кроме этого, я считаю, что ваш ответ правильный. David42
0

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

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

[+] Вы можете запретить браузеру отправлять HTTP-запросы, которые в 99% будут возвращать 304 (не изменено), независимо от того, как сильно пользователь пытается (F5, Ctrl + F5, просто повторное посещение страницы и т. Д.)

[-] Для этого нужно приложить дополнительные усилия для поддержки javascript.

[-] Изображения хранятся в base64 (мы не можем хранить двоичные данные), поэтому они каждый раз декодируются на стороне клиента. Которыйобычн довольно быстро и не так уж и сложно, но это все же требует дополнительного использования ресурсов процессора на стороне клиента и об этом следует помнить.

[-] Локальное хранилище ограничено. Вы можете стремиться использовать ~ 5 МБ данных на домен (Примечание: base64 добавляет ~ 30% к исходному размеру изображения).

[?] При поддержке Большинство браузеров.http: //caniuse.com/#search=localstorag

Приме

Тес

0

Проверка кэша и ответ 304

В ряде случаев Internet Explorer должен проверить, является ли кэшированная запись действительной:

У записи ca, ched нет срока действия, и к контенту обращаются впервые в сеансе браузера

Кэшированная запись имеет срок действия, но он истек

Пользователь запросил обновление страницы, нажав кнопку Обновить или нажав F5

Если кэшированная запись имеет дату последней модификации, IE отправляет ее в заголовке If-Modified-Since сообщения запроса GET:

GET /images/logo.gif HTTP/1.1
Accept: */*
Referer: http://www.google.com/
Accept-Encoding: gzip, deflate
If-Modified-Since: Thu, 23 Sep 2004 17:42:04 GMT
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;)
Host: www.google.com

Сервер проверяет заголовок If-Modified-Since и отвечает соответствующим образом. Если содержимое не изменилось с указанной даты / времени, оно отвечает кодом состояния 304 и ответным сообщением, которое содержит только заголовки:

HTTP/1.1 304 Not Modified
Content-Type: text/html
Server: GWS/2.1
Content-Length: 0
Date: Thu, 04 Oct 2004 12:00:00 GMT

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

Если запрошенный объект фактически изменился с даты / времени в заголовке If-Modified-Since, сервер отвечает кодом состояния 200 и предоставляет измененную версию ресурса.

0

Во на сайте обмена веб-мастерами.

Более подробная информация, которая также упоминается в приведенной выше ссылке, находится на HttpWatch

Согласно статье

В ряде случаев Internet Explorer должен проверить, является ли кэшированная запись действительной:

Кэшированная запись не имеет срока действия, и к контенту обращаются впервые в сеансе браузера Кэшированная запись имеет срок действия, но он истек

Пользователь запросил обновление страницы, нажав кнопку Обновить или нажав F5

введите код сюд

Похожие вопросы