Управление кешем браузера, динамический контент

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

Установка: статический сервер Apache с обратным прокси-сервером на динамический сервер (mod_perl2) в бэкенде.

Вот URL-адрес запроса для сервера. Он отправляется на динамический сервер, где cookie используется для проверки доступа к изображению:

Заголовки запроса

Host:  <OBSCURED>
User-Agent:  Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.15) Gecko/2009102815 Ubuntu/9.04 (jaunty) Firefox/3.0.15
Accept:  image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset:  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive:  300
Connection:  keep-alive
Referer: <OBSCURED>
Cookie:  pz_cred=4KCNr0RM15%2FJCOt%2BEa6%2BL62z%2Fxvbp2xNQHY5pJw5d6Q
Pragma:  no-cache
Cache-Control: no-cache

Динамический сервер передает изображение обратно на сервер и предоставляет следующий ответ:

Заголовки ответа

Date:  Tue, 24 Nov 2009 04:28:07 GMT
Server:  Apache/2.2.11 (Ubuntu) mod_apreq2-20051231/2.6.0 mod_perl/2.0.4 Perl/v5.10.0
Cache-Control: public, max-age=31536000
Content-Length:  25496
Content-Type:  image/jpeg
Via: 1.1 127.0.1.1:8081
Keep-Alive:  timeout=15, max=75
Connection:  Keep-Alive

Пока все хорошо (мне кажется). Однако при перезагрузке страницы изображение не отображается в кэше, и снова отправляется запрос:

Заголовки запроса

Host: <OBSCURED>
User-Agent:  Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.15) Gecko/2009102815 Ubuntu/9.04 (jaunty) Firefox/3.0.15
Accept:  image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset:  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive:  300
Connection:  keep-alive
Referer: <OBSCURED>
Cookie:  pz_cred=4KCNr0RM15%2FJCOt%2BEa6%2BL62z%2Fxvbp2xNQHY5pJw5d6Q
Cache-Control: max-age=0

Кажется, что запрос не должен происходить, поскольку браузер должен был кэшировать изображение. Как бы то ни было, получен ответ 200, такой же, как и первый, и изображение, похоже, повторно загружено (хотя браузер, похоже, использует кэшированные изображения).

На проблему намекает Cache-Control: max-age=0 в заголовке запроса на перезагрузку выше.

Кто-нибудь знает, почему это происходит? Возможно, причиной проблемы является заголовок Via в ответе?


person Michael Mikowski    schedule 24.11.2009    source источник


Ответы (3)


Исходный запрос имеет

Cache-Control: no-cache

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

В ответе говорится:

Cache-Control: public, max-age=31536000

который сообщает всем, что, что касается исходного сервера, ответ может быть закэширован. Похоже, сервер настроен на кэширование изображения PNG: HTTP 1.1 (раздел 14.21) говорит:

Примечание: если ответ включает поле Cache-Control с директивой max-age (см. раздел 14.9.3), эта директива переопределяет поле Expires.

Ваш второй запрос говорит:

Cache-Control: max-age=0

который сообщает всем промежуточным кешам HTTP, что вы не будете принимать кешированные ответы старше 0 секунд.

Одна вещь, на которую следует обратить внимание: если вы нажмете кнопку «Обновить» в Firefox, вы запросите перезагрузку с исходного веб-сервера. Чтобы проверить кэширование изображения, перейдите со страницы и обратно или откройте ее в новой вкладке. Не уверен, почему вы увидели no-cache в первый раз и max-age=0 во второй раз.

Кстати, мне нравится плагин FireBug для Firefox. Вы можете взглянуть на заголовки запроса и ответа с ним и на все другие полезные вещи.

