Forçar o navegador a limpar o cache


283

Existe uma maneira de colocar algum código na minha página para que, quando alguém visite um site, ele limpe o cache do navegador para que ele possa visualizar as alterações?

Idiomas usados: ASP.NET, VB.NET e, claro, HTML, CSS e jQuery.


Uma boa solução ou solução para "limpar cache" pode ser encontrada aqui: stackoverflow.com/a/43676353/2008111
caramba

Respostas:


350

Se isso ocorrer .csse .jsmudar, uma maneira de "impedir o armazenamento em cache" é anexar algo como " _versionNo" ao nome do arquivo para cada release. Por exemplo:

script_1.0.css // This is the URL for release 1.0
script_1.1.css // This is the URL for release 1.1
script_1.2.css // etc.

Ou, alternativamente, faça-o após o nome do arquivo:

script.css?v=1.0 // This is the URL for release 1.0
script.css?v=1.1 // This is the URL for release 1.1
script.css?v=1.2 // etc.

Você pode conferir este link para ver como ele poderia funcionar.


10
Essa é uma solução bastante boa e pode até ser automatizada pelo seu sistema de compilação (e deveria ser). O Stackoverflow, por exemplo, usa essa abordagem.
21449 derobert

7
SO está usando argumentos GET agora.
Saeb Amini 23/11

60
Melhor ainda é manter o nome do arquivo como está, mas anexe o número da versão como um parâmetro da string de consulta, ou seja script.js?v=1.2. (Ou, se você não estiver acompanhando as versões, use o horário da última modificação do arquivo, o que é ainda mais fácil). Não tenho certeza se é isso que o comentarista anterior quis dizer!
Doin

5
Como todos fazem isso com o controle de versão? Parece uma verdadeira dor.
Shawn

1
@ Shawn No controle de versão, você pode renderizar as <link />tags dinamicamente e injetar a versão do aplicativo como um parâmetro de string de consulta. Como alternativa, alguns CMSes terão uma "versão de recursos do cliente" como uma configuração em todo o CMS anexada - o administrador do site pode aumentar manualmente essa versão, e as atualizações do CMS também podem atualizá-la automaticamente. Conclusão: você precisa renderizar os URLs do arquivo dinamicamente.
Jeroen

103

Olhe para o controle de cache e a tag META expira .

<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="EXPIRES" CONTENT="Mon, 22 Jul 2002 11:12:01 GMT">

Outra prática comum é anexar seqüências em constante mudança ao final dos arquivos solicitados. Por exemplo:

<script type="text/javascript" src="main.js?v=12392823"></script>


44
Isso não ajudará muito no caso de já estar armazenado em cache - desde que armazenado em cache, o servidor não será consultado e, portanto, não poderá responder com nenhum cache. Além disso, essa metatag realmente não deve ser usada, como diz a nota, será quebrada com os caches da web.
Derobert

1
+1 ao que derobert disse. É sempre melhor usar cabeçalhos HTTP para sugerir uma política de cache para clientes e caches da Web, mas mesmo isso não funciona para forçar uma recarga de cache.

4
+1 para sua segunda solução. Eu tenho esse problema que o cache deve ser limpo somente na primeira vez após a atualização de algum administrador. Esta abordagem deve resolver isso
Jules Colle

Desabilitar completamente o cache geralmente é uma péssima idéia.
Jordânia

73

Atualização 2012

Essa é uma pergunta antiga, mas acho que precisa de uma resposta mais atualizada, porque agora existe uma maneira de ter mais controle do cache do site.

Em Aplicativos da Web offline (que é realmente qualquer site HTML5), você applicationCache.swapCache()pode atualizar a versão em cache do site, sem a necessidade de recarregar manualmente a página.

Este é um exemplo de código do Guia do Iniciante para Usar o Cache do Aplicativo nas Rochas HTML5, explicando como atualizar os usuários para a versão mais recente do seu site:

// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {

  window.applicationCache.addEventListener('updateready', function(e) {
    if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
      // Browser downloaded a new app cache.
      // Swap it in and reload the page to get the new hotness.
      window.applicationCache.swapCache();
      if (confirm('A new version of this site is available. Load it?')) {
        window.location.reload();
      }
    } else {
      // Manifest didn't changed. Nothing new to server.
    }
  }, false);

}, false);

Consulte também Usando o cache do aplicativo na Mozilla Developer Network para obter mais informações.

Atualização 2016

