Pregunta

Actualmente estamos trabajando en una versión beta privada y, por lo tanto, todavía estamos en el proceso de realizar cambios bastante rápidos, aunque obviamente, a medida que el uso comience a aumentar, ralentizaremos este proceso.Dicho esto, un problema con el que nos encontramos es que después de publicar una actualización con nuevos archivos JavaScript, los navegadores del cliente todavía usan la versión en caché del archivo y no ven la actualización.Obviamente, en una llamada de soporte, simplemente podemos informarles que hagan una controlF5 actualice para asegurarse de que obtengan los archivos actualizados del servidor, pero sería preferible manejar esto antes de ese momento.

Nuestra idea actual es simplemente adjuntar un número de versión al nombre de los archivos JavaScript y luego, cuando se realicen cambios, incrementar la versión en el script y actualizar todas las referencias.Esto definitivamente hace el trabajo, pero actualizar las referencias en cada versión puede resultar engorroso.

Como estoy seguro de que no somos los primeros en lidiar con esto, pensé en decírselo a la comunidad.¿Cómo se asegura de que los clientes actualicen su caché cuando actualiza su código?Si está utilizando el método descrito anteriormente, ¿está utilizando un proceso que simplifica el cambio?

¿Fue útil?

Solución

Hasta donde yo sé, una solución común es agregar un ?<version> al enlace src del script.

Por ejemplo:

<script type="text/javascript" src="myfile.js?1500"></script>

Supongo en este punto que no hay mejor manera que buscar y reemplazar para incrementar estos "números de versión" en todas las etiquetas del script.

¿Es posible que tenga un sistema de control de versiones que haga eso por usted?La mayoría de los sistemas de control de versiones tienen una forma de inyectar automáticamente el número de revisión al realizar el check-in, por ejemplo.

Se vería algo como esto:

<script type="text/javascript" src="myfile.js?$$REVISION$$"></script>

Por supuesto, siempre hay mejores soluciones como Éste.

Otros consejos

Agregar la hora actual a la URL es de hecho una solución común.Sin embargo, también puedes gestionar esto a nivel del servidor web, si así lo deseas.El servidor se puede configurar para enviar diferentes encabezados HTTP para archivos javascript.

Por ejemplo, para forzar que el archivo se almacene en caché por no más de 1 día, enviaría:

Cache-Control: max-age=86400, must-revalidate

Para la versión beta, si desea obligar al usuario a obtener siempre la última versión, deberá utilizar:

Cache-Control: no-cache, must-revalidate

Velocidad de página de Google:No incluya una cadena de consulta en la URL de recursos estáticos.La mayoría de los proxies, sobre todo en calamar a través de la versión 3.0, no almacenan en caché los recursos con un "?" En su URL, incluso si un control de caché:El encabezado público está presente en la respuesta.Para habilitar el almacenamiento en caché de proxy para estos recursos, elimine las cadenas de consulta de las referencias a recursos estáticos y, en su lugar, codifique los parámetros en los nombres de los archivos.

En este caso, puede incluir la versión en la URL, por ejemplo: http://abc.com/v1.2/script.js y use apache mod_rewrite para redirigir el enlace a http://abc.com/script.js.Cuando cambie la versión, el navegador del cliente actualizará el nuevo archivo.

Este uso ha quedado obsoleto: https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache

Esta respuesta tiene solo 6 años de retraso, pero no veo esta respuesta en muchos lugares...HTML5 ha introducido Caché de aplicaciones que se utiliza para resolver este problema.Descubrí que el nuevo código de servidor que estaba escribiendo fallaba el antiguo javascript almacenado en los navegadores de las personas, así que quería encontrar una manera de hacer caducar su javascript.Utilice un archivo de manifiesto similar a este:

CACHE MANIFEST
# Aug 14, 2014
/mycode.js

NETWORK:
*

y genere este archivo con una nueva marca de tiempo cada vez que desee que los usuarios actualicen su caché.Como nota al margen, si agrega esto, el navegador no recargar (incluso cuando un usuario actualiza la página) hasta que el manifiesto se lo indique.

¿Qué tal si agregamos el tamaño de archivo como parámetro de carga?

<script type='text/javascript' src='path/to/file/mylibrary.js?filever=<?=filesize('path/to/file/mylibrary.js')?>'></script>

Entonces, cada vez que actualiza el archivo, el parámetro "filever" cambia.

¿Qué tal cuando actualiza el archivo y su actualización da como resultado el mismo tamaño de archivo?¿Cuáles son las probabilidades?

