¿Qué es el control de caché: privado?

148

Cuando visito chesseng.herokuapp.com obtengo un encabezado de respuesta que parece

Cache-Control:private
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/css
Date:Tue, 16 Oct 2012 06:37:53 GMT
Last-Modified:Tue, 16 Oct 2012 03:13:38 GMT
Status:200 OK
transfer-encoding:chunked
Vary:Accept-Encoding
X-Rack-Cache:miss

y luego actualizo la página y obtengo

Cache-Control:private
Connection:keep-alive
Date:Tue, 16 Oct 2012 06:20:49 GMT
Status:304 Not Modified
X-Rack-Cache:miss

Parece que el almacenamiento en caché está funcionando. Si eso funciona para el almacenamiento en caché, ¿cuál es el punto de expira y control de caché: max-age . Para añadir confusión, cuando pruebo la página en https://developers.google.com/speed/pagespeed/insights/ me dice que "aproveche el almacenamiento en caché del navegador".

usuario782220
fuente
consulte este diagrama stackoverflow.com/a/49925190/3748498
pravdomil

Respuestas:

74

Para responder a su pregunta sobre por qué funciona el almacenamiento en caché, aunque el servidor web no incluye los encabezados:

  • Caduca: [a date]
  • Control de caché: max-age =[seconds]

El servidor solicitó amablemente a los proxies intermedios que no almacenen en caché el contenido (es decir, el elemento solo debe almacenarse en caché en un caché privado , es decir, solo en su propia máquina local):

  • Control de caché: privado

Pero el servidor olvidó incluir cualquier tipo de sugerencias de almacenamiento en caché:

  • olvidaron incluir Expires , por lo que el navegador sabe usar la copia en caché hasta esa fecha
  • se olvidaron de incluir Max-Age , por lo que el navegador sabe cuánto tiempo es bueno para el elemento en caché
  • olvidaron incluir E-Tag , por lo que el navegador puede hacer una solicitud condicional

Pero sí incluyeron una fecha de Última modificación en la respuesta:

Last-Modified: Tue, 16 Oct 2012 03:13:38 GMT

Como el navegador sabe la fecha en que se modificó el archivo, puede realizar una solicitud condicional . Le pedirá al servidor el archivo, pero le indicará que solo envíe el archivo si se ha modificado desde el 16/10/2012 3:13:38:

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT

El servidor recibe la solicitud, se da cuenta de que el cliente ya tiene la versión más reciente. En lugar de enviar al cliente 200 OK, seguido del contenido de la página, le dice que su versión en caché es buena:

304 Not Modified

Su navegador tuvo que sufrir el retraso de enviar una solicitud al servidor y esperar una respuesta, pero ahorró tener que volver a descargar el contenido estático.

¿Por qué Max-Age ? ¿Por qué caduca ?

Porque Last-Modified apesta.

No todo en el servidor tiene una fecha asociada. Si estoy construyendo una página sobre la marcha, no hay una fecha asociada, es ahora . Pero estoy perfectamente dispuesto a dejar que el usuario almacene en caché la página de inicio durante 15 segundos:

200 OK
Cache-Control: max-age=15

Si el usuario martilla F5, seguirá obteniendo la versión en caché durante 15 segundos. Si se trata de un proxy corporativo, todos los 67198 usuarios que accedan a la misma página en la misma ventana de 15 segundos obtendrán el mismo contenido, todo servido desde un caché cercano. Victoria de rendimiento para todos.

La virtud de agregar Cache-Control: max-agees que el navegador ni siquiera tiene que realizar una solicitud condicional .

  • si solo especificó Last-Modified, el navegador debe realizar una solicitud If-Modified-Sincey esperar una 304 Not Modifiedrespuesta
  • si lo especificó max-age, el navegador ni siquiera tendrá que sufrir el viaje de ida y vuelta de la red; el contenido saldrá directamente de los cachés

La diferencia entre "Cache-Control: max-age" y "Expires"

Expireses un equivalente heredado del Cache-Control: max-ageencabezado moderno (c. 1998) :

  • Expires: especifica una fecha ( qué asco)
  • max-age: especifica segundos (bondad)
  • Y si se especifican ambos , entonces el navegador usa max-age:

    200 OK
    Cache-Control: max-age=60
    Expires: 20180403T192837 
    

Cualquier sitio web escrito después de 1998 ya no debería usarse Expires, y en su lugar debe usarse max-age.

¿Qué es ETag?

ETag es similar a Last-Modified , excepto que no tiene que ser una fecha, solo tiene que ser algo .

Si estoy sacando una lista de productos de una base de datos, el servidor puede enviar el último rowversioncomo un ETag, en lugar de una fecha:

200 OK
ETag: "247986"

Mi ETag puede ser el hash SHA1 de un recurso estático (p. Ej., Imagen, js, css, fuente) o de la página renderizada en caché (es decir, esto es lo que hace el wiki de Mozilla MDN; ellos cortan el marcado final):

200 OK
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

Y exactamente como en el caso de una solicitud condicional basada en Last-Modified :

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT

304 Not Modified

Puedo realizar una solicitud condicional basada en el ETag:

GET / HTTP/1.1
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

304 Not Modified

An ETages superior a Last-Modifiedporque funciona para cosas además de archivos , o cosas que tienen una noción de fecha . Solo es

Ian Boyd
fuente
1
¡Increíble! Puse una recompensa por esta respuesta. ¿Qué pasa si cache-controlno existe? ¿Y solo tienes Etag? ¿Todavía no necesita hacer una 'solicitud condicional' contra el servidor? El comportamiento que veo cuando estoy desconectado es que solo regresa de la memoria caché. Pero cuando está fuera de línea no puede hacer esa solicitud condicional. Entonces, ¿eso significa si se almacenará en caché indefinidamente si te quedas sin conexión? Ya he hecho esta pregunta en detalle aquí . ¿Puedes echar un vistazo?
Miel
168
Cache-Control: private

Indica que todo o parte del mensaje de respuesta está destinado a un solo usuario y NO DEBE ser almacenado en caché por un caché compartido, como un servidor proxy.

De RFC2616 sección 14.9.1

Dan D.
fuente
14
Porque fue guardado en caché por su navegador. Usted es el usuario único al que se destina la respuesta.
Dan D.
13
No, no se debe a que Cache-Control:privatesolo establece que las memorias caché compartidas (como las memorias caché proxy) no deberían almacenar en caché la respuesta.
Dan D.
55
@Trejkaz No, realmente significa un solo usuario. Un usuario es una cuenta que tiene su propio directorio de inicio en el que reside el caché. Los perfiles que son propiedad del mismo usuario pueden compartir su caché. Como has encontrado. Pero dos perfiles en la misma computadora si son propiedad de diferentes usuarios no deben compartir su caché, a menos que ese caché se trate como un caché compartido.
Dan D.
2
Ah, entonces es por usuario en el nivel del sistema operativo. Sí, la razón por la que me pregunto es por una aparente fuga de información entre las ventanas de incógnito de Chrome y las de no incógnito, que usa el caché para hacerlo.
Trejkaz
2
@didibus proxy-revalidaterequiere que los proxies siempre se revaliden en cada acceso. Donde como privateevita que el proxy se almacene en caché.
Dan D.
21

RFC 2616, sección 14.9.1 :

Indica que todo o parte del mensaje de respuesta está destinado a un solo usuario y NO DEBE ser almacenado en caché por un caché compartido ... Un caché privado (no compartido) PUEDE almacenar en caché la respuesta.


Los navegadores podrían usar esta información. Por supuesto, el "usuario" actual puede significar muchas cosas: usuario del sistema operativo, un usuario del navegador (por ejemplo, los perfiles de Chrome), etc. No se especifica.

Para mí, un ejemplo más concreto de Cache-Control: privatees que los servidores proxy (que suelen tener muchos usuarios) no van a almacenar en caché. Está destinado al usuario final y a nadie más.


Para su información, el RFC deja en claro que esto no proporciona seguridad. Se trata de mostrar el contenido correcto, no asegurar el contenido.

Este uso de la palabra privado solo controla dónde se puede almacenar en caché la respuesta y no puede garantizar la privacidad del contenido del mensaje.

Paul Draper
fuente
55
Un caché privado (no compartido) PUEDE almacenar en caché la respuesta. Esta parte es clave. Gracias.
Oliver
0

El campo de encabezado de entidad expira da la fecha / hora después de la cual la respuesta se considera obsoleta.

Aunque el campo de encabezado anterior proporciona un mecanismo al cliente para decidir si se debe enviar una solicitud al servidor. En alguna condición, el cliente envía una solicitud de corte y el valor de edad de la respuesta es mayor que el valor máximo, ¿significa que el servidor debe enviar el recurso al cliente? Tal vez el recurso nunca cambió.

Para resolver este problema, HTTP1.1 proporciona la última cabeza modificada. El servidor da la última fecha de modificación de la respuesta al cliente. Cuando el cliente necesita este recurso, enviará el campo de encabezado If-Modified-Since al servidor. Si esta fecha es anterior a la fecha modificada del recurso, el servidor enviará el recurso al cliente y le dará un código 200. De lo contrario, devolverá el código 304 al cliente y esto significa que el cliente puede usar el recurso que almacenó en caché.

Lin.Yang
fuente