Pergunta

No momento, estamos trabalhando em uma versão beta privada e, portanto, ainda estamos no processo de fazer mudanças bastante rápidas, embora, obviamente, à medida que o uso está começando a aumentar, iremos desacelerar esse processo.Dito isso, um problema que estamos enfrentando é que depois de enviarmos uma atualização com novos arquivos JavaScript, os navegadores clientes ainda usam a versão em cache do arquivo e não veem a atualização.Obviamente, numa chamada de suporte, podemos simplesmente informá-los para fazerem uma CtrlF5 atualize para garantir que eles obtenham os arquivos atualizados do servidor, mas seria preferível lidar com isso antes desse horário.

Nosso pensamento atual é simplesmente anexar um número de versão ao nome dos arquivos JavaScript e então, quando alterações forem feitas, incrementar a versão no script e atualizar todas as referências.Isso definitivamente dá conta do recado, mas atualizar as referências em cada versão pode ser complicado.

Como tenho certeza de que não somos os primeiros a lidar com isso, resolvi lançar o assunto para a comunidade.Como você garante que os clientes atualizem o cache quando você atualiza seu código?Se estiver usando o método descrito acima, você está usando um processo que simplifica a mudança?

Foi útil?

Solução

Pelo que eu sei, uma solução comum é adicionar um ?<version> para o link src do script.

Por exemplo:

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

Presumo neste ponto que não há maneira melhor do que localizar e substituir para incrementar esses "números de versão" em todas as tags de script.

Você pode ter um sistema de controle de versão fazendo isso por você?A maioria dos sistemas de controle de versão tem uma maneira de injetar automaticamente o número de revisão no check-in, por exemplo.

Seria algo assim:

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

Claro, sempre existem soluções melhores, como Este.

Outras dicas

Acrescentar a hora atual ao URL é de fato uma solução comum.No entanto, você também pode gerenciar isso no nível do servidor web, se desejar.O servidor pode ser configurado para enviar diferentes cabeçalhos HTTP para arquivos javascript.

Por exemplo, para forçar o armazenamento em cache do arquivo por no máximo 1 dia, você enviaria:

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

Para beta, se você quiser forçar o usuário a sempre obter as últimas novidades, você usaria:

Cache-Control: no-cache, must-revalidate

Velocidade da página do Google:Não inclua uma string de consulta na URL para recursos estáticos.A maioria dos proxies, principalmente luta na versão 3.0, não cache os recursos com um "?" em seu URL, mesmo que um controle de cache:o cabeçalho público está presente na resposta.Para ativar o cache de proxy para esses recursos, remova as cadeias de consulta das referências a recursos estáticos e, em vez disso, codifique os parâmetros nos próprios nomes dos arquivos.

Neste caso, você pode incluir a versão no URL, por exemplo: http://abc.com/v1.2/script.js e use apache mod_rewrite para redirecionar o link para http://abc.com/script.js.Quando você altera a versão, o navegador do cliente atualizará o novo arquivo.

Este uso foi preterido: https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache

Esta resposta está atrasada apenas 6 anos, mas não vejo essa resposta em muitos lugares ...HTML5 introduziu Cache de aplicativo que é usado para resolver este problema.Eu estava descobrindo que o novo código de servidor que estava escrevendo estava travando o javascript antigo armazenado nos navegadores das pessoas, então queria encontrar uma maneira de expirar o javascript.Use um arquivo de manifesto parecido com este:

CACHE MANIFEST
# Aug 14, 2014
/mycode.js

NETWORK:
*

e gere esse arquivo com um novo carimbo de data/hora sempre que desejar que os usuários atualizem seu cache.Como observação lateral, se você adicionar isso, o navegador irá não recarregar (mesmo quando um usuário atualiza a página) até que o manifesto solicite.

Que tal adicionar o tamanho do arquivo como parâmetro de carregamento?

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

Portanto, toda vez que você atualiza o arquivo, o parâmetro "filever" muda.

E quando você atualiza o arquivo e sua atualização resulta no mesmo tamanho de arquivo?Quais são as hipóteses?

Nem todos os navegadores armazenam arquivos em cache com '?' iniciar.O que fiz para garantir que fosse armazenado em cache tanto quanto possível, incluí a versão no nome do arquivo.

Então, em vez de stuff.js?123, Eu fiz stuff_123.js

eu usei mod_redirect(eu acho) no apache para have stuff_*.js ir stuff.js

Para páginas ASP.NET estou usando o seguinte

ANTES

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

DEPOIS (forçar recarga)

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

Adicionar DateTime.Now.Ticks funciona muito bem.

Para ASP.NET, suponho a próxima solução com opções avançadas (modo de depuração/liberação, versões):

Arquivos Js ou CSS incluídos desta forma:

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

Global.JsPostfix e Global.CssPostfix são calculados da seguinte maneira em 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();
    }
    ...
}

Se você estiver gerando a página vinculada aos arquivos JS, uma solução simples é anexar o carimbo de data/hora da última modificação do arquivo aos links gerados.

Isso é muito semelhante à resposta do Huppie, mas funciona em sistemas de controle de versão sem substituição de palavras-chave.Também é melhor do que acrescentar a hora atual, pois isso impediria o armazenamento em cache mesmo quando o arquivo não fosse alterado.

