Подтвердить что ты не робот

Кэширование изображений сайта с помощью Apache

Как я могу заставить статический контент на Apache быть {кэширован браузером}, а не {проверено на свежесть {с каждым запросом}}?

Я работаю над сайтом, размещенным на веб-сервере Apache. Недавно я тестировал что-то с заголовками (Content-Type для разных типов контента) и видел много условных запросов на изображения. Пример:

200 /index.php?page=1234&action=list
304 /favicon.ico
304 /img/logo.png
304 /img/arrow.png
(etc.)

Хотя файлы изображений являются статическим содержимым и кэшируются браузером, каждый раз, когда пользователь открывает страницу, которая ссылается на них, они запрашиваются с условием, к которому они отправляют "304 Not Modified". Это хорошо (меньше переданных данных), но это означает еще 20 запросов с каждой загрузкой на странице (более длинная загрузка страницы из-за всех этих раундов, даже если Keep-Alive и конвейерная обработка включены).

Как сообщить браузеру сохранить существующий файл и не проверять более новую версию?

EDIT: метод mod_expires работает даже с значком.

4b9b3361

Ответ 1

Модуль Expires в Apache решает эту проблему

a2enmod expires

его нужно загрузить в конфигурации сервера и настроить в .htaccess (или в конфигурации сервера).

С заголовком Expires ресурс запрашивается только в первый раз. До истечения срока действия последующие запросы выполняются из кэша браузера. По истечении заданного времени и необходимости в ресурсе, только затем он запрашивается снова (условно - возвращается 304 для неизмененного ресурса). Единственный надежный способ удалить его из кэша до его истечения - это вручную или принудительно обновить его (обычно Ctrl-F5). (Это может быть проблемой, если ресурс тем временем меняется, но статические изображения меняются не очень часто.)

# enable the directives - assuming they're not enabled globally
ExpiresActive on

# send an Expires: header for each of these mimetypes (as defined by server)
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"

# css may change a bit sometimes, so define shorter expiration
ExpiresByType text/css "access plus 1 days"

Для favicon.ico требуется немного больше работы (Apache обычно не распознает файлы значков Windows и отправляет его как текст по умолчанию/обычный текст).

# special MIME type for icons - see http://www.iana.org/assignments/media-types/image/vnd.microsoft.icon
AddType image/vnd.microsoft.icon .ico
# now we have icon MIME type, we can use it
# my favicon doesn't change much
ExpiresByType image/vnd.microsoft.icon "access plus 3 months"

И вуаля, это работает ™!

Ответ 2

С директивой filesMatch вместо ExpiresByType вы можете группировать Content-Type, сопоставляя subtype (например, image/*) вместо перечисления каждой пары type/subtype, а не subtype (например, image/jpeg, image/png).

#Set caching on image files for 11 months
<filesMatch "\.(ico|gif|jpg|png)$">
  ExpiresActive On
  ExpiresDefault "access plus 11 month"
  Header append Cache-Control "public"
</filesMatch>

В соответствии с этой статьей Google я сделал срок действия не более 1 года (access plus 11 month) и добавил Cache-Control "public", чтобы включить кеширование HTTPS для Firefox.

Для CSS и JS Google рекомендует использовать срок действия 1 недели.

<filesMatch "\.(css|js)$">
  ExpiresActive On
  ExpiresDefault "access plus 1 week"
  Header append Cache-Control "public"
</filesMatch>

Ответ 3

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

Expires: Fri, 1 Jan 2010 00:00:01 GMT 

то мой браузер не будет искать его с вашего сервера снова до 2010 года, если я не очищу свой кеш/не обновить силу (Ctrl + F5 на окнах).

Здесь есть простое введение в настройку здесь, а также список других возможных полезных ответов в wikipedia

Ответ 4

Что касается favicon.ico, поместите его в свой корневой каталог сервера say/var/www/html и добавьте его в /etc/httpd/conf/httpd.conf в разделе "Псевдонимы": -

Alias /favicon.ico "/var/www/html/favicon.ico"
<Directory "/var/www/html">
    <Files favicon.ico>
       ExpiresActive On
       ExpiresDefault "access plus 1 month"
    </Files>
</Directory>

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

Я не смог получить

ExpiresByType image/ico "access plus 1 month"

работать вообще. Возможно, это должен быть тип text/plain, как было предложено выше. В любом случае ExpiresDefault работает нормально.