À quoi sert l'ajout de «? V = 1» aux URL CSS et Javascript dans les balises de lien et de script?

138

J'ai regardé un modèle standard HTML 5 (à partir de http://html5boilerplate.com/ ) et j'ai remarqué l'utilisation de "?v=1"dans les URL pour faire référence aux fichiers CSS et Javascript.

  1. À quoi sert l'ajout "?v=1"aux URL CSS et Javascript dans les balises de lien et de script?
  2. Toutes les URL Javascript n'ont pas le "?v=1"(exemple de l'exemple ci-dessous:) js/modernizr-1.5.min.js. Y a-t-il une raison pour laquelle c'est le cas?

Échantillon de leur 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
la source

Réponses:

175

Il s'agit généralement de s'assurer que le navigateur obtient une nouvelle version lorsque le site est mis à jour avec une nouvelle version, par exemple dans le cadre de notre processus de construction, nous aurions quelque chose comme ceci:

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

Comme cela change à chaque nouvelle poussée de code, le client est obligé de récupérer une nouvelle version, juste à cause de la chaîne de requête. Regardez cette page (au moment de cette réponse) par exemple:

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

Je pense qu'au lieu d'un numéro de révision, l'équipe SO a opté pour un hachage de fichier, ce qui est une approche encore meilleure, même avec une nouvelle version, les navigateurs ne sont obligés de saisir une nouvelle version que lorsque le fichier change réellement .

Ces deux approches vous permettent de définir l'en-tête du cache sur quelque chose de ridiculement long, disons 20 ans ... mais quand il change, vous n'avez pas à vous soucier de cet en-tête de cache, le navigateur voit une chaîne de requête différente et la traite comme un différent, nouveau fichier.

Nick Craver
la source
3
@Free - Un en-tête de contrôle de cache envoyé hier ne peut pas indiquer au client le fichier modifié aujourd'hui (le client ne vérifiera même pas), une URL le peut. Pouvez-vous expliquer ce que je manque là-bas?
Nick Craver
8
@Free - La façon dont ces fichiers sont mis en cache est éternelle , ce qui signifie que le client ne vérifie en aucun cas si le fichier est modifié. Cela signifie qu'ils n'obtiendront jamais le fichier mis à jour ... à moins que l'URL ne soit modifiée, ce qui se produit avec la technique ci-dessus. Vous obtenez une durée de vie maximale du cache sur le client (le moins de requêtes HTTP), mais le client est instantanément mis à jour lorsque le fichier change réellement . Comment pourriez-vous accomplir tout cela en utilisant uniquement les en-têtes de contrôle du cache?
Nick Craver
4
@Free - Stack Overflow reçoit 5 millions de visiteurs par mois, votre approche aurait 2 impacts: a) beaucoup plus de requêtes et de données envoyées vers / depuis nos serveurs, et b) les utilisateurs n'obtiendraient pas immédiatement de nouveau JavaScript / CSS (par exemple quand nous avons eu un bug, ou les changements HTML nécessitant un nouveau JS / CSS). L'expiration naturelle n'est vraiment pas une option ici. La méthode que vous proposez serait techniquement beaucoup moins efficace et il en résulterait de réels bogues d'utilisateurs , sur une base régulière ... ce qui n'est vraiment acceptable sur aucun site majeur (et cela ne devrait pas l'être sur aucun site).
Nick Craver
2
@Free - Les 5 millions, c'est 5 millions de visiteurs par mois , puisque nous déployons plusieurs fois par jour , les demandes sont plusieurs fois plus élevées . En termes de chargement de pages HTML, nous parlons d'un peu plus de 110 millions par mois (et de plus en plus ... encore une fois, ce ne sont que des chargements de pages HTML). Pour a) oui, beaucoup plus, ou plus de pauses, c'est un compromis entre le temps de cache et les clients ayant un contenu correct. De plus, votre logique pour b) est imparfaite, le html n'est pas mis en cache, donc utilisé avec JS mis en cache qui ne fonctionne plus signifie que seuls les utilisateurs mis en cache sont affectés, pas qu'ils sont immunisés.
Nick Craver
5
@GMsoF v représente juste pour nous "version", c'est un choix complètement arbitraire. N'importe quelle chaîne de requête de valeur fonctionnerait, par exemple cela pourrait tout aussi bien l'être? Jejdutogjesudo =
Nick Craver
23

Cela garantit que vous obtenez la dernière version du fichier css ou js du serveur.

Et plus tard, vous pouvez ajouter "?v=2"si vous avez une version plus récente "?v=3", "?v=4"et ainsi de suite.

Notez que vous pouvez utiliser n'importe quel querystring, 'v' n'est pas un must par exemple:

"?blah=1"fonctionnera également.

Et

"?xyz=1002" marchera.