No todos los navegadores almacenan en caché archivos con '?' en eso.Lo que hice para asegurarme de que se almacenara en caché tanto como fuera posible fue incluir la versión en el nombre del archivo.

Así que en lugar de stuff.js?123, Hice stuff_123.js

solía mod_redirect(creo) en apache a a have stuff_*.js ir stuff.js

Para páginas ASP.NET estoy usando lo siguiente

ANTES

<script src="/Scripts/pages/common.js" type="text/javascript"></script>

DESPUÉS (forzar recarga)

<script src="/Scripts/pages/common.js?ver<%=DateTime.Now.Ticks.ToString()%>" type="text/javascript"></script>

Agregar DateTime.Now.Ticks funciona muy bien.

Para ASP.NET supongo que la siguiente solución con opciones avanzadas (modo de depuración/liberación, versiones):

Archivos Js o Css incluidos de esta manera:

<script type="text/javascript" src="Scripts/exampleScript<%=Global.JsPostfix%>" />
<link rel="stylesheet" type="text/css" href="Css/exampleCss<%=Global.CssPostfix%>" />

Global.JsPostfix y Global.CssPostfix se calculan de la siguiente manera en Global.asax:

protected void Application_Start(object sender, EventArgs e)
{
    ...
    string jsVersion = ConfigurationManager.AppSettings["JsVersion"];
    bool updateEveryAppStart = Convert.ToBoolean(ConfigurationManager.AppSettings["UpdateJsEveryAppStart"]);
    int buildNumber = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Revision;
    JsPostfix = "";
#if !DEBUG
    JsPostfix += ".min";
#endif      
    JsPostfix += ".js?" + jsVersion + "_" + buildNumber;
    if (updateEveryAppStart)
    {
        Random rand = new Random();
        JsPosfix += "_" + rand.Next();
    }
    ...
}

Si está generando la página que enlaza con los archivos JS, una solución simple es agregar la marca de tiempo de la última modificación del archivo a los enlaces generados.

Esto es muy similar a la respuesta de Huppie, pero funciona en sistemas de control de versiones sin sustitución de palabras clave.También es mejor que agregar la hora actual, ya que eso evitaría el almacenamiento en caché incluso cuando el archivo no haya cambiado en absoluto.

Hemos estado creando un SaaS para los usuarios y proporcionándoles un script para adjuntarlo en la página de su sitio web, y no fue posible adjuntar una versión con el script ya que el usuario adjuntará el script a su sitio web para obtener funcionalidades y no puedo forzarlos. cambiar la versión cada vez que actualizamos el script

Entonces, encontramos una manera de cargar la versión más nueva del script cada vez que el usuario llama al script original.

el enlace del script proporcionado al usuario

<script src="https://thesaasdomain.com/somejsfile.js" data-ut="user_token"></script>

el archivo de secuencia de comandos

if($('script[src^="https://thesaasdomain.com/somejsfile.js?"]').length !== 0) {
   init();
} else {
   loadScript("https://thesaasdomain.com/somejsfile.js?" + guid());
}

var loadscript = function(scriptURL) {
   var head = document.getElementsByTagName('head')[0];
   var script = document.createElement('script');
   script.type = 'text/javascript';
   script.src = scriptURL;
   head.appendChild(script);
}

var guid = function() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}

var init = function() {
    // our main code
}

Explicación:

El usuario adjuntó el script que se le proporcionó en su sitio web y verificamos si el token único adjunto al script existe o no usa el selector jQuery y, si no, lo cargamos dinámicamente con el token (o versión) más nuevo.

Esto es llamar al mismo script dos veces, lo que podría ser un problema de rendimiento, pero realmente resuelve el problema de forzar que el script no se cargue desde el caché sin poner la versión en el enlace del script real proporcionado al usuario o cliente.

Descargo de responsabilidad:No lo utilice si el rendimiento es un gran problema en su caso.

La función jQuery getScript también se puede utilizar para garantizar que se cargue un archivo js cada vez que se carga la página.

Así es como lo hice:

$(document).ready(function(){
    $.getScript("../data/playlist.js", function(data, textStatus, jqxhr){
         startProgram();
    });
});

Compruebe la función en http://api.jquery.com/jQuery.getScript/

De forma predeterminada, $.getScript() establece la configuración de caché en falso.Esto agrega un parámetro de consulta con marca de tiempo a la URL de solicitud para garantizar que el navegador descargue el script cada vez que se solicita.

Una solución es agregar una cadena de consulta con una marca de tiempo a la URL al recuperar el recurso.Esto aprovecha el hecho de que un navegador no almacenará en caché los recursos obtenidos de URL que contengan cadenas de consulta.

