Estoy tratando de descubrir cómo manejar correctamente el caché del navegador web para aplicaciones de una sola página.
Tengo un diseño bastante típico: varios archivos HTML, JS y CSS que implementan el SPA, y un montón de datos JSON que consume el SPA. Los problemas surgen cuando quiero enviar una actualización: actualizo la parte estática del sitio y el código que genera el JSON al mismo tiempo, pero los navegadores de los clientes a menudo tienen la parte estática en caché, por lo que el código antiguo intenta procesar los nuevos datos y puede (dependiendo de los cambios realizados) tener problemas. (En particular, IE parece más agresivo que Chrome o Firefox sobre el uso de JS en caché sin revalidar).
¿Cuál es la mejor manera de manejar esto?
- Asegúrese de que mis cambios de JSON sean compatibles con versiones anteriores y suponga que las memorias caché del navegador caducarán en un plazo razonable.
- Incruste algún tipo de número de versión tanto en el JS estático como en el JSON, luego ejecútelo
window.location.reload(true);
si no coinciden. - Calcule la combinación apropiada de encabezados (
must-revalidate
ono-cache
lo que sea; las fuentes varían en cómo hacer esto) para garantizar que los navegadores siempre revaliden todos los recursos en cada carga, incluso si esto implica algunos viajes de ida y vuelta adicionales para cargar el sitio. - Microgestione mi control de caché y caduca los encabezados para que el contenido estático caduque cuando quiera enviar una actualización.
- ¿Algo más?
fuente
Respuestas:
Necesita una solución de eliminación de caché . La función del busting de caché es:
En un proyecto basado en Grunt es común usar grunt-rev para garantizar que todos los archivos que necesitan actualizarse reciban nombres únicos, en función de su contenido.
Si se asegura de que sus archivos JSON obtengan nombres de archivos de almacenamiento en caché junto con las referencias a ellos en su Javascript, los clientes siempre cargarán los archivos JSON que el Javascript espera.
La ventaja de los nombres de archivos basados en hash es que los archivos que no han cambiado obtendrán los mismos nombres de archivo después de la eliminación de la memoria caché, por lo que los navegadores pueden continuar usando el contenido en caché de forma segura cuando no haya cambiado.
Obviamente, este es el tipo de cosas que desea automatizar como parte de la compilación de producción de su proyecto para que no tenga que realizar un seguimiento de los cambios de nombres y referencias de archivos manualmente.
fuente
Puede usar
if-modified-since + last-modified
oif-none-match + etag
encabezados junto con elcache-control
encabezado adecuado . (Puede haber errores del navegador , pero nada que no pueda administrar en los navegadores recientes).Si los archivos son estáticos, le sugiero que los use
if-modified-since
, ya que se puede hacer automáticamente con un servidor HTTP bien configurado. Debería devolver 304 si el archivo no se modifica desde la última descarga.No creo que tu # 1 y # 2 funcionen a largo plazo. El # 3 o # 4 puede funcionar. El # 3 es más simple, pero debe aprender a lidiar con este problema solo una vez. Así que probaría el # 4 si fuera usted, pero la solución podría depender de qué navegadores usen sus clientes ... Por ejemplo, IE8 tiene problemas al actualizar el caché ajax, etc.
fuente
Si puede incluir Java Servlet Filter en su SPA, aquí hay una solución de trabajo: CorrectBrowserCacheHandlerFilter.java
Básicamente, cuando su navegador solicita los archivos estáticos, el servidor redirigirá todas las solicitudes a la misma pero con un parámetro de consulta hash (
?v=azErT
por ejemplo) que depende del contenido del archivo estático de destino.Al hacer esto, el navegador nunca almacenará en caché los archivos estáticos declarados en su
index.html
por ejemplo (porque siempre recibió un302 Moved Temporarily
), pero solo almacenará en caché los que tengan la versión hash (el servidor responderá200
por ellos). Por lo tanto, el caché del navegador se usará de manera eficiente para aquellos archivos estáticos con versión hash.Descargo de responsabilidad: soy el autor de
CorrectBrowserCacheHandlerFilter.java
.fuente