person Jim Ferrans    schedule 24.11.2009
comment
Привет Джим: Спасибо за вашу помощь! Первый запрос исходит от Firefox, когда я нажимаю Shift-Reload. Это кажется уместным, поскольку я явно прошу свежий контент. И первый ответ тоже кажется правильным; он имеет предполагаемые заголовки. Второй запрос происходит при перезагрузке браузера /без/ смены. Ожидается, что кеш firefox будет учитывать первый ответ, например. максимальный возраст = 31536000. Похоже, сервер говорит, что все изображения (image/*) можно кэшировать. Если все верно, то возникает вопрос, что заставляет FireFox игнорировать директивы кеша? - person Michael Mikowski; 24.11.2009
comment
Должен добавить, в FireFox включен кеш, и он успешно кеширует изображения со статического сервера. Я также удалил заголовки переходов, но не люблю. - person Michael Mikowski; 24.11.2009

Мой предыдущий ответ был правильным лишь частично.

Проблема заключается в том, как FireFox 3 обрабатывает события перезагрузки. Судя по всему, он почти всегда снова запрашивает контент с исходного сервера. Таким образом, заголовок запроса Cache-Control: max-age=0.

Firefox действительно использует кэшированные изображения для отображения страницы при перезагрузке, но затем он по-прежнему отправляет все запросы на их обновление «в фоновом режиме». Затем он заменяет их по мере их поступления.

Поэтому страница отображается быстро, YSlow сообщает о кешированном содержимом. Но сервер все еще прибивается.

Решение состоит в том, чтобы опросить входящие заголовки в сценарии динамического сервера и определить, предоставлен ли заголовок «If-Modified-Since». Если это так и определено, что содержимое не изменилось, возвращается ответ HTTP_NOT_MODIFIED (304).

Это не оптимально — я бы предпочел, чтобы Firefox вообще не выполнял запросы, — но это вдвое сокращает время загрузки страницы и значительно снижает пропускную способность. Учитывая то, как Firefox работает при перезагрузке, это кажется лучшим решением.

Другие комментарии. Замечание Джима Феррана о переходе со страницы и возвращении заслуживает внимания: кэш всегда используется, а запросы не исходят (+1 Джиму). Кроме того, контент, который добавляется динамически (например, вызовы AJAX после начальной загрузки), по-видимому, также использует кеш.

Надеюсь, это поможет кому-то, кроме меня :)

person Michael Mikowski    schedule 30.11.2009

Вроде решил:

  • Убрал прокси через шапку
  • Добавлен заголовок Last-Modified
  • Добавлена ​​дата истечения срока действия в далеком будущем

Firebug по-прежнему показывает 200 ответов от исходного сервера, однако YSlow распознает изображения как кэшированные. По данным YSlow, общий размер загруженного изображения в свежем виде превышает 500 КБ; с загруженным кешем он показывает размер загрузки 0K.

Вот заголовок ответа от сервера Origin, который делает свое дело:

Date: Tue, 24 Nov 2009 08:54:24 GMT
Server: Apache/2.2.11 (Ubuntu) mod_apreq2-20051231/2.6.0 mod_perl/2.0.4 Perl/v5.10.0
Last-Modified: Sun, 22 Nov 2009 07:28:25 GMT
Expires: Tue, 30 Nov 2010 19:00:25 GMT
Content-Length: 10883
Content-Type: image/jpeg
Keep-Alive: timeout=15, max=89
Connection: Keep-Alive

Из-за того, как я запрашиваю изображения, действительно не должно иметь значения, являются ли эти даты статичными; мое приложение знает время последнего мода перед запросом изображения и добавляет его к URL-адресу запроса на стороне клиента, чтобы создать уникальный URL-адрес для каждой версии изображения, например. http://myserver.com/img/125.jpg?20091122 (информация поступает из фида AJAX JSON). Я мог бы, например, сделать дату последнего изменения 01 января 2000 года, а дату истечения срока действия где-то в 2050 году.

Если YSlow верен — а тестирование производительности предполагает, что это так — тогда FireBug должен действительно сообщать об этих попаданиях в локальный кэш вместо ответа 200.

person Michael Mikowski    schedule 24.11.2009
comment
ps я зарегистрировал ошибку с FireBug по сообщенным 200 ответам из локального кеша - person Michael Mikowski; 24.11.2009