Sin embargo, probablemente no desee que el navegador no almacene en caché estos recursos;es más probable que desee almacenarlos en caché, pero desea que el navegador obtenga una nueva versión del archivo cuando esté disponible.

La solución más común parece ser incrustar una marca de tiempo o un número de revisión en el nombre del archivo.Esto requiere un poco más de trabajo, porque su código debe modificarse para solicitar los archivos correctos, pero significa que, por ejemplo.versión 7 de tu snazzy_javascript_file.js (es decir. snazzy_javascript_file_7.js) se almacena en caché en el navegador hasta que lanza la versión 8, y luego su código cambia para buscar snazzy_javascript_file_8.js en cambio.

Usa una versión GET variable para evitar el almacenamiento en caché del navegador.

Anexando ?v=AUTO_INCREMENT_VERSION al final de su URL evita el almacenamiento en caché del navegador, evitando todos y cada uno de los scripts almacenados en caché.

Mi colega acaba de encontrar una referencia a ese método justo después de que publiqué (en referencia a CSS) en http://www.stefanhayden.com/blog/2006/04/03/css-caching-hack/.Es bueno ver que otros lo están usando y parece funcionar.Supongo en este punto que no hay mejor manera que buscar y reemplazar para incrementar estos "números de versión" en todas las etiquetas del script.

Aunque es un marco específico, Django 1.4 tiene esta funcionalidad que funciona de manera similar al enlace al sitio 'greenfelt' en el respuesta anterior

En PHP:

function latest_version($file_name){
    echo $file_name."?".filemtime($_SERVER['DOCUMENT_ROOT'] .$file_name);
}

En HTML:

<script type="text/javascript" src="<?php latest_version('/a-o/javascript/almanacka.js'); ?>">< /script>

Cómo funciona:

En HTML, escriba el filepath y nombre como lo haría, pero solo en la función.PHP obtiene el filetime del archivo y devuelve el filepath+name+"?"+time del último cambio

La eliminación de caché en ASP.NET Core a través de un asistente de etiquetas se encargará de esto por usted y permitirá que su navegador mantenga scripts/css en caché hasta que el archivo cambie.Simplemente agregue la etiqueta auxiliar asp-append-version="true" a su etiqueta de script (js) o enlace (css):

<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true"/>

Dave Paquette tiene un buen ejemplo y una explicación de la eliminación de caché aquí (al final de la página) Eliminación de caché

La práctica común hoy en día es generar un código hash de contenido como parte del nombre del archivo para obligar al navegador, especialmente IE, a recargar los archivos javascript o css.

Por ejemplo,

proveedor.a7561fb0e9a071baadb9.js
principal.b746e3eb72875af2caa9.js

Generalmente es el trabajo de las herramientas de compilación como webpack.aqui hay mas detalles Si alguien quiere probar si está utilizando webpack.

¿La solución más sencilla?No dejes que el navegador almacene caché en absoluto.Agregue la hora actual (en ms) como consulta.

(Aún estás en versión beta, por lo que podrías presentar argumentos razonables para no optimizar el rendimiento.Pero aquí YMMV.)

La ventaja de utilizar un file.js?V=1 sobre un fileV1.js es que no necesita almacenar múltiples versiones de los archivos JavaScript en el servidor.

El problema que veo con file.js?V=1 es que es posible que tengas código dependiente en otro archivo JavaScript que se rompa al usar la nueva versión de las utilidades de la biblioteca.

Por razones de compatibilidad con versiones anteriores, creo que es mucho mejor usar jQuery.1.3.js para sus nuevas páginas y permitir que las páginas existentes utilicen jQuery.1.1.js, hasta que esté listo para actualizar las páginas más antiguas, si es necesario.

Una forma sencilla.Editar acceso directo

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} \.(jpe?g|bmp|png|gif|css|js|mp3|ogg)$ [NC]
RewriteCond %{QUERY_STRING} !^(.+?&v33|)v=33[^&]*(?:&(.*)|)$ [NC]
RewriteRule ^ %{REQUEST_URI}?v=33 [R=301,L]

En asp.net mvc puedes usar @DateTime.UtcNow.ToString() para el número de versión del archivo js.El número de versión cambia automáticamente con la fecha y obliga al navegador del cliente a actualizar automáticamente el archivo js.Utilizo este método y funciona bien.

<script src="~/JsFilePath/JsFile.js?v=@DateTime.UtcNow.ToString()"></script>

A continuación funcionó para mí:

<head>
<meta charset="UTF-8">
<meta http-equiv="cache-control" content="no-cache, must-revalidate, post-check=0, pre-check=0" />
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />
</head>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top