web-dev-qa-db-fra.com

Mise en cache des images de site Web avec Apache

Comment puis-je obtenir du contenu statique sur Apache pour qu'il soit {mis en cache par le navigateur} et non {vérifié pour la fraîcheur {à chaque demande}}?

Je travaille sur un site Web hébergé sur le serveur Web Apache. Récemment, je testais quelque chose avec des en-têtes (Content-Type pour différents types de contenu) et j'ai vu beaucoup de demandes conditionnelles d'images. Exemple:

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

Bien que les fichiers image soient à contenu statique et mis en cache par le navigateur, chaque fois qu'un utilisateur ouvre une page qui leur est liée, ils sont sollicités sous condition, auxquels ils envoient "304 non modifié". C'est bien (moins de données transférées), mais cela signifie plus de 20 demandes de plus à chaque chargement de page (chargement de page plus long en raison de tous ces allers-retours, même avec Keep-Alive et le pipelining activé).

Comment dire au navigateur de conserver le fichier existant et de ne pas rechercher de version plus récente?

EDIT: la méthode mod_expires fonctionne, même avec le favicon.

42
Piskvor

Expire module dans Apache résout ce

a2enmod expires

il doit être chargé dans la configuration du serveur et configuré dans .htaccess (ou dans la configuration du serveur).

Avec un en-tête Expires , la ressource n'est demandée que la première fois. Avant la date d'expiration, les demandes suivantes sont satisfaites à partir du cache du navigateur. Une fois le délai spécifié expiré et la ressource nécessaire, ce n'est qu'ensuite qu'elle est à nouveau demandée (conditionnellement - un 304 sera retourné pour une ressource inchangée). Le seul moyen fiable de l'effacer du cache avant son expiration est manuellement ou en forçant une actualisation (généralement Ctrl-F5). (Cela pourrait être un problème si la ressource change entre-temps, mais les images statiques ne changent pas très souvent.)

# 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"

Pour favicon.ico, un peu plus de travail est nécessaire (Apache ne reconnaît normalement pas les fichiers d'icônes Windows et les envoie comme texte/texte par défaut).

# 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"

Et le tour est joué, It Works ™!

56
Piskvor

Avec la directive filesMatch, au lieu de ExpiresByType, vous pouvez regrouper Content-Type en faisant correspondre subtype (par exemple image/*), au lieu de répertorier chaque type/subtype paire, pas subtype (par exemple 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>

Selon cet article Google J'ai expiré au plus tard 1 an (access plus 11 month) et ajouté Cache-Control "public" pour activer la mise en cache HTTPS pour Firefox.

Pour CSS et JS, Google recommande une période d'expiration d'une semaine.

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

Si vous définissez l'en-tête Expires sur votre réponse http pour vos images statiques, votre serveur ne sera pas vérifié à nouveau pour cette image après le premier téléchargement tant que le temps spécifié n'est pas passé, par exemple si je télécharge un fichier depuis votre serveur qui donne son en-tête Expires comme

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

alors mon navigateur ne le recherchera plus depuis votre serveur avant 2010, à moins que j'efface mon cache/fasse un rafraîchissement forcé (Ctrl + F5 sous Windows).

Il y a une introduction simple à la mise en place ici , et une liste d'autres réponses éventuellement utiles sur wikipedia

3
ConroyP

En ce qui concerne favicon.ico, placez-le dans la racine du document de votre serveur, dites/var/www/html et ajoutez-le à /etc/httpd/conf/httpd.conf dans la section Alias: -

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

Ensuite, un seul favicon.ico fonctionnera pour tous les sites hébergés virtuels puisque vous l'aliasez. Après qu'un utilisateur visite votre site, toute autre visite s'appuiera sur la copie de cache du navigateur pendant un mois, et non sur le Web.

Je ne pouvais pas obtenir

ExpiresByType image/ico "access plus 1 month"

travailler du tout. Peut-être qu'il doit être de type texte/simple comme suggéré ci-dessus. Dans tous les cas, ExpiresDefault fonctionne correctement.

2
Anon