Estamos criando um SaaS para os usuários e fornecendo a eles um script para anexar na página do site, e não foi possível anexar uma versão com o script, pois o usuário anexará o script ao site para obter funcionalidades e não posso forçá-los para alterar a versão cada vez que atualizarmos o script

Então, encontramos uma maneira de carregar a versão mais recente do script cada vez que o usuário chama o script original

o link do script fornecido ao usuário

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

o arquivo de script

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
}

Explicação:

O usuário anexou o script fornecido a ele em seu site e verificamos se o token exclusivo anexado ao script existe ou não usando o seletor jQuery e, se não, carregamos-o dinamicamente com o token (ou versão) mais recente

Isso chama o mesmo script duas vezes, o que pode ser um problema de desempenho, mas realmente resolve o problema de forçar o script a não carregar do cache sem colocar a versão no link do script real fornecido ao usuário ou cliente

Isenção de responsabilidade:Não use se o desempenho for um grande problema no seu caso.

A função jQuery getScript também pode ser usada para garantir que um arquivo js seja realmente carregado sempre que a página for carregada.

Foi assim que eu fiz:

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

Verifique a função em http://api.jquery.com/jQuery.getScript/

Por padrão, $.getScript() define a configuração de cache como falsa.Isso anexa um parâmetro de consulta com carimbo de data/hora ao URL de solicitação para garantir que o navegador baixe o script sempre que ele for solicitado.

Uma solução é anexar uma string de consulta com um carimbo de data/hora ao URL ao buscar o recurso.Isso aproveita o fato de que um navegador não armazenará em cache recursos obtidos de URLs que contenham strings de consulta.

Você provavelmente não deseja que o navegador não armazene esses recursos em cache;é mais provável que você queira armazená-los em cache, mas deseja que o navegador busque uma nova versão do arquivo quando ele for disponibilizado.

A solução mais comum parece ser incorporar um carimbo de data/hora ou número de revisão no próprio nome do arquivo.Isso é um pouco mais trabalhoso, porque seu código precisa ser modificado para solicitar os arquivos corretos, mas significa que, por exemplo.versão 7 do seu snazzy_javascript_file.js (ou seja, snazzy_javascript_file_7.js) é armazenado em cache no navegador até o lançamento da versão 8 e, então, seu código muda para buscar snazzy_javascript_file_8.js em vez de.

Usar uma versão GET variável para evitar o cache do navegador.

Anexando ?v=AUTO_INCREMENT_VERSION ao final do seu URL impede o cache do navegador - evitando todo e qualquer script armazenado em cache.

Meu colega encontrou uma referência a esse método logo após eu postar (em referência ao css) em http://www.stefanhayden.com/blog/2006/04/03/css-caching-hack/.É bom ver que outras pessoas estão usando e parece funcionar.Presumo neste ponto que não há maneira melhor do que localizar e substituir para incrementar esses "números de versão" em todas as tags de script.

Embora seja específico do framework, o Django 1.4 tem esta funcionalidade que funciona de forma semelhante ao link para o site 'greenfelt' no resposta acima

Em PHP:

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

Em HTML:

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

Como funciona:

Em HTML, escreva o filepath e nomeie como faria, mas apenas na função.PHP obtém o filetime do arquivo e retorna o filepath+name+"?"+time da última mudança

O bloqueio de cache no ASP.NET Core por meio de um auxiliar de tag cuidará disso para você e permitirá que seu navegador mantenha scripts/css em cache até que o arquivo seja alterado.Basta adicionar o auxiliar de tag asp-append-version="true" à sua tag de script (js) ou link (css):

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

Dave Paquette tem um bom exemplo e explicação sobre invasão de cache aqui (parte inferior da página) Rebentamento de cache

A prática comum hoje em dia é gerar um código hash de conteúdo como parte do nome do arquivo para forçar o navegador, especialmente o IE, a recarregar os arquivos javascript ou css.

Por exemplo,

fornecedor.a7561fb0e9a071baadb9.js
principal.b746e3eb72875af2caa9.js

Geralmente é o trabalho das ferramentas de construção, como o webpack.Aqui está mais detalhes se alguém quiser experimentar se você estiver usando o webpack.

Solução mais simples?Não deixe o navegador armazenar em cache.Acrescente a hora atual (em ms) como uma consulta.

(Você ainda está na versão beta, portanto, poderia apresentar um argumento razoável para não otimizar o desempenho.Mas YMMV aqui.)

A vantagem de usar um file.js?V=1 através de um fileV1.js é que você não precisa armazenar várias versões dos arquivos JavaScript no servidor.

O problema que vejo com file.js?V=1 é que você pode ter código dependente em outro arquivo JavaScript que quebra ao usar a nova versão dos utilitários da biblioteca.

Por uma questão de compatibilidade com versões anteriores, acho muito melhor usar jQuery.1.3.js para suas novas páginas e permitir que as páginas existentes usem jQuery.1.1.js, até que você esteja pronto para atualizar as páginas mais antigas, se necessário.

Uma maneira simples.Editar htaccess

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]

No asp.net mvc você pode usar @DateTime.UtcNow.ToString() para o número da versão do arquivo js.O número da versão muda automaticamente com a data e você força o navegador do cliente a atualizar automaticamente o arquivo js.Estou usando esse método e funciona bem.

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

Abaixo funcionou para mim:

<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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top