As coisas mudam rapidamente na Web. Esta pergunta foi feita em 2009 e em 2012 publiquei uma atualização sobre uma nova maneira de lidar com o problema descrito na pergunta. Mais quatro anos se passaram e agora parece que ele já está obsoleto. Agradecemos a cgaldiolo por apontar nos comentários.

Atualmente, em julho de 2016, o padrão HTML, seção 7.9, aplicativos offline da Web inclui um aviso de descontinuação:

Esse recurso está sendo removido da plataforma da Web. (Esse é um processo longo que leva muitos anos.) No momento, o uso de qualquer um dos recursos de aplicativos da Web offline é altamente desencorajado. Use trabalhadores de serviço em seu lugar.

O mesmo acontece com o uso do cache do aplicativo na Mozilla Developer Network que referenciei em 2012:

Descontinuado
Esse recurso foi removido dos padrões da Web. Embora alguns navegadores ainda possam suportá-lo, ele está sendo eliminado. Não o use em projetos antigos ou novos. As páginas ou aplicativos da Web que o utilizam podem quebrar a qualquer momento.

Consulte também Bug 1204581 - Adicione um aviso de descontinuação para o AppCache se a interceptação de busca do trabalhador de serviço estiver ativada .


1
Isso implica que você precisa usar e manter um arquivo de manifesto de cache?
Sam

Atenção: o cache de aplicativos de interface (AppCache) foi preterido
cgaldiolo

59
Então, qual é a recomendação atual a partir de 2017?
24717 Garrett

o principal problema observado neste tópico é quando o dispositivo que o visualizador está usando continua usando as versões em cache porque a memória interna do dispositivo do usuário está ficando cheia. parece ficar preso em uma versão em cache da página e não atualizará nenhum elemento no documento. isso só acontece no chrome ?? esse é o único navegador que o experimentou.
user2585548

4
2017: Use Trabalhadores do Serviço.
digitai

27

Não como tal. Um método é enviar os cabeçalhos apropriados ao fornecer conteúdo para forçar o navegador a recarregar:

Garantir que uma página da Web não seja armazenada em cache em todos os navegadores.

Se sua pesquisa "cache header"ou algo semelhante aqui no SO, você encontrará exemplos específicos do ASP.NET.

Outra maneira menos limpa, mas às vezes a única maneira de controlar os cabeçalhos no servidor, é adicionar um parâmetro GET aleatório ao recurso que está sendo chamado:

myimage.gif?random=1923849839

2
É realmente melhor versão dos arquivos corretamente. Isso é um desperdício muito grande de largura de banda e, provavelmente o mais importante, diminui bastante o site.
21769 derobert

8
Isso realmente depende da situação, não é? Se você estiver programando um CMS e precisar garantir que todos os recursos alterados sejam atualizados corretamente, às vezes não há como contornar uma dessas duas opções.
Pekka

Soluções como essa devem ser votadas negativamente. Cabe a nós manter a pegada de CO2 da Internet o mais baixa possível.
cronometrando

14

Para recursos estáticos, o armazenamento em cache correto seria usar parâmetros de consulta com o valor de cada implantação ou versão de arquivo. Isso terá efeito de limpar o cache após cada implantação.

/Content/css/Site.css?version={FileVersionNumber}

Aqui está o exemplo do ASP.NET MVC.

<link href="@Url.Content("~/Content/Css/Reset.css")?version=@this.GetType().Assembly.GetName().Version" rel="stylesheet" type="text/css" />

Não se esqueça de atualizar a versão do assembly.


Obrigado por esta resposta, mas como fazer isso quando adicionamos recursos na BundleTable, por favor?
toregua

No meu caso, isso estava retornando "0.0.0.0" como a versão. Para obter a versão da dll do seu aplicativo MVC, use isto:?version=@ViewContext.Controller.GetType().Assembly.GetName().Version
CGodo 4/13

1
Descobri que isso impede o Firefox e o Chrome de armazenar em cache todo o conteúdo.
Sam

10

