O que acrescenta "? V = 1" aos URLs CSS e Javascript nas tags de link e script?

138

Eu estive pesquisando um modelo de clichê HTML 5 (em http://html5boilerplate.com/ ) e notei o uso de "?v=1"URLs ao me referir a arquivos CSS e Javascript.

  1. O que acrescenta "?v=1"aos URLs CSS e Javascript nas tags de link e script?
  2. Nem todos os URLs Javascript possuem o "?v=1"(exemplo da amostra abaixo:) js/modernizr-1.5.min.js. Existe uma razão para que este seja o caso?

Amostra de index.html:

<!-- CSS : implied media="all" -->
<link rel="stylesheet" href="css/style.css?v=1">

<!-- For the less-enabled mobile browsers like Opera Mini -->
<link rel="stylesheet" media="handheld" href="css/handheld.css?v=1">

<!-- All JavaScript at the bottom, except for Modernizr which enables HTML5 elements & feature detects -->
<script src="js/modernizr-1.5.min.js"></script>

<!------ Some lines removed ------>

<script src="js/plugins.js?v=1"></script>
<script src="js/script.js?v=1"></script>

<!--[if lt IE 7 ]>
  <script src="js/dd_belatedpng.js?v=1"></script>
<![endif]-->


<!-- yui profiler and profileviewer - remove for production -->
<script src="js/profiling/yahoo-profiling.min.js?v=1"></script>
<script src="js/profiling/config.js?v=1"></script>
<!-- end profiling code -->
maxyfc
fonte

Respostas:

175

Isso geralmente é para garantir que o navegador obtenha uma nova versão quando o site for atualizado com uma nova versão; por exemplo, como parte do nosso processo de criação, teríamos algo como isto:

/Resources/Combined.css?v=x.x.x.buildnumber

Como isso muda a cada novo envio de código, o cliente é forçado a pegar uma nova versão, apenas por causa da string de consulta. Veja esta página (no momento desta resposta), por exemplo:

<link ... href="http://sstatic.net/stackoverflow/all.css?v=c298c7f8233d">

Acho que, em vez de um número de revisão, a equipe de SO adotou um hash de arquivo, que é uma abordagem ainda melhor, mesmo com uma nova versão, os navegadores apenas forçados a pegar uma nova versão quando o arquivo realmente muda.

Ambas as abordagens permitem que você defina o cabeçalho do cache como algo ridiculamente longo, digamos 20 anos ... mas, quando ele muda, você não precisa se preocupar com esse cabeçalho, o navegador vê uma sequência de consultas diferente e a trata como uma novo arquivo diferente.

Nick Craver
fonte
3
@Free - Um cabeçalho de controle de cache enviado ontem não pode informar ao cliente que o arquivo foi alterado hoje (o cliente nem verifica), um URL pode. Você pode explicar o que estou perdendo lá?
Nick Craver
8
@Free - A maneira como esses arquivos são armazenados em cache é para sempre , o que significa que o cliente não está de forma alguma verificando se o arquivo foi modificado. Isso significa que eles nunca receberiam o arquivo atualizado ... a menos que o URL seja alterado, o que acontece com a técnica acima. Você obtém a vida útil máxima do cache no cliente (o menor número de solicitações HTTP), mas o cliente é atualizado instantaneamente quando o arquivo é alterado . Exatamente como você faria tudo isso usando apenas cabeçalhos de controle de cache?
Nick Craver
4
@Free - Stack Overflow recebe 5 milhões de visitantes por mês, sua abordagem teria 2 impactos: a) muito mais solicitações e dados enviados para / de nossos servidores eb) os usuários não receberiam imediatamente novo JavaScript / CSS (por exemplo quando tivemos um bug ou o HTML muda, necessitando de novos JS / CSS). Expiração natural realmente não é uma opção aqui. O método que você está propondo seria tecnicamente muito menos eficiente e o resultado são erros reais do usuário , regularmente ... que não são realmente aceitáveis ​​em nenhum site importante (nem deveriam ser em nenhum site).
Nick Craver
2
@Free - Os 5 milhões são 5 milhões de visitantes por mês , já que implantamos muitas vezes ao dia , as solicitações são muitas vezes isso. Em termos de carregamento de páginas HTML, estamos falando de pouco mais de 110 milhões por mês (e crescendo ... novamente, isso é apenas o carregamento de páginas HTML). Para a) sim, muitas mais ou mais quebras, é uma troca de qualquer maneira no tempo de cache versus clientes com conteúdo correto. Além disso, sua lógica para b) é falha, o html não é armazenado em cache, portanto, usado com JS em cache que não funciona mais significa que apenas os usuários armazenados em cache são afetados, e não imunes.
Nick Craver
5
O @GMsoF v representa apenas "versão" para nós, é uma escolha completamente arbitrária. Qualquer string de consulta de valor funcionaria, por exemplo, poderia ser tão facilmente? Jejdutogjesudo =
Nick Craver
23

Isso garante que você esteja obtendo a versão mais recente do arquivo css ou js do servidor.

E depois, você pode anexar "?v=2"se tiver uma versão mais recente "?v=3", "?v=4"e assim por diante.

