2009-10-18 9 views
13

Estoy usando un script PHP para servir archivos. Me gustaría poder devolver un 304 encabezado no modificado en mi respuesta HTTP si el archivo no ha cambiado desde que el cliente lo descargó por última vez. Esta parece ser una característica en Apache (y la mayoría de los otros servidores web), pero no tengo idea de cómo esto puede implementarse a través de PHP.304: Caché no modificado y front-end

He oído hablar del uso de $_SERVER['HTTP_IF_MODIFIED_SINCE'], pero esta variable no parece aparecer en mi superrsenal $_SERVER.

Mi pregunta no es cómo devolver un encabezado 304, pero cómo saber que se debe devolver.


Editar: El problema es que mi $_SERVER['HTTP_IF_MODIFIED_SINCE'] no está establecida. Este es el contenido de mi archivo .htaccess:

ExpiresActive On 
ExpiresByType image/jpeg "modification plus 1 month" 
ExpiresByType image/png "modification plus 1 month" 
ExpiresByType image/gif "modification plus 1 month" 
Header append Cache-Control: "must-revalidate" 


<IfModule mod_rewrite.c> 
    RewriteEngine On 
    RewriteCond $1 !^(controller\.php) 
    RewriteRule (.*\.jpg|.*\.png|.*\.gif) controller.php/$1 
</IfModule> 

HTTP_IF_MODIFIED_SINCE sigue sin aparecer en la matriz súper $_SERVER.

Respuesta

26

HTTP_IF_MODIFIED_SINCE es la forma correcta de hacerlo. Si no lo está obteniendo, verifique que Apache tenga mod_expires y mod_headers habilitados y funcionando correctamente. Tomado de a comment on PHP.net:

$last_modified_time = filemtime($file); 
$etag = md5_file($file); 
// always send headers 
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT"); 
header("Etag: $etag"); 
// exit if not modified 
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time || 
    @trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) { 
    header("HTTP/1.1 304 Not Modified"); 
    exit; 
} 

// output data 
+1

He visto esta manera de hacer esto, pero $ _SERVER ['HTTP_IF_MODIFIED_SINCE'] siempre está vacío para mí ... –

+0

Revise mi edición reciente - Olvidé una parte de la información de configuración de Apache importante. –

+0

Intenté modificar mi archivo htaccess.txt según http://www.webmasterworld.com/forum23/2300.htm, pero no voy. ¿Algunas ideas? –

0

$_SERVER['HTTP_IF_MODIFIED_SINCE'] suele estar vacío cuando register_globals está apagado.

Compruebe si ese es el caso, y si es así tratar getenv('HTTP_IF_MODIFIED_SINCE')

1

This article responderá a todas sus preguntas sobre el almacenamiento en caché

he encontrado que la adición de

RewriteRule .* - [E=HTTP_IF_MODIFIED_SINCE:%{HTTP:If-Modified-Since}] 
RewriteRule .* - [E=HTTP_IF_NONE_MATCH:%{HTTP:If-None-Match}] 

Para el fondo de mi archivo .htaccess (debajo de todo reescritura) funcionó.

0

También hay algunos parámetros para comprobar otros .. en mi caso no he tenido estos dos cabeceras:

$_SERVER['HTTP_IF_NONE_MATCH'] && $_SERVER['HTTP_IF_MODIFIED_SINCE'] 

que se requieren para devolver una cabecera adecuada 304, como mi reloj del sistema era una poco tarde, que va a interpretar esas páginas que expira en el futuro, entonces no enviar esos valores en absoluto

también comprobar que la cabecera que se devuelve por Apache, o al menos anular a un valor mayor

Cache-Control: max-age=3600 

Como no va a enviar cabeceras anteriores si

Last-Modified previous sent header < (NOW - 3600) 

Así que en mi caso me he fijado esta función bastante útil function lastModified($file){ $x=filemtime($file); while($x>time())$x-=86000;}#reduce by one day if touched in future date $date=gmdate('D, j M Y H:i:s',$x).' GMT'; header('Cache-Control: max-age=86000',1); if($_SERVER['HTTP_IF_NONE_MATCH'] == $x || $_SERVER['HTTP_IF_MODIFIED_SINCE']==$date){ header('HTTP/1.1 304 Not Modified',1,304);die;} header('Etag: '.$x,1);header('Last-Modified: '.$date,1); }

0

tuve este problema y que resultó ser simplemente que tuve Firebug abierto. Tiene una opción en la pestaña de red "Deshabilitar la memoria caché del navegador" que está marcada de forma predeterminada. Hay una opción similar en las herramientas para desarrolladores de Chrome, una de las casillas de verificación en la barra debajo de la barra de menú.

Si desactivas estas opciones, el navegador enviará correctamente HTTP_IF_MODIFIED_SINCE y todo funcionará correctamente (incluso con Firebug o Chrome Dev Tools abiertas).

Cuestiones relacionadas