Fuerza la actualización de los datos CSS almacenados en caché

¿Es posible forzar al navegador a actualizar el CSS en caché?

Esto no es tan simple como cada solicitud. Tenemos un sitio que ha tenido CSS estable por un tiempo.

Ahora tenemos que hacer algunas actualizaciones importantes al CSS; sin embargo, los navegadores que han guardado en caché el CSS no recibirán el nuevo CSS durante un par de días, lo que provocará problemas de procesamiento.

¿Hay alguna manera de forzar la actualización del CSS o mejor optando por las URL de CSS específicas de la versión?

Hay varias cosas a considerar y una variedad de formas de abordar esto. Primero, la especificación

¿Qué estamos tratando de lograr?

Idealmente, un recurso modificado se recuperará sin condiciones la primera vez que se solicita, y luego se recupera de un caché local hasta que caduque sin interacción posterior del servidor.

Comportamiento de almacenamiento en caché observado

Hacer un seguimiento de las diferentes permutaciones puede ser un poco confuso, así que creé la siguiente tabla. Estas observaciones se generaron al realizar solicitudes de Chrome contra IIS y observar la respuesta / comportamiento en la consola de desarrollador.

En todos los casos, una nueva URL dará como resultado HTTP 200. Lo importante es lo que sucede con las solicitudes posteriores .

+---------------------+--------------------+-------------------------+ | Type | Cache Headers | Observed Result | +---------------------+--------------------+-------------------------+ | Static filename | Expiration +1 Year | Taken from cache | | Static filename | Expire immediately | Never caches | | Static filename | None | HTTP 304 (not modified) | | | | | | Static query string | Expiration +1 Year | HTTP 304 (not modified) | | Static query string | Expire immediately | HTTP 304 (not modified) | | Static query string | None | HTTP 304 (not modified) | | | | | | Random query string | Expiration +1 Year | Never caches | | Random query string | Expire immediately | Never caches | | Random query string | None | Never caches | +---------------------+--------------------+-------------------------+ 

Sin embargo , recuerde que los navegadores y los servidores web no siempre se comportan de la manera que esperamos. Un ejemplo famoso: en 2012 Safari móvil comenzó a almacenar en caché las solicitudes POST . Los desarrolladores no estaban contentos.

Cadena de consulta

Ejemplos en la syntax ASP.Net MVC Razor, pero aplicables en casi cualquier lenguaje de procesamiento de servidor.

… dado que algunas aplicaciones tradicionalmente han usado GET y HEAD con URL de consulta (las que contienen un “?” en la parte rel_path) para realizar operaciones con efectos secundarios significativos, las memorias caché NO DEBEN tratar las respuestas a tales URI como nuevas a menos que el servidor proporcione tiempo de expiración explícito Esto significa específicamente que las respuestas de los servidores HTTP / 1.0 para dichos URI NO DEBEN tomarse de un caché.

Agregar un parámetro aleatorio al final de la URL de CSS incluida en su HTML forzará una nueva solicitud y el servidor debería responder con HTTP 200 (no 304, incluso si no se ha modificado).

  

Por supuesto, si aleatorizamos la cadena de consulta con cada solicitud, esto frustrará por completo el almacenamiento en caché. Esto rara vez / nunca es deseable para una aplicación de producción.

Si solo mantiene unas pocas URL, puede modificarlas manualmente para que contengan un número de comstackción o una fecha:

 @{ var assembly = Assembly.GetEntryAssembly(); var name = assembly.GetName(); var version = name.Version; }  

Esto causará una nueva solicitud la primera vez que el agente de usuario encuentra la URL, pero las solicitudes posteriores devolverán principalmente 304. Esto todavía provoca que se realice una solicitud, pero al menos no se sirve el archivo completo.

Modificación de camino

Una mejor solución es crear una nueva ruta. Con un poco de esfuerzo, este proceso se puede automatizar para reescribir la ruta con un número de versión (o algún otro identificador coherente).

Esta respuesta muestra algunas opciones simples y elegantes para plataformas que no son de Microsoft.

Los desarrolladores de Microsoft pueden usar un módulo HTTP que intercepta todas las solicitudes para un tipo de archivo dado o, posiblemente, aprovechar un combo de ruta / controlador MVC para servir el archivo correcto (no he visto esto hecho, pero creo que es factible) )

Por supuesto, el método más simple (no necesariamente el más rápido o el mejor) es simplemente cambiar el nombre de los archivos en cuestión con cada versión y hacer referencia a las rutas actualizadas en las tags de link .

TLDR

  • Cambiar el nombre del archivo o cadena de consulta
  • Use un cambio que solo ocurre una vez por lanzamiento
  • El cambio de nombre de archivo es preferible a un cambio de cadena de consulta
  • Configure siempre los encabezados HTTP para maximizar los beneficios del almacenamiento en caché

Creo que cambiar el nombre del archivo CSS es una idea mucho mejor. Puede que no se adapte a todas las aplicaciones, pero asegurará que el usuario solo tenga que cargar el archivo CSS una vez. Agregar una cadena aleatoria al final asegurará que tengan que descargarlo todo el tiempo. Lo mismo ocurre con el método javascript y los métodos apache anteriores. A veces, la respuesta simple puede ser la más efectiva.

Otra solución es:

  Header set Cache-Control "max-age=86400, public"  

Esto limita la edad máxima de caché a 1 día u 86400 segundos.

Yu podría hacerlo en apache …

  FileETag None  Header unset ETag Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate" Header set Pragma "no-cache" Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"