Observe que você pode usar qualquer um querystring, 'v' não é obrigatório, por exemplo:

"?blah=1"funcionará também.

E

"?xyz=1002" vai funcionar.

E essa é uma técnica comum, porque os navegadores estão agora armazenando em cache os arquivos js e css cada vez melhor.

Amr Elgarhy
fonte
13

A solução de hash é boa, mas não é realmente legível quando você deseja saber qual versão do arquivo está na pasta da web local. A solução édate/time carimbar sua versão para que você possa compará-la facilmente com o arquivo do servidor.

Por exemplo, se seu .js or .cssarquivo estiver datado 2011-02-08 15:55:30(última modificação), a versão deverá ser igual a.js?v=20110208155530

Deve ser fácil ler as propriedades de qualquer arquivo em qualquer idioma. No ASP.Net é realmente fácil ...

".js?v=" + File.GetLastWriteTime(HttpContext.Current.Request.PhysicalApplicationPath + filename).ToString("yyMMddHHHmmss");

De coz obtê-lo bem refatorado em propriedades / funções primeiro e pronto. Não há mais desculpas.

Boa sorte, art.

Arte
fonte
2
E se você estiver construindo seu site apenas com html js e css. Então, como podemos injetar automaticamente o nome da versão nos recursos estáticos?
Nishanth Nair
@ Whizkid747 resposta tardia, mas para os novatos, qualquer sistema de criação / construção de sites que você estiver usando deve ter uma maneira de obter a data em milissegundos que você pode usar como versão, caso contrário, se você não estiver usando um construtor // sistema de construção você teria que escrever isso sozinho.
AntK
7

Os arquivos Javascript geralmente são armazenados em cache pelo navegador por muito mais tempo do que você poderia esperar.

Geralmente, isso pode resultar em comportamento inesperado quando você libera uma nova versão do seu arquivo JS.

Portanto, é prática comum adicionar um parâmetro QueryString à URL do arquivo javascript. Dessa forma, o navegador armazena em cache o arquivo Javascript com v = 1. Quando você lança uma nova versão do seu arquivo javascript, altera os URLs para v = 2 e o navegador será forçado a baixar uma nova cópia.

Robin Day
fonte
quais navegadores exatamente? mesmo os mais peculiares IE 5 e 6 estavam obedecendo aos cabeçalhos de controle de cache.
Free Consulting
7

Para responder a suas perguntas;

"? v = 1" isto é escrito apenas porque é necessário baixar uma nova cópia dos arquivos css e js em vez de usar a partir do cache do navegador.

Se você mencionar esse parâmetro de string de consulta no final da folha de estilo ou do arquivo js, ​​ele força o navegador a baixar um novo arquivo, devido ao qual as alterações recentes nos arquivos .css e .js são efetivas em seu navegador.

Se você não usar esse controle de versão, poderá ser necessário limpar o cache para atualizar a página para visualizar as alterações recentes nesses arquivos.

Aqui está um artigo que explica isso Como e por que criar versões de arquivos CSS e JS

Tapan kumar
fonte
2

Durante o desenvolvimento / teste de novos lançamentos, o cache pode ser um problema, porque o navegador, o servidor e, às vezes, a empresa de telecomunicações 3G (se você fizer uma implantação móvel) armazenará em cache o conteúdo estático (por exemplo, JS, CSS, HTML, img). Você pode superar isso anexando o número da versão, o número aleatório ou o carimbo de data / hora no URL, por exemplo: JSP:<script src="js/excel.js?time=<%=new java.util.Date()%>"></script>

Caso você esteja executando HTML puro (em vez de páginas JSP, ASP, PHP), o servidor não o ajudará. No navegador, os links são carregados antes da execução do JS, portanto, você deve remover os links e carregá-los com o JS.

// front end cache bust
var cacheBust = ['js/StrUtil.js', 'js/protos.common.js', 'js/conf.js', 'bootstrap_ECP/js/init.js'];   
for (i=0; i < cacheBust.length; i++){
     var el = document.createElement('script');
     el.src = cacheBust[i]+"?v=" + Math.random();
     document.getElementsByTagName('head')[0].appendChild(el);
}
Conete Cristian
fonte
0

Como você pode ler antes, o ?v=1 isso garante que seu navegador obtenha a versão 1 do arquivo. Quando você tem uma nova versão, basta adicionar um número de versão diferente e o navegador esquece a versão antiga e carrega a nova.

Há um plug-in gulp que cuida da versão dos seus arquivos durante a fase de construção, para que você não precise fazer isso manualmente. É útil e você pode integrá-lo facilmente no processo de criação. Aqui está o link: gulp-annotate

Phugo
fonte
-2

Conforme mencionado por outros, isso é usado para impedir o cache do front-end. Para implementar isso, eu pessoalmente acho útil o pacote grunt-cache-bust npm.

RAM
fonte
1
Embora esse link possa responder à pergunta, as respostas somente ao link são desencorajadas no Stack Overflow, você pode melhorar essa resposta pegando partes vitais do link e colocando-o na sua resposta, isso garante que sua resposta ainda seja uma resposta se o link for alterado ou removido :)
WhatsThePoint