2009-01-15 10 views
40

¿Cómo puedo obtener el contenido estático en Apache para que {almacenado en caché por el navegador} y no {verificado por frescura {con cada solicitud}}?Caché de imágenes del sitio web con Apache

Estoy trabajando en un sitio web alojado en el servidor web Apache. Recientemente, estaba probando algo con encabezados (Content-Type para diferentes tipos de contenido) y vi muchas solicitudes condicionales de imágenes. Ejemplo:

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

Aunque los archivos de imagen son de contenido estático y se almacenan en caché por el navegador, cada vez que un usuario abre una página que enlaza a ellos, se les solicita de forma condicional, a los que mandan "304 Not Modified". Eso es bueno (menos datos transferidos), pero significa más de 20 solicitudes con cada carga de página (carga de página más larga debido a todos los viajes de ida y vuelta, incluso con Keep-Alive y pipelining habilitados).

¿Cómo le digo al navegador que conserve el archivo existente y no busque una versión más nueva?

EDIT: el método mod_expires funciona, incluso con el favicon.

Respuesta

52

Expires módulo en Apache resuelve esto - se debe cargar en la configuración del servidor y configurarlo en .htaccess (o en la configuración del servidor).

Con un encabezado Expires, el recurso solo se solicita la primera vez. Antes de la fecha de vencimiento, las siguientes solicitudes se cumplen desde la memoria caché del navegador. Una vez que expira el tiempo especificado y se necesita el recurso, solo se vuelve a solicitar (condicionalmente, se devolverá un 304 para un recurso no modificado). La única forma confiable de borrarlo de la memoria caché antes de que caduque es manualmente o forzando una actualización (generalmente Ctrl-F5). (Esto podría ser un problema si el recurso cambia mientras tanto, pero las imágenes estáticas no cambian muy a menudo.)

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

Para favicon.ico, se necesita un poco más de trabajo (Apache normalmente no reconoce de Windows archivos de icono, y envía esto como el texto/plano predeterminado).

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

¡Y listo, It Works ™!

+1

he especificado mi favicon tener un tipo MIME "image/x-icon" - y me parece que no puede conseguir Apache para establecer cabeceras Expira en él. ¿Alguna idea de por qué es esto? ¿NECESITO usar image/vnd.microsoft.icon? – Tom

+1

@Tom: "El tipo oficial MIME registrado en IANA para archivos .ICO es image/vnd.microsoft.icon". (Wikipedia) Entonces, NO NECESITA usarlo, pero es del tipo MIME correcto - ¿enviaría "image/x-jpg" con imágenes JPEG en lugar de la "imagen/jpeg" estándar? ¿Existe alguna razón técnica por la que no desee devolver el tipo MIME correcto? – Piskvor

+1

@Tom: en cuanto a la primera pregunta, al servidor no le debe importar cuál es el tipo MIME, siempre que lo sepa. ¿Tiene AddType * antes * ExpiresByType para este tipo MIME? – Piskvor

3

Si configura el encabezado Expires en su respuesta http para sus imágenes estáticas, su servidor no se volverá a verificar para esa imagen después de la primera descarga hasta que haya transcurrido el tiempo especificado, p. Si se descarga un archivo desde el servidor ahora que da es Expires encabezado como

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

entonces mi navegador no lo buscará desde el servidor de nuevo hasta el año 2010, a menos que yo aclaro la cache/hacer una actualización de fuerza (Ctrl + F5 en Windows).

Hay una introducción sencilla a configurar esto here, y una lista de otras respuestas posiblemente más votos en wikipedia

2

En cuanto a favicon.ico, lo puso en la raíz del documento del servidor especificar/var/www/html y añadir esto a /etc/httpd/conf/httpd.conf en la sección 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> 

Entonces una sola favicon.ico funcionará para todos los sitios alojados virtuales, ya que está aliasing ella. Después de que un usuario visite su sitio, cualquier visita adicional se basará en la copia del caché del navegador durante un mes y no desde la web.

no pude conseguir

ExpiresByType image/ico "access plus 1 month" 

trabajar en absoluto. Tal vez tiene que ser tipo texto/simple como se sugiere arriba. En cualquier caso, ExpiresDefault funciona bien.

+0

Buen punto sobre el favicon global, si no te importa que todos los sitios compartan el mismo. Ver mi respuesta re 'image/ico': 1)' image/ico' no es el tipo MIME correcto, 2) necesita definir 'image/vnd.microsoft.icon' - no está predefinido por Apache. – Piskvor

22

con la directiva filesMatch, en lugar de ExpiresByType, puede agrupar Content-Type emparejando subtype (por ejemplo image/*), en lugar de enumerar cada type/subtype par, no subtype (por ejemplo 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> 

Acoording a this Google article hice de vencimiento no superior a 1 año (access plus 11 month) y se añadió Cache-Control "public" para activar la caché HTTPS para Firefox.

Para CSS y JS, Google recomienda un período de caducidad de 1 semana.

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

Me gusta esta respuesta mucho. ¡Gracias por compartir! – KyleFarris

+0

Si necesito tener '', ¿está bien tener una directiva anidada? – Rantiev

Cuestiones relacionadas