2010-06-29 42 views
14

Tengo una lista de elementos, que también contiene una imagen en miniatura. A veces necesito cambiar la imagen en miniatura, pero mantener el nombre del archivo igual. ¿Hay alguna manera de forzar al navegador a descargar la imagen recién cargada, en lugar de tomar una de la memoria caché del navegador?¿Cómo borrar la caché del navegador al volver a cargar la imagen con el mismo nombre de archivo, en php?

Esto es muy pertinente cuando las personas actualizan sus avatares, lo que causa confusión para algunos usuarios, que siguen viendo su antiguo avatar, hasta que borran el caché del navegador o reinician el navegador.

Respuesta

2

Puede invalidar el caché para una página entera al alterar la headers:

<?php 
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past 
?> 
+2

Esto, lamentablemente hace imposible el almacenamiento en caché del archivo, lo que aumenta el tiempo de carga de la página y el costo del ancho de banda. –

+3

Entonces solo hazlo después de una carga? –

1

Al enviar la imagen, asegúrese de no enviar ningún encabezado Expires. También considere enviar este encabezado de caché:

Cache-Control: must-revalidate 

Esto hará que el navegador pregunte a su servidor la imagen cada vez. Esté atento a un encabezado If-Modified-Since en la solicitud; si la imagen no se modifica, responda con un código HTTP 304.

Este procedimiento completo (debe revalidar, If-Modified-Since, 304 answer) hará posible que el navegador guarde en caché el contenido de la imagen pero, al mismo tiempo, pregunte a su servidor si el archivo ha cambiado.


Otro, quizás más simple, la solución es única establecer una cabecera Expires un breve periodo de tiempo en el futuro , por ejemplo, diez minutos, e informar al usuario de la demora de diez minutos. Esto acelerará la mayoría de las cargas de página, ya que no es necesario realizar ninguna solicitud HTTP para la imagen.

+0

¿Qué quiere decir con "al enviar la imagen"? Después de subir una imagen, y uso el encabezado ("Ubicación: whatever.php"); ? –

+0

No, me refiero a cuando alguien solicita el archivo de imagen, es decir, hace una solicitud HTTP para /example/image.jpg –

5

Se puede utilizar el tiempo de modificación del archivo:

<? 

$filename = 'avatar.jpg'; 
$filemtime = filemtime($filename); 

echo "<img src='".$filename."?".$filemtime."'>"; 

//result: <img src='avatar.jpg?1269538749'> 

?> 

cuando se modifica el archivo se borrará la caché del cliente

+0

No es posible en muchos casos debido a la naturaleza en caché del código HTML. –

+0

puede decirme qué casos? – Leo

+0

Donde un caché generó código HTML en el DB, que se actualiza una vez cada pocos días –

25

Anexar un número único al final de la imagen src

es decir,

<?php 

echo "<img src=../thumbnail.jpg?" . time() . ">"; 

haz esto solo en el formulario para la actualización de avatar

funciona para mí

por cierto, esto funciona bien para forzar actualizaciones de otros archivos estáticos

es decir html para archivos CSS es

<link rel="Stylesheet" href="../css/cssfile.css?<?= md5_file('cssfile.css'); ?>" /> 
+0

Tenga en cuenta que el cálculo de md5 requiere una gran cantidad de potencia de procesamiento. Sería mejor usar 'filemtime()'. – oriadam

0

imágenes almacenadas en caché también se invalidan en la página de actualización manual (presionando F5 en el navegador). Esto se puede simular con el método Javascript location.reload() que se activa en la carga corporal. Para evitar la recarga perpetua, esto puede ocurrir solo una vez. Cuando el usuario carga un nuevo avatar, la solicitud ReloadPending se establece persistentemente en su sesión y se restablece cuando se ha respondido.

<?php 
if ($session['ReloadPending']) 
{ $session['ReloadPending']=false; 
     echo "<body onload='location.reload(true);'>"; 
} else echo "<body>"; 
?> 

volver a cargar la página entera después de avatar carga hará que el parpadeo de página, pero esto sucede sólo una vez, que, creo, es aceptable.

0

Descubrí que una de las mejores maneras de hacerlo es tener la misma URL para obtener y publicar una imagen (REST).

de POST/mi/imagen (Cache-control: no-cache, debe-revalidate)

GET/mi/imagen (Cache-control: debe-revalidate)

Cuestiones relacionadas