Eu tive um problema semelhante e foi assim que resolvi:

  1. No index.htmlarquivo eu adicionei manifesto:

    <html manifest="cache.manifest">
  2. Na <head>seção script incluído, a atualização do cache:

    <script type="text/javascript" src="update_cache.js"></script>
  3. Na <body>seção eu inseri a função onload:

    <body onload="checkForUpdate()">
  4. Em cache.manifesteu coloquei todos os arquivos que eu quero armazenar em cache. É importante agora que funcione no meu caso (Apache) apenas atualizando cada vez que o comentário "versão". Também é uma opção para nomear arquivos com "? Ver = 001" ou algo no final do nome, mas não é necessário . Alterar apenas # version 1.01aciona o evento de atualização do cache.

    CACHE MANIFEST
    # version 1.01
    style.css
    imgs/logo.png
    #all other files

    É importante incluir os pontos 1., 2. e 3. apenas no index.html. De outra forma

    GET http://foo.bar/resource.ext net::ERR_FAILED

    ocorre porque todo arquivo "filho" tenta armazenar em cache a página enquanto a página já está em cache.

  5. No update_cache.jsarquivo eu coloquei este código:

    function checkForUpdate()
    {
        if (window.applicationCache != undefined && window.applicationCache != null)
        {
            window.applicationCache.addEventListener('updateready', updateApplication);
        }
    }
    function updateApplication(event)
    {
        if (window.applicationCache.status != 4) return;
        window.applicationCache.removeEventListener('updateready', updateApplication);
        window.applicationCache.swapCache();
        window.location.reload();
    }

Agora você acabou de alterar os arquivos e, no manifesto, precisa atualizar o comentário da versão. Agora, visitar a página index.html atualizará o cache.

As partes da solução não são minhas, mas eu as encontrei através da Internet e reunidas para que funcionem.


Posso saber onde está escrito o CACHE.MANIFEST.
Shweta Gulati

1
Shweta Gulati O arquivo de manifesto deve estar na mesma pasta que o arquivo "index". Quais são os horários em que não funciona?
Wojtek Mazurek 04/10

1
@ShwetaGulati Sim, o cache não detecta alterações nos arquivos html - é por isso que você precisa atualizar o número da versão no arquivo de manifesto, porque é o que está sendo verificado quanto a alterações. É realmente difícil ajudá-lo, porque não conheço detalhes. Por favor, diga-me se Você colocou todos os arquivos em cache desejados no manifesto? O caminho deve ser relativo ao arquivo de manifesto. Você pode me dar endereço do seu site e eu posso dizer qual é o problema :)
Wojtek Mazurek

1
@ShwetaGulati É porque o navegador armazena em cache alguns arquivos automaticamente para acelerar o carregamento da página. É um comportamento padrão e depende apenas do navegador, portanto você não pode configurá-lo de nenhuma maneira. Especialmente, os arquivos js estão no escopo do navegador, porque geralmente são usados ​​em todas as páginas do site, portanto, é aconselhável armazená-los em cache. Não há outra maneira senão gravar os nomes de todos os arquivos no arquivo de manifesto para armazenar em cache todos os arquivos. Se você encontrar algum, diga-me, porque eu preciso dele também :)
Wojtek Mazurek

1
O caminho absoluto para seus arquivos não importa. O caminho relativo do endereço é importante porque o navegador envia a solicitação de arquivos. F.ex: Eu tenho o domínio example.com e está no serwer names.com. Meu espaço é exemplo.names.com. Então, ingresso meu domínio example.com no espaço do servidor example.names.com como redirecionamento. Para fazer isso, preciso definir a pasta como objetivo desse redirecionamento. Portanto, se eu quiser ter vários sites em example.names.com, eu crio a pasta "name1", defina o redirecionamento para ela e coloque todos os meus arquivos. Os caminhos são contados a partir daqui. Se eu tiver name1 \ scripts \ test.js no arquivo de manifesto, escrevo scripts \ test.js.
Wojtek Mazurek

7

Eu tive um caso em que eu tirava fotos de clientes on-line e precisaria atualizar a div se uma foto fosse alterada. O navegador ainda estava mostrando a foto antiga. Então, eu usei o hack de chamar uma variável aleatória GET, que seria única todas as vezes. Aqui está, se isso pudesse ajudar alguém

<img src="/photos/userid_73.jpg?random=<?php echo rand() ?>" ...

EDITAR Como apontado por outros, a seguir é uma solução muito mais eficiente, uma vez que recarregará as imagens somente quando elas forem alteradas, identificando essa alteração pelo tamanho do arquivo:

<img src="/photos/userid_73.jpg?modified=<? filemtime("/photos/userid_73.jpg")?>"

29
Isso não é nada elegante, faria com que o site recarregasse a imagem toda vez que perdesse muito tempo fazendo o download de recursos; uma solução melhor seria usar o tamanho do arquivo em vez de um número aleatório; isso fará com que o cache revalide apenas quando o arquivo realmente alterações
Roberto Arosemena 06/01

8
Ou um hash da imagem bytes
Taylor Edmiston