Et c'est une technique courante car les navigateurs mettent désormais en cache les fichiers js et css mieux et plus longtemps.

Amr Elgarhy
la source
13

La solution de hachage est agréable mais pas vraiment lisible par l'homme lorsque vous voulez savoir quelle version du fichier se trouve dans votre dossier Web local. La solution consiste à date/timetamponner votre version afin de pouvoir la comparer facilement à votre fichier serveur.

Par exemple, si votre .js or .cssfichier est daté 2011-02-08 15:55:30(dernière modification), la version doit être égale à.js?v=20110208155530

Devrait être facile à lire les propriétés de n'importe quel fichier dans n'importe quelle langue. Dans ASP.Net, c'est vraiment simple ...

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

Bien sûr, faites-le bien remanié en propriétés / fonctions d'abord et c'est parti. Plus d'excuses.

Bonne chance, Art.

Art
la source
2
Que faire si vous créez votre site Web uniquement avec html js et css. Alors, comment pouvons-nous injecter automatiquement le nom de la version aux ressources statiques?
Nishanth Nair
@ Whizkid747 réponse tardive, mais pour les nouveaux arrivants, quel que soit le système de création / construction de site que vous utilisez, vous devez avoir un moyen d'obtenir la date en millisecondes que vous pouvez utiliser comme version, sinon si vous n'utilisez pas de système de construction // build vous devrez les écrire vous-même.
AntK
7

Les fichiers Javascript sont souvent mis en cache par le navigateur pendant beaucoup plus longtemps que prévu.

Cela peut souvent entraîner un comportement inattendu lorsque vous publiez une nouvelle version de votre fichier JS.

Par conséquent, il est courant d'ajouter un paramètre QueryString à l'URL du fichier javascript. De cette façon, le navigateur met en cache le fichier Javascript avec v = 1. Lorsque vous publiez une nouvelle version de votre fichier javascript, vous changez l'URL en v = 2 et le navigateur sera obligé de télécharger une nouvelle copie.

Jour de Robin
la source
quels navigateurs exactement? même les IE 5 et 6 les plus excentriques obéissaient aux en-têtes de contrôle du cache.
Consultation gratuite du
7

Afin de répondre à vos questions;

"? v = 1" ceci n'est écrit que pour télécharger une nouvelle copie des fichiers css et js au lieu d'utiliser depuis le cache du navigateur.

Si vous mentionnez ce paramètre de chaîne de requête à la fin de votre feuille de style ou du fichier js, cela force le navigateur à télécharger un nouveau fichier, en raison duquel les modifications récentes dans les fichiers .css et .js sont rendues effectives dans votre navigateur.

Si vous n'utilisez pas ce contrôle de version, vous devrez peut-être vider le cache pour actualiser la page afin d'afficher les modifications récentes de ces fichiers.

Voici un article qui explique cette chose Comment et pourquoi faire le versionnage des fichiers CSS et JS

Tapan Kumar
la source
2

Lors du développement / test de nouvelles versions, le cache peut être un problème car le navigateur, le serveur et même parfois l'opérateur de télécommunications 3G (si vous effectuez un déploiement mobile) mettront en cache le contenu statique (par exemple JS, CSS, HTML, img). Vous pouvez surmonter cela en ajoutant le numéro de version, le nombre aléatoire ou l'horodatage à l'URL, par exemple: JSP:<script src="js/excel.js?time=<%=new java.util.Date()%>"></script>

Dans le cas où vous exécutez du HTML pur (au lieu des pages serveur JSP, ASP, PHP), le serveur ne vous aidera pas. Dans le navigateur, les liens sont chargés avant l'exécution du JS, vous devez donc supprimer les liens et les charger avec 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
la source
0

Comme vous pouvez le lire auparavant, le ?v=1 garantit que votre navigateur obtient la version 1 du fichier. Lorsque vous avez une nouvelle version, il vous suffit d'ajouter un numéro de version différent et le navigateur oubliera l'ancienne version et chargera la nouvelle.

Il existe un plugin gulp qui s'occupe de la version de vos fichiers pendant la phase de construction, vous n'avez donc pas à le faire manuellement. C'est pratique et vous pouvez facilement l'intégrer dans votre processus de construction. Voici le lien: gulp-annotate

Phugo
la source
-2

Comme mentionné par d'autres, ceci est utilisé pour le contournement du cache frontal. Pour implémenter cela, j'ai personnellement trouvé le paquet npm grunt-cache-bust utile.

RAM
la source
1
Bien que ce lien puisse répondre à la question, les réponses aux liens uniquement sont déconseillées sur Stack Overflow, vous pouvez améliorer cette réponse en prenant des parties vitales du lien et en les insérant dans votre réponse, cela garantit que votre réponse est toujours une réponse si le lien est modifié ou supprimé :)
WhatsThePoint