Para mejorar el rendimiento de nuestro sitio web, tiempo de respuesta que demora en responder el servidor a una solicitud por parte del cliente, es recomendable hacer uso Etags y LastModified. Con ellos podremos procesar desde nuestro servidor más peticiones, sin necesidad de enviar por la red páginas dinámicas que no han sido modificadas si el navegador las posee ya cacheada.
Los Etags son parte de la información que envían los navegadores dentro de las solicitudes HTTP, esto sirve para indicarle al servidor web cual es la versión de la página que tenemos almacenada localmente, para que determine si ha cambiado y nos mande una nueva.
Ejemplo de uso:
1234567891011121314151617181920212223242526272829303132333435
<?PHP//Consigue la última fecha de modificación de este archivo$Lastmodified=Filemtime(__File__);echo "Lastmodified: ".$Lastmodified; //Consigue el hash unico de este archivo (Etag)$Etagfile = Md5_File(__File__);echo "Etagfile: ".$Etagfile.; //Consigue la Cabecera Http_If_Modified_Since si la Tiene$Ifmodifiedsince=(Isset($_Server['Http_If_Modified_Since']) ? $_Server['Http_If_Modified_Since'] : False);echo "Ifmodifiedsince: ".$Ifmodifiedsince.; //Consigue La Cabecera Http_If_None_Match Si La Tiene (Etag: Hash Unico Del Archivo)$Etagheader=(Isset($_Server['Http_If_None_Match']) ? Trim($_Server['Http_If_None_Match']) : False);echo "Etagheader: ".$Etagheader.; //Pone la cabecera Last-Modified (Ultima Modificacion)Header("Last-Modified: ".Gmdate("D, D M Y H:I:S", $Lastmodified)); //Pone la cabecera Etag-HeaderHeader("Etag: $Etagfile"); //Se asegura de habilitar la cacheHeader('Cache-Control: Public'); //Verifica si la Pagina ha cambiado. Si No, envia 304 Y SaleIf (@Strtotime($_Server['Http_If_Modified_Since'])==$Lastmodified || $Etagheader == $Etagfile){ Header("Http/1.1 304 Not Modified"); Exit;}//Acá iría nuestro códigoecho "Esta Pagina Fue Modificada: ".Date("D.M.Y H:I:S",Time()); ?>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?PHP //Consigue la última fecha de modificación de este archivo $Lastmodified=Filemtime(__File__); echo "Lastmodified: ".$Lastmodified; //Consigue el hash unico de este archivo (Etag) $Etagfile = Md5_File(__File__); echo "Etagfile: ".$Etagfile.; //Consigue la Cabecera Http_If_Modified_Since si la Tiene $Ifmodifiedsince=(Isset($_Server['Http_If_Modified_Since']) ? $_Server['Http_If_Modified_Since'] : False); echo "Ifmodifiedsince: ".$Ifmodifiedsince.; //Consigue La Cabecera Http_If_None_Match Si La Tiene (Etag: Hash Unico Del Archivo) $Etagheader=(Isset($_Server['Http_If_None_Match']) ? Trim($_Server['Http_If_None_Match']) : False); echo "Etagheader: ".$Etagheader.; //Pone la cabecera Last-Modified (Ultima Modificacion) Header("Last-Modified: ".Gmdate("D, D M Y H:I:S", $Lastmodified)); //Pone la cabecera Etag-Header Header("Etag: $Etagfile"); //Se asegura de habilitar la cache Header('Cache-Control: Public'); //Verifica si la Pagina ha cambiado. Si No, envia 304 Y Sale If (@Strtotime($_Server['Http_If_Modified_Since'])==$Lastmodified || $Etagheader == $Etagfile) { Header("Http/1.1 304 Not Modified"); Exit; } //Acá iría nuestro código echo "Esta Pagina Fue Modificada: ".Date("D.M.Y H:I:S",Time()); ?> |
En la primera solicitud nos devolverá 200 como código de estado.
1234567891011
HTTP/1.1 200 OKDate: Fri, 18 Aug 2017 15:45:36 GMTServer: Apache/2.4.25 (Win32) OpenSSL/1.0.2j PHP/5.6.30X-Powered-By: PHP/5.6.30LAST-MODIFIED: Wed, Wed Aug 2017 20:0:thETAG: 26b74f23fe3f3915acbbbd3cf0774760CACHE-CONTROL: PUBLICContent-Length: 167Keep-Alive: timeout=5, max=100Connection: Keep-AliveContent-Type: text/html; charset=UTF-8
1 2 3 4 5 6 7 8 9 10 11 |
HTTP/1.1 200 OK Date: Fri, 18 Aug 2017 15:45:36 GMT Server: Apache/2.4.25 (Win32) OpenSSL/1.0.2j PHP/5.6.30 X-Powered-By: PHP/5.6.30 LAST-MODIFIED: Wed, Wed Aug 2017 20:0:th ETAG: 26b74f23fe3f3915acbbbd3cf0774760 CACHE-CONTROL: PUBLIC Content-Length: 167 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/html; charset=UTF-8 |
En las siguientes invocaciones, el archivo PHP al no ser modificado, devolvera 304.
1234567
HTTP/1.1 304 NOT MODIFIEDDate: Fri, 18 Aug 2017 15:47:19 GMTServer: Apache/2.4.25 (Win32) OpenSSL/1.0.2j PHP/5.6.30Connection: Keep-AliveKeep-Alive: timeout=5, max=100ETAG: 26b74f23fe3f3915acbbbd3cf0774760CACHE-CONTROL: PUBLIC
1 2 3 4 5 6 7 |
HTTP/1.1 304 NOT MODIFIED Date: Fri, 18 Aug 2017 15:47:19 GMT Server: Apache/2.4.25 (Win32) OpenSSL/1.0.2j PHP/5.6.30 Connection: Keep-Alive Keep-Alive: timeout=5, max=100 ETAG: 26b74f23fe3f3915acbbbd3cf0774760 CACHE-CONTROL: PUBLIC |
Si usamos estos mecanismos, cada vez que devolvamos una página insertaremos en la cabecera un Etag y LastModified identificativo, cuando el navegador vuelva a solicitarla nos enviará de nuevo ese valor en If-None-Match. Si coinciden, el servidor devolverá un 304 Not Modified, por lo que se evitara realizar un envío de página.
El mecanismo para usarlo varía de cada implementación, pero principalmente debemos decidir cuál será nuestro valor de Etag y LastModified, por ejemplo, la url con la concatenación de la fecha de modificación, ultima modificacion de un archivo, modificacion de ultimo registro en una tabla de la base de datos.
A traves de nuestro código podemos implementarlo y enviarlo en la cabecera, como en el ejemplo, si coinciden los valores que nos envía el navegador simplemente devolvera el codigo de estado 304.