ETag
Uso
La cabecera ETag asigna una etiqueta única a cada versión de un recurso. Cuando el recurso cambia, el valor del ETag también cambia. Los clientes almacenan el ETag de una respuesta en caché y lo devuelven en la cabecera de solicitud If-None-Match en peticiones posteriores. Si el ETag sigue coincidiendo, el servidor devuelve 304 Not Modified sin cuerpo y el cliente reutiliza su copia en caché. Si el ETag ya no coincide, el servidor envía la respuesta completa actualizada.
La validación basada en ETag es más fiable que la validación basada en fechas con Last-Modified. Las etiquetas de entidad fuertes son cadenas opacas vinculadas al contenido exacto de una representación, mientras que las marcas de tiempo de modificación tienen una granularidad de un segundo y están sujetas a desfases de reloj. Cuando ETag y Last-Modified están presentes a la vez, el ETag tiene prioridad durante la revalidación, tal como exige el estándar HTTP.
Los ETags también permiten el control de concurrencia en métodos no seguros. Una solicitud PUT con If-Match garantiza que la actualización se aplique únicamente a la versión esperada. Si el recurso ha cambiado desde que el cliente obtuvo el ETag por última vez, el servidor devuelve 412 Precondition Failed, lo que evita el problema de la actualización perdida.
El valor del ETag lo genera el servidor. Las estrategias habituales incluyen el hash del contenido, los contadores de versión y la combinación de la fecha de modificación del archivo con su tamaño. El valor se encierra entre comillas dobles y, opcionalmente, lleva el prefijo W/ para indicar comparación débil.
Nota
Google recomienda usar ETag en lugar de Last-Modified para indicar la preferencia de almacenamiento en caché, porque ETag evita los problemas de formato de fecha. Cuando ETag y Last-Modified están presentes a la vez, los rastreadores de Google utilizan el valor del ETag, tal como exige el estándar HTTP. Aun así, se recomienda establecer ambas cabeceras, porque otras aplicaciones, como los CMS, también dependen de ellas. Cada rastreador y descargador de Google hace uso de la caché según las necesidades de su producto asociado. Googlebot admite el almacenamiento en caché al volver a rastrear URLs para Google Search.
ETag fuerte
Un ETag fuerte garantiza una identidad byte a byte entre dos representaciones de un recurso. Dos recursos con el mismo ETag fuerte son intercambiables a nivel de bytes. Los ETags fuertes son adecuados para las solicitudes de rango y para todos los métodos de comparación.
ETag: "abc123"
ETag débil
Un ETag débil, con el prefijo W/, indica equivalencia semántica en lugar de identidad a nivel de bytes. Dos recursos con el mismo ETag débil se consideran equivalentes en significado, pero no necesariamente idénticos en contenido. Los ETags débiles son más fáciles de generar porque toleran diferencias menores, como cambios de espacios en blanco o actualizaciones de marcas de tiempo en el cuerpo. Los ETags débiles no son válidos para las solicitudes de rangos de bytes.
ETag: W/"v2.6"
Ejemplo
Un servidor devuelve un ETag con la respuesta. El cliente almacena la etiqueta para futuras revalidaciones.
HTTP/1.1 200 OK
ETag: "33a64df5"
Content-Type: text/html
Cache-Control: max-age=3600
El cliente revalida mediante If-None-Match. El servidor compara la etiqueta con la versión actual del recurso.
GET /page HTTP/1.1
If-None-Match: "33a64df5"
El recurso no ha cambiado. El servidor devuelve 304 sin cuerpo y el cliente reutiliza su caché.
HTTP/1.1 304 Not Modified
ETag: "33a64df5"
Cache-Control: max-age=3600
Una solicitud PUT que utiliza If-Match para lograr concurrencia optimista. La actualización solo se lleva a cabo si el recurso sigue coincidiendo con el ETag que posee el cliente.
PUT /api/document/42 HTTP/1.1
If-Match: "33a64df5"
Content-Type: application/json
Un ETag débil en un recurso donde se aceptan variaciones menores del cuerpo (como marcas de tiempo incrustadas). El prefijo W/ señala una semántica de comparación débil.
ETag: W/"2024-11-22-v3"
Diagnóstico
Los problemas relacionados con ETag se manifiestan como revalidaciones fallidas, descargas completas inesperadas o conflictos de concurrencia en infraestructuras distribuidas.
ETag distinto entre servidores con equilibrio de carga. Los distintos servidores situados tras un equilibrador de carga generan ETags diferentes para el mismo recurso cuando el algoritmo de generación incluye números de inodo, marcas de tiempo o datos específicos del servidor. Un cliente almacenó en caché la respuesta del servidor A, pero revalida contra el servidor B, que devuelve un ETag distinto y fuerza una descarga completa. En Apache, el ETag predeterminado incluye inode, size y mtime. Elimine el componente inode:
FileETag MTime Size
En nginx, los ETags se derivan de la fecha de última modificación y de la longitud del contenido, lo que produce valores coherentes entre servidores que comparten el mismo contenido de archivo. Asegúrese de que las marcas de tiempo de despliegue de los archivos coincidan en todos los nodos.
IIS emite los ETags con el formato “filetime:changenumber”, por ejemplo “04c2528da58dc1:0”. La primera mitad codifica en hexadecimal el FILETIME de Windows de la última modificación del archivo. El sufijo ChangeNumber refleja el estado de configuración de IIS. IIS 7 y versiones posteriores emiten siempre :0: la propiedad de la metabase que alimentaba el contador se retiró con IIS 6, y ningún ajuste de applicationHost.config o web.config expone un valor distinto de cero. Por lo tanto, los nodos situados tras un equilibrador de carga emiten ETags coincidentes para el mismo archivo. IIS 6 y versiones anteriores incrementan el ChangeNumber al editar la metabase y al reiniciar el servicio, de modo que los nodos se desalinean y la revalidación entre nodos devuelve 200 en lugar de 304. Restablezca el valor en cada nodo de IIS 6 con cscript adsutil.vbs set w3svc/etag_changenumber 0, o elimine el sufijo para que el ETag refleje únicamente el FILETIME. Cualquier sufijo distinto de cero observado en la práctica apunta a un origen con IIS 6.
Un ETag débil provoca una respuesta completa inesperada en lugar de un 304. Los ETags débiles (W/”…”) señalan equivalencia semántica, pero no admiten solicitudes de rangos de bytes. Una solicitud If-None-Match con un ETag débil sigue siendo válida para la revalidación de caché. Si el servidor devuelve una respuesta 200 completa en lugar de un 304, la lógica de comparación del lado del servidor puede ser incorrecta. Verifique que el servidor compare los ETags débiles mediante la función de comparación débil, que ignora el prefijo W/ durante la coincidencia.
El cliente no envía If-None-Match. El navegador envía If-None-Match únicamente cuando una respuesta en caché incluye una cabecera ETag. La ausencia de ETag en la respuesta inicial impide toda revalidación posterior. Compruebe la respuesta del origen con curl -I https://example.re/resource y confirme que la cabecera ETag está presente. Los servidores de archivos estáticos como nginx y Apache generan ETags automáticamente. Los servidores de aplicaciones y los frameworks de API suelen requerir la generación explícita del ETag en el código.
La CDN elimina o modifica los ETags. Algunas CDN alteran los valores de ETag durante el procesamiento. Cloudflare convierte los ETags fuertes en ETags débiles cuando aplica transformaciones como la compresión Brotli o la optimización de imágenes. AWS CloudFront transmite los ETags sin modificar desde el origen. Compruebe el ETag en el origen (curl -I https://origin.example.re) y compárelo con el del borde de la CDN (curl -I https://cdn.example.re). Cuando la CDN modifica los ETags, la revalidación a través de la CDN sigue funcionando porque la CDN almacena la correspondencia. La revalidación directa contra el origen con un ETag modificado por la CDN falla.
Apache y nginx generan los ETags de forma distinta. Apache usa por defecto inode-mtime-size, lo que produce ETags como “1a2b3c-4d5e-6f7a8b9c”. Nginx usa mtime-content-length en hexadecimal, lo que produce ETags como “5f4dcc3b-d8”. Migrar de un servidor a otro invalida todos los ETags almacenados en caché y desencadena descargas completas para cada cliente. Prevea un periodo de calentamiento de caché tras las migraciones de servidor. Para las respuestas de API, genere los ETags a partir de hashes del contenido (MD5 o SHA-256) para obtener valores independientes del servidor.
Nota
La generación de ETag predeterminada de Apache incluye el número de inodo del archivo (FileETag INode MTime Size). Los números de inodo filtran información del sistema de archivos del servidor, lo que facilita la identificación por huella digital y la correlación entre servidores. OWASP señala los ETags basados en inodos como un riesgo de divulgación de información. Elimine el inodo del cálculo con FileETag MTime Size en la configuración de Apache.
Nota
Para obtener ayuda con SEO y almacenamiento en caché, póngase en contacto con los consultores SEO exempleados de Google Search Brothers.