1
Tudo depende dos requisitos do usuário. Para um grande número de fotos, o cenário seria diferente de algumas fotos. A verificação do tamanho do arquivo economizaria largura de banda, mas também adicionaria processamento extra, potencialmente diminuindo o carregamento da página. No meu caso, em que as imagens mudavam com bastante frequência e era uma decisão crítica dos negócios que o usuário recebesse as mais atualizadas, essa era uma solução perfeita.
zeeshan

Você pode torná-lo um valor estático na configuração, mesmo que isso não seja de forma alguma uma abordagem ideal.
vidente

3
<img src = "/ photos / userid_73.jpg? modified = <? = filemtime (" / photos / userid_73.jpg ")?>" seria muito mais útil!
Fusca Software

4

Muitas respostas estão faltando ao ponto - a maioria dos desenvolvedores sabe que desligar o cache é ineficiente. No entanto, existem muitas circunstâncias comuns em que a eficiência não é importante e o comportamento do cache padrão é bastante prejudicado.

Isso inclui testes de script iterativos aninhados (o maior!) E soluções alternativas de software de terceiros quebradas. Nenhuma das soluções fornecidas aqui é adequada para abordar esses cenários comuns. A maioria dos navegadores da Web é um cache muito agressivo e não oferece meios adequados para evitar esses problemas.



2

Atualizar o URL para o seguinte funciona para mim:

/custom.js?id=1

Ao adicionar um número único depois ?id=e incrementá-lo para novas alterações, os usuários não precisam pressionarCTRL + F5 para atualizar o cache. Como alternativa, você pode anexar a versão hash ou string do horário atual ou da Epoch após?id=

Algo como ?id=1520606295


1

Aqui está a página MDSN sobre a configuração do cache no ASP.NET.

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
Response.Cache.SetCacheability(HttpCacheability.Public)
Response.Cache.SetValidUntilExpires(False)
Response.Cache.VaryByParams("Category") = True

If Response.Cache.VaryByParams("Category") Then
   '...
End If

1

Não tenho certeza se isso pode realmente ajudá-lo, mas é assim que o cache deve funcionar em qualquer navegador. Quando o navegador solicita um arquivo, ele deve sempre enviar uma solicitação ao servidor, a menos que exista um modo "offline". O servidor irá ler alguns parâmetros como data de modificação ou etags.

O servidor retornará uma resposta de erro 304 para NÃO MODIFICADO e o navegador precisará usar seu cache. Se o etag não for validado no lado do servidor ou a data de modificação estiver abaixo da data de modificação atual, o servidor deverá retornar o novo conteúdo com a nova data ou etags modificadas ou ambas.

Se não houver dados de cache enviados ao navegador, acho que o comportamento é indeterminado, o navegador pode ou não armazenar em cache arquivos que não informam como eles são armazenados em cache. Se você definir parâmetros de armazenamento em cache na resposta, os arquivos serão armazenados em cache corretamente e o servidor poderá optar por retornar um erro 304 ou o novo conteúdo.

É assim que deve ser feito. Usar parâmetros aleatórios ou número de versão em URLs é mais um truque do que qualquer coisa.

http://www.checkupdown.com/status/E304.html http://en.wikipedia.org/wiki/HTTP_ETag http://www.xpertdeveloper.com/2011/03/last-modified-header-vs- expire-header-vs-etag /

Depois de ler, vi que também há uma data de validade. Se você tiver algum problema, pode ser que você tenha uma data de validade configurada. Em outras palavras, quando o navegador armazenará o arquivo em cache, já que ele tem uma data de validade, ele não deverá solicitá-lo novamente antes dessa data. Em outras palavras, ele nunca solicitará o arquivo ao servidor e nunca receberá um 304 não modificado. Ele simplesmente usará o cache até que a data de validade seja atingida ou o cache seja limpo.

Portanto, esse é meu palpite: você tem algum tipo de data de validade e deve usar etags da última modificação ou uma mistura de tudo e garantir que não haja uma data de validade.

Se as pessoas tendem a atualizar muito e o arquivo não sofrer muitas alterações, pode ser aconselhável definir uma grande data de validade.

Meus 2 centavos!


1

Eu implementei esta solução simples que funciona para mim (ainda não no ambiente de produção):

function verificarNovaVersio() {
    var sVersio = localStorage['gcf_versio'+ location.pathname] || 'v00.0.0000';
    $.ajax({
        url: "./versio.txt"
        , dataType: 'text'
        , cache: false
        , contentType: false
        , processData: false
        , type: 'post'
     }).done(function(sVersioFitxer) {
        console.log('Versió App: '+ sVersioFitxer +', Versió Caché: '+ sVersio);
        if (sVersio < (sVersioFitxer || 'v00.0.0000')) {
            localStorage['gcf_versio'+ location.pathname] = sVersioFitxer;
            location.reload(true);
        }
    });
}

Eu tenho um pequeno arquivo localizado onde estão o html:

"versio.txt":

v00.5.0014

Essa função é chamada em todas as minhas páginas; portanto, ao carregá-la, verifique se o valor da versão do localStorage é menor que a versão atual e faz um

location.reload(true);

... para forçar a recarga do servidor em vez do cache.

(obviamente, em vez de localStorage, você pode usar cookies ou outro armazenamento persistente do cliente)

Optei por esta solução por sua simplicidade, porque apenas a manutenção de um único arquivo "versio.txt" forçará o recarregamento do site completo.

O método queryString é difícil de implementar e também é armazenado em cache (se você mudar da v1.1 para uma versão anterior será carregada do cache, isso significa que o cache não será liberado, mantendo todas as versões anteriores no cache).

Sou um pouco novato e agradeceria sua verificação e revisão profissional para garantir que meu método seja uma boa abordagem.

Espero que ajude.



0

Existe um truque que pode ser usado. O truque é anexar um parâmetro / string ao nome do arquivo na tag de script e alterá-lo quando o arquivo for alterado.

<script src="myfile.js?version=1.0.0"></script>

O navegador interpreta toda a cadeia de caracteres como o caminho do arquivo, mesmo que o que vem depois do "?" são parâmetros. Então, o que acontece agora é que, na próxima vez em que você atualizar seu arquivo, altere o número na tag de script no seu site (exemplo <script src="myfile.js?version=1.0.1"></script>) e cada navegador de usuários verá que o arquivo foi alterado e pega uma nova cópia.


0

Forçar navegadores a limpar o cache ou recarregar os dados corretos?Eu tentei a maioria das soluções descritas no stackoverflow, algumas funcionam, mas depois de um tempo, ele acaba armazenando em cache e exibindo o script ou arquivo carregado anteriormente. Existe outra maneira de limpar o cache (css, js, etc) e realmente funcionar em todos os navegadores?

Descobri até agora que recursos específicos podem ser recarregados individualmente se você alterar a data e a hora em seus arquivos no servidor. "Limpar cache" não é tão fácil como deveria ser. Em vez de limpar o cache em meus navegadores, percebi que "tocar" nos arquivos do servidor em cache altera a data e a hora do arquivo de origem em cache no servidor (Testado no Edge, Chrome e Firefox) e a maioria dos navegadores baixa automaticamente os arquivos mais cópia atualizada atual do que está no seu servidor (código, gráficos também multimídia). Eu sugiro que você copie os scripts mais atuais no servidor e a solução "faça o que é necessário" antes da execução do programa, para que ele altere a data de todos os seus arquivos com problemas para a data e hora mais atuais e faça o download de uma nova cópia para o seu navegador:

<?php
   touch('/www/sample/file1.css');
   touch('/www/sample/file2.js');
?>

então ... o resto do seu programa ...

Levei algum tempo para resolver esse problema (como muitos navegadores agem de maneira diferente com comandos diferentes, mas todos verificam a hora dos arquivos e se comparam à sua cópia baixada no navegador, se houver data e hora diferentes, a atualização será feita). Não é possível seguir o caminho certo, sempre há outra solução melhor e utilizável. Cumprimentos e acampamento feliz. A propósito, toque (); ou alternativas funcionam em muitas linguagens de programação, inclusive em javascript bash sh php e você pode incluí-las ou chamá-las em html.


1
se o arquivo for modificado, o carimbo de data e hora já será alterado, portanto, não há benefício em forçá-lo novamente.
Fusca Software

O comando touch não altera o arquivo. Ele altera o atributo de data e hora, convertendo-o para uma versão mais recente, enganando o navegador para fazer o download como nova cópia.
Luis H Cabrejo 17/10/2018

-1

Deseja limpar o cache ou apenas garantir que sua página atual (alterada?) Não esteja em cache?

Neste último caso, deve ser tão simples quanto

<META HTTP-EQUIV="Pragma" CONTENT="no-cache">

Li recentemente sobre essa abordagem em uma postagem do Chrome e só encontrei resultados consistentes em alguns servidores ativos, host local e compartilhamento de arquivos do Windows ... com o Firefox 3.6.
danjah 27/05
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.