una navegadores los htaccess evitar equiv ejemplo control caché cache aplicación almacenamiento actualizar http rest caching

navegadores - Estoy confundido acerca del almacenamiento en caché de HTTP



evitar caché de los navegadores al actualizar una aplicación web (5)

El protocolo HTTP admite un tipo de solicitud llamado "If-Modified-Since", que básicamente permite que el servidor de caché pregunte al servidor web si el elemento ha cambiado. El protocolo HTTP también admite encabezados "Cache-Control" dentro de las respuestas del servidor HTTP que le dicen a los servidores de caché qué hacer con el contenido (como nunca almacenar en caché esto, o asumir que caduca en 1 día, etc.).

También mencionó respuestas encriptadas. Los servidores de caché HTTP no pueden almacenar en caché SSL porque para hacerlo necesitarían descifrar las páginas como un "hombre en el medio". Hacerlo sería un desafío técnico (descifrar la página, almacenarla y volver a cifrarla para el cliente) y también violaría la seguridad de la página que causa advertencias de "certificado inválido" en el lado del cliente. Es técnicamente posible hacer que un servidor de caché lo haga, pero causa más problemas de los que soluciona, y es una mala idea. Dudo que ningún servidor de caché realmente haga este tipo de cosas.

He estado pensando en leer y escribir lotes en un entorno RESTful, y creo que me he dado cuenta de que tengo más preguntas sobre el almacenamiento en caché de HTTP. (A continuación utilizo comas (",") para delimitar varias identificaciones de registro, pero ese detalle no es particular de la discusión).

Empecé con este problema:

1. Single GET invalidado por actualización por lotes

GET /farms/123 # get info about Old MacDonald''s Farm PUT /farms/123,234,345 # update info on Old MacDonald''s Farm and some others GET /farms/123

¿Cómo sabe un servidor de almacenamiento en caché entre el cliente y el servidor Farms invalidar su caché de /farms/123 cuando ve el PUT ?

Entonces me di cuenta de que esto también era un problema:

2. Batch GET invalidado por actualización única (o por lotes)

GET /farms/123,234,345 # get info about a few farms PUT /farms/123 # update Old MacDonald''s Farm GET /farms/123,234,345

¿Cómo sabe el caché para invalidar el GET granja múltiple cuando ve pasar el PUT?

Así que pensé que el problema realmente era solo con las operaciones por lotes. Entonces me di cuenta de que cualquier relación podría causar un problema similar. Digamos que una granja tiene cero o un propietario, y un propietario puede tener cero o una granja.

3. Single GET invalidado por la actualización de un registro relacionado

GET /farms/123 # get info about Old MacDonald''s Farm PUT /farmers/987 # Old MacDonald sells his farm and buys another one GET /farms/123

¿Cómo sabe la memoria caché para invalidar el único GET cuando ve pasar el PUT?

Incluso si cambia los modelos para que sean más RESTful, usando modelos de relación, obtendrá el mismo problema:

GET /farms/123 # get info about Old MacDonald''s Farm DELETE /farm_ownerships/456 # Old MacDonald sells his farm... POST /farm_ownerships # and buys another one GET /farms/123

En ambas versiones de # 3, el primer GET debería devolver algo así como (en JSON):

farm: { id: 123, name: "Shady Acres", size: "60 acres", farmer_id: 987 }

Y el segundo GET debería devolver algo como:

farm: { id: 123, name: "Shady Acres", size: "60 acres", farmer_id: null }

¡Pero no puede! Ni siquiera si usa ETag s apropiadamente. No puede esperar que el servidor de almacenamiento en caché inspeccione los contenidos para los ETag s; los contenidos se pueden encriptar. Y no puede esperar que el servidor notifique a las memorias caché que los registros deben invalidarse: las memorias caché no se registran en los servidores.

Entonces, ¿hay encabezados que me estoy perdiendo? Las cosas que indican un caché deben hacer un HEAD antes de cualquier GET para ciertos recursos? Supongo que podría vivir con solicitudes dobles para cada recurso si puedo decirles a los cachés qué recursos es probable que se actualicen con frecuencia.

¿Y el problema de que un caché reciba el PUT y sepa invalidar su caché y que otro no lo vea?


Lamentablemente, el almacenamiento en caché de HTTP se basa en URI exactos, y no puede lograr un comportamiento sensato en su caso sin forzar a los clientes a realizar la revalidación de la memoria caché.

Si has tenido:

GET /farm/123 POST /farm_update/123

Podría usar el encabezado Content-Location para especificar que la segunda solicitud modificó la primera. AFAIK no puede hacer eso con múltiples URI y no he comprobado si esto funciona en clientes populares.

La solución es hacer que las páginas caduquen rápidamente y manejar If-Modified-Since o E-Tag con estado 304 Not Modified .


No puede almacenar en caché contenido dinámico (sin inconvenientes), porque ... es dinámico.


Se supone que los servidores de caché invalidan la entidad a la que hace referencia el URI al recibir un PUT (pero como habrás notado, esto no cubre todos los casos).

Aparte de esto, puede usar encabezados de control de caché en sus respuestas para limitar o evitar el almacenamiento en caché, e intente procesar los encabezados de solicitud que preguntan si el URI se ha modificado desde la última vez que se extrajo.

Este es un tema realmente complicado y, de hecho, todavía se está trabajando (por ejemplo, véase http://www.ietf.org/internet-drafts/draft-ietf-httpbis-p6-cache-05.txt ).

El almacenamiento en caché dentro de los servidores proxy no se aplica realmente si el contenido está encriptado (al menos con SSL), por lo que no debería ser un problema (aunque puede ser un problema para el cliente).


En re: respuesta de SoapBox :

  1. Creo que If-Modified-Since es el GET dos etapas que sugerí al final de mi pregunta. Parece una solución correcta donde el contenido es grande (es decir, donde el costo de duplicar el número de solicitudes y, por lo tanto, la sobrecarga se supera con las ganancias de no volver a enviar contenido. Eso no es cierto en mi ejemplo de Granjas, ya que la información de cada Granja es corta.)

  2. Es perfectamente razonable construir un sistema que envíe contenido encriptado a través de un canal no encriptado (HTTP). Imagínese el escenario de una arquitectura orientada a servicios donde las actualizaciones son poco frecuentes y los GET son (a) frecuentes, (b) deben ser extremadamente rápidos, y (c) deben estar encriptados. Construiría un servidor que requiere un encabezado FROM (o, de manera equivalente, una clave API en los parámetros de solicitud), y devolverá una versión cifrada asimétricamente del contenido para el solicitante. El cifrado asimétrico es lento, pero si se almacena correctamente en la memoria caché, supera al protocolo de enlace SSL combinado (cifrado asimétrico) y al cifrado de contenido simétrico. Agregar un caché al frente de este servidor aceleraría drásticamente los GET .

  3. Un servidor de almacenamiento en caché podría almacenar en caché los GET de HTTPS durante un corto período de tiempo. Mi banco podría poner un control de caché de aproximadamente 5 minutos en la página de inicio de mi cuenta y transacciones recientes. No es muy probable que pase mucho tiempo en el sitio, por lo que las sesiones no serán muy largas, y probablemente terminaré golpeando la página principal de mi cuenta varias veces mientras busco el cheque que envié recientemente. a SnorgTees .