¿Cuál es la función del encabezado HTTP "Vary: Accept"?

93

Utilizo PHP para generar páginas web dinámicas. Como se indica en el siguiente tutorial (ver enlace a continuación), el tipo MIME de documentos XHTML debe ser "application / xhtml + xml" cuando $ _SERVER ['HTTP_ACCEPT'] lo permita. Dado que puede publicar la misma página con 2 MIME diferentes ("aplicación / xhtml + xml" y "texto / html"), debe configurar el encabezado HTTP "Vary" en "Aceptar". Esto ayudará a la caché de los proxies.

Enlace: http://keystonewebsites.com/articles/mime_type.php

Ahora no estoy seguro de la implicación de: header ('Vary: Accept'); No estoy realmente seguro de qué hará exactamente 'Vary: Accept' ...

La única explicación que encontré es:

Después del encabezado Content-Type, se envía un encabezado Vary (si lo entiendo correctamente) para indicarle a las cachés intermedias, como los servidores proxy, que el tipo de contenido del documento varía según las capacidades del cliente que solicita el documento. http://www.456bereastreet.com/archive/200408/content_negotiation/

Cualquiera puede darme una explicación "real" de este encabezado ( con ese valor ). Creo que entiendo cosas como: Vary: Accept-Encoding donde la caché de los proxies podría basarse en la codificación de la página servida, pero no entiendo: Vary: Accept

AlexV
fuente
1
Francamente, no te molestes. Dejando a un lado las fallas en la implementación en ese sitio, la única vez que obtendrá beneficios de servir con un tipo de contenido XML es cuando hace cosas que no se pueden hacer en texto / html, y si todo lo que está haciendo está cambiando Doctype y xmlns, entonces no vas a hacer esas cosas. Cíñete a texto / html. Para el caso, también puede ceñirse a HTML 4.01.
Quentin
Sí, lo entiendo y creo que "problemas" como éste surgen con demasiada frecuencia en el desarrollo web. ¡Gracias a "debería" en las especificaciones / RFC!
AlexV
2
Probablemente debería leer esto: blogs.msdn.com/ieinternals/archive/2009/06/17/… antes de considerar el uso de VARY.
EricLaw
1
Este video tiene una buena explicación sobre el Vary:encabezado.
Kannan Mohan

Respuestas:

94
  • El cache-controlencabezado es el mecanismo principal para que un servidor HTTP le diga a un proxy de almacenamiento en caché la "actualidad" de una respuesta. (es decir, cuánto tiempo almacenar la respuesta en el caché)

  • En algunas situaciones, las cache-controldirectivas son insuficientes. Aquí se archiva una discusión del grupo de trabajo HTTP , que describe una página que cambia solo con el idioma. Este no es el caso de uso correcto para el encabezado de variación, pero el contexto es valioso para nuestra discusión. (Aunque creo que el encabezado Vary resolvería el problema en ese caso, hay una forma mejor). Desde esa página:

Vary es estrictamente para aquellos casos en los que es inútil o excesivamente complicado para un proxy replicar lo que haría el servidor.

Un ejemplo artificial:

Su servidor HTTP tiene una gran página de destino. Tiene dos páginas ligeramente diferentes con la misma URL, dependiendo de si el usuario ha estado allí antes. Distingue entre las solicitudes y el "recuento de visitas" de un usuario según las cookies. Pero, dado que la página de destino de su servidor es tan grande, desea que los proxies intermediarios almacenen la respuesta en caché si es posible.

Los encabezados URL, Last-Modified y Cache-Control son insuficientes para brindar esta información a un proxy de almacenamiento en caché, pero si agrega Vary: Cookie, el motor de caché agregará el encabezado Cookie a sus decisiones de almacenamiento en caché.

Finalmente, para sitios web dinámicos con poco tráfico, siempre he encontrado lo simple Cache-Control: no-cache, no-storey Pragma: no-cachesuficiente.

Editar: para responder con mayor precisión a su pregunta: el encabezado de solicitud HTTP 'Aceptar' define los tipos de contenido que un cliente puede procesar. Si tiene dos copias del mismo contenido en la misma URL, que solo difieren en el tipo de contenido, entonces el uso Vary: Acceptpodría ser apropiado.

Actualización 11 de septiembre 12:

Incluyo un par de enlaces que han aparecido en los comentarios desde que este comentario se publicó originalmente. Ambos son recursos excelentes para ejemplos (y problemas) del mundo real con Vary: Accept; Si está leyendo esta respuesta, también debe leer esos enlaces.

El primero, del destacado EricLaw, sobre el comportamiento de Internet Explorer con el encabezado Vary y algunos de los desafíos que presenta a los desarrolladores: El encabezado Vary evita el almacenamiento en caché en IE . En resumen, IE (anterior a IE9) no almacena en caché ningún contenido que use el encabezado Vary porque el caché de solicitud no incluye encabezados de solicitud HTTP. EricLaw (Eric Lawrence en el mundo real) es un administrador de programas en el equipo de IE.

El segundo es de Eran Medan, y es una discusión en curso sobre el comportamiento inesperado relacionado con Vary en Chrome: Backing no maneja el encabezado Vary correctamente . Está relacionado con el comportamiento de IE, excepto que los desarrolladores de Chrome adoptaron un enfoque diferente, aunque no parece haber sido una elección deliberada.

JJ
fuente
3
Tenga cuidado con esto junto con el botón de retroceso del navegador en Chrome, hay una especie de guerra de llamas en este error (que ahora no se solucionará por alguna razón) code.google.com/p/chromium/issues/detail?id=94369
Eran Medan
6
@EranMedan El error de Chrome se ha solucionado desde entonces.
59

Vary: Acceptsimplemente dice que la respuesta se generó en función del Acceptencabezado de la solicitud. Una solicitud con un Acceptencabezado diferente puede obtener una respuesta diferente.

(Puede ver que el código PHP vinculado se ve $HTTP_ACCEPT. Ese es el valor del Acceptencabezado de la solicitud).

Para los cachés HTTP, esto significa que la respuesta debe almacenarse en caché con especial cuidado. Solo será una coincidencia válida para solicitudes posteriores con exactamente el mismo Acceptencabezado .

Ahora, esto solo importa si la página se puede almacenar en caché en primer lugar. Por defecto, las páginas PHP no lo son. Una página PHP puede marcar la salida como almacenable en caché enviando ciertos encabezados ( Expirespor ejemplo). Pero si hacerlo y cómo hacerlo es una cuestión diferente.

Jason Orendorff
fuente
¿"podría conseguir" o "debería conseguir"?
Pacerier
6
@Pacerier "might get" es correcto. Vary: Acceptno significa que cada Acceptvalor de encabezado distinto posible produce una respuesta diferente y única. Solo significa que un Acceptencabezado diferente puede producir una respuesta diferente.
Jason Orendorff
2

En realidad, pronto habrá una cantidad significativa de nuevas funciones (y ya en Chrome) que hacen que el Varyencabezado sea extremadamente útil. Por ejemplo, considere las sugerencias del cliente . Cuando se usa en conexión con imágenes, por ejemplo, la sugerencia de cliente permite que un servidor optimice recursos como imágenes dependiendo de:

  • ancho de la imagen
  • Ancho de la ventana gráfica
  • Tipo de codificación compatible con el navegador (piense en WebP)
  • Enlace descendente (esencialmente velocidad de red)

Entonces, un servidor que admita esas características establecería el Varyencabezado para indicar eso.

Chrome anuncia la compatibilidad con WebP configurando "image / webp" como parte del Varyencabezado de cada solicitud. Por lo tanto, un servidor podría reescribir una imagen como WebP si el navegador lo admite, por lo que el proxy debería verificar el encabezado para no almacenar en caché una imagen de WebP y luego servirla en un navegador que no sea compatible con WebP. Obviamente, si su servidor no hace eso, no importaría. Entonces, dado que la respuesta del servidor varía en el Acceptencabezado de la solicitud, la respuesta debe incluir eso para no confundir a los proxies:

Vary: Accept

Otro ejemplo podría ser el ancho de la imagen. En un navegador móvil, el Widthencabezado puede ser bastante pequeño para una imagen receptiva, en comparación con lo que sería si se viera desde un navegador de escritorio. Entonces, en ese caso Width, se agregaría al Varyencabezado que es esencial para que el proxy no almacene en caché la versión móvil pequeña y la sirva a los navegadores de escritorio, o viceversa. En ese caso, el encabezado podría incluir:

Vary: Accept, Width

O en el caso de que un servidor admita todas las especificaciones de sugerencias del cliente, el encabezado sería algo como:

Vary: Accept, DPR, Width, Save-Data, Downlink
Brad Berger
fuente