¿Qué tiene prioridad: la ETag o el encabezado HTTP Last-Modified?

83

Para dos solicitudes subsiguientes, ¿cuál de los siguientes dos encabezados recibe más peso de los navegadores si uno de ellos cambia: ETag o Last-Modified?

usuario101442
fuente

Respuestas:

90

De acuerdo con la sección 13.3.4 de RFC 2616 , un cliente HTTP 1.1 DEBE usar la ETag en cualquier solicitud condicional de caché, y si tanto una ETag como la última modificación están presentes, DEBERÍA usar ambas. El encabezado ETag se considera un validador fuerte (ver sección 13.3.3), a menos que el servidor lo declare explícitamente débil, mientras que el encabezado Última modificación se considera débil a menos que exista al menos una diferencia de un minuto entre él y el encabezado Fecha. Sin embargo, tenga en cuenta que tampoco se requiere que el servidor envíe (pero DEBERÍA, si puede).

Tenga en cuenta que el Cliente no comprueba los encabezados para ver si han cambiado; simplemente los usa ciegamente en la siguiente solicitud condicional; Depende del servidor evaluar si enviar el contenido solicitado o una respuesta 304 No modificado. Si el servidor solo envía uno, entonces el cliente usará ese solo (aunque, solo los validadores sólidos son útiles para una solicitud de rango). Por supuesto, también queda a discreción de los cachés intermedios (a menos que se les haya impedido el almacenamiento en caché a través de las directivas de control de caché) y el servidor cómo actuarán sobre los encabezados; el RFC establece que NO DEBEN devolver un 304 No modificado si los validadores son inconsistentes, pero dado que los valores de encabezado son generados por el servidor, tiene bastante margen de maniobra.

En la práctica, he notado que Chrome, FireFox e IE 7+ envían ambos encabezados, si están disponibles. También probé el comportamiento al enviar encabezados modificados, que ya había sospechado por la información en el RFC. Los cuatro clientes que probé solo enviaron solicitudes condicionales si las páginas se actualizaron o si fue la primera vez que el proceso actual solicitó la página.

Thomas S. Trias
fuente
1
Gran respuesta, Thomas. Gracias por proporcionar la especificación oficial y discutir las implementaciones actuales del navegador.
dthrasher
1
Citando la sección 14.26, el servidor NO DEBE realizar el método solicitado, a menos que sea necesario porque la fecha de modificación del recurso no coincide con la proporcionada en un campo de encabezado If-Modified-Since en la solicitud. Parece que If-Modified-Since tiene prioridad.
Vicary
20

¿No es más como una expresión "OR"? En pseudocódigo:

if ETagFromServer != ETagOnClient || LastModifiedFromServer != LastModifiedOnClient
   GetFromServer
else
   GetFromCache
Gedeón
fuente
4
Creo que la última marca de tiempo modificada debería compararse de manera diferente, como en: if ETagFromServer! = ETagOnClient || LastModifiedFromServer> LastModifiedOnClient
RoyM
Es una instrucción AND porque ETag puede ser débil, en cuyo caso podría tener una entidad semánticamente equivalente y luego recurrir al encabezado modificado por última vez. Considere una situación en la que una imagen podría volver a codificarse y queremos decir que el original y la recodificación son iguales a pesar de que no son idénticos en bytes. En este caso queremos usar la modificada por última vez como punto de retorno y es por eso que ambos deben ser coherentes
ParoX
8

=! es el operador de comparación correcto. Se requiere que el cliente mantenga la cadena literal recibida del servidor, ya que las conversiones pueden crear pequeñas diferencias. No se puede asumir que 'más nuevo es mejor'.

¿Por qué? Considere el caso en el que el operador del servidor revierte una versión incorrecta de un recurso. La versión revertida es MÁS ANTIGUA, pero correcta.

El cliente debe utilizar la versión ofrecida actualmente por el servidor; puede usar una versión en caché solo si es la misma. Por lo tanto, el servidor debe verificar la igualdad, no 'más nuevo'.

AccuracyInReponses
fuente