Comment puis-je forcer les clients à rafraîchir les fichiers JavaScript?

nous travaillons actuellement dans un bêta privé et sommes donc toujours dans le processus de faire des changements assez rapides, bien que évidemment que l'utilisation commence à augmenter, Nous allons ralentir ce processus. Cela dit, un problème que nous rencontrons est qu'après avoir lancé une mise à jour avec de nouveaux fichiers JavaScript, les navigateurs clients utilisent toujours la version mise en cache du fichier et ils ne voient pas la mise à jour. Évidemment, sur un appel de soutien, nous pouvons simplement les informer de faire un ctrl F5 rafraîchir pour s'assurer qu'ils obtiennent les fichiers à jour à partir du serveur, mais il serait préférable de gérer cela avant ce moment.

notre pensée actuelle est de simplement joindre un numéro de version sur le nom des fichiers JavaScript et ensuite quand des changements sont faits, incrémenter la version sur le script et mettre à jour toutes les références. Cela permet certainement de faire le travail, mais mettre à jour les références sur chaque version pourrait devenir fastidieux.

comme je suis sûr que nous ne sommes pas les premiers à nous occuper de ça, j'ai pensé que je le jetterais à la communauté. Comment vous assurez-vous que les clients mettent à jour leur cache lorsque vous mettez à jour votre code? Si vous utilisez la méthode décrite ci-dessus, utilisez-vous un processus qui simplifie le changement?

500
demandé sur Jason Plank 2008-08-28 18:30:26

21 réponses

autant que je sache, une solution courante consiste à ajouter un ?<version> au lien src du script.

par exemple:

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

je suppose à ce point qu'il n'y a pas une meilleure façon que find-replace pour incrémenter ces "numéros de version" dans toutes les balises de script?

vous pourriez avoir un système de contrôle de version faire cela pour vous? La plupart des systèmes de contrôle de version ont un façon d'injecter automatiquement le numéro de révision lors de l'enregistrement par exemple.

il ressemblerait à quelque chose comme ceci:

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

bien sûr, il y a toujours de meilleures solutions comme celle-ci .

462
répondu Huppie 2015-04-17 21:22:10

ajouter l'heure actuelle à L'URL est en effet une solution courante. Cependant, vous pouvez également gérer cela au niveau du serveur web, si vous le souhaitez. Le serveur peut être configuré pour envoyer différents en-têtes HTTP pour les fichiers javascript.

par exemple, pour forcer le fichier à être mis en cache pour pas plus d'un jour, vous enverriez:

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

pour beta, si vous voulez forcer l'utilisateur à toujours obtenir la dernière, vous utilisez:

Cache-Control: no-cache, must-revalidate
75
répondu Chase Seibert 2008-09-17 16:04:02

Google Page-Speed: N'incluez pas de chaîne de requête dans l'URL pour les ressources statiques. La plupart des mandataires, notamment Squid up à travers la version 3.0, ne mettent pas en cache des ressources avec un "?"dans leur URL même si un en-tête Cache-control: public est présent dans la réponse. Pour activer la mise en cache par procuration de ces ressources, supprimez les chaînes de requête des références aux ressources statiques, et encodez plutôt les paramètres dans les noms de fichiers eux-mêmes.

dans ce cas, vous pouvez inclure version dans L'URL ex: http://abc.com / v1.2 /script.js et utiliser apache mod_rewrite pour rediriger le lien vers http://abc.com/script.js . Lorsque vous changez la version, le navigateur client mettra à jour le nouveau fichier.

40
répondu Hắc Huyền Minh 2011-10-06 08:13:44

cette réponse n'a que 6 ans de retard, mais je ne la vois pas souvent... HTML5 a introduit Application Cache qui est utilisé pour résoudre ce problème. J'ai découvert que le nouveau code de serveur que j'écrivais était en train de planter l'ancien javascript stocké dans les navigateurs des gens, donc je voulais trouver un moyen d'expirer leur javascript. Utiliser un fichier de manifeste qui ressemble à ceci:

CACHE MANIFEST
# Aug 14, 2014
/mycode.js

NETWORK:
*

et générer ce fichier avec un nouvel horodatage à chaque fois vous voulez que les utilisateurs mettent à jour leur cache. Si vous ajoutez ceci, le navigateur rechargera et non (même si un utilisateur rafraîchit la page) jusqu'à ce que le manifeste le lui dise.

33
répondu amos 2014-08-14 20:05:48

Que Diriez-vous d'ajouter le paramètre filesize comme paramètre de charge?

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

donc chaque fois que vous mettez à jour le fichier, le paramètre" filever " change.

Qu'en est-il lorsque vous mettez à jour le fichier et que votre mise à jour aboutit à la même taille de fichier? quelles sont les chances?

25
répondu Erik Corona 2015-12-02 00:45:42

tous les navigateurs ne mettent pas en cache les fichiers avec "?' . Ce que j'ai fait pour m'assurer qu'il était mis en cache autant que possible, j'ai inclus la version dans le nom de fichier.

donc au lieu de stuff.js?123 , j'ai fait stuff_123.js

j'ai utilisé mod_redirect (je crois) dans apache have stuff_*.js aller stuff.js

18
répondu Echo 2018-04-15 14:39:42

Pour ASP.NET pages que je suis en utilisant la suite de

avant

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

après (force de rechargement)

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

ajout de la DateTime.Maintenant.Les tiques marchent très bien.

9
répondu Ravi Ram 2014-01-23 01:10:56

pour ASP.NET je suppose que la solution suivante avec des options avancées (mode de débogage / libération, versions):

fichiers Js ou Css inclus de cette manière:

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

Global.JsPostfix et Global.CssPostfix est calculé de la manière suivante dans 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();
    }
    ...
}
5
répondu Ivan Kochurkin 2013-08-03 13:55:23

si vous générez la page qui renvoie aux fichiers JS, une solution simple est d'ajouter la dernière date de modification du fichier aux liens générés.

c'est très similaire à la réponse de Huppie, mais fonctionne dans les systèmes de contrôle de version sans substitution de mot clé. C'est aussi mieux que d'ajouter l'heure actuelle, car cela empêcherait la mise en cache même si le fichier ne change pas du tout.

4
répondu 2008-09-17 16:03:06

la fonction jQuery getScript peut également être utilisée pour s'assurer qu'un fichier js est effectivement chargé chaque fois que la page est chargée.

C'est comme ça que je l'ai fait:

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

vérifier la fonction à http://api.jquery.com/jQuery.getScript /

par défaut, $.getScript () définit le paramètre cache à false. Cela ajoute un paramètre de requête horodaté à L'URL de la requête pour s'assurer que le navigateur télécharge le script à chaque fois qu'il est demandé.

2
répondu Michael Franz 2015-10-10 20:53:10

nous avons créé un SaaS pour les utilisateurs et leur fournir un script à joindre dans leur page de site web, et il n'était pas possible d'attacher une version avec le script car l'utilisateur attachera le script à leur site web pour des fonctionnalités et je ne peux pas les forcer à changer la version chaque fois que nous mettons à jour le script""

donc, nous avons trouvé un moyen de charger la nouvelle version du script chaque fois que l'utilisateur appelle le script original

le script lien vers l'utilisateur

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

le fichier 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
}

explication:

l'Utilisateur a joint le script qui lui a été fourni sur son site web et nous avons vérifié si le token unique joint avec le script existe ou n'utilise pas le sélecteur jQuery et s'il n'est pas chargé dynamiquement avec le nouveau token (ou la version)""

c'est appeler le même script deux fois ce qui pourrait être un problème de performance, mais ça résout vraiment le problème de forcer le script à ne pas charger depuis le cache sans mettre la version dans le lien script donné à l'utilisateur ou au client

Avertissement: Ne pas utiliser si la performance est un gros problème dans votre cas.

2
répondu Aman Singh 2017-11-08 08:27:59

utilisez la variable GET pour empêcher la mise en cache du navigateur.

ajouter ?v=AUTO_INCREMENT_VERSION à la fin de votre url empêche la mise en cache du navigateur - en évitant tous les scripts mis en cache.

1
répondu Derek Adair 2010-11-27 21:00:59

mon collègue vient de trouver une référence à cette méthode juste après que j'ai posté (en référence à css) à http://www.stefanhayden.com/blog/2006/04/03/css-caching-hack / . Bon de voir que d'autres l'utilisent et il semble fonctionner. Je suppose à ce point qu'il n'y a pas de meilleur moyen que find-replace pour incrémenter ces "numéros de version" dans toutes les balises de script?

1
répondu AdamB 2011-12-15 15:22:48

bien qu'il soit spécifique au cadre, Django 1.4 a cette fonctionnalité qui fonctionne d'une manière similaire au lien vers le site "greenfelt" dans le réponse ci-dessus

1
répondu Taras 2017-05-23 11:54:59

In PHP :

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

In HTML :

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

Comment cela fonctionne:

en HTML, écrivez le filepath et le nom comme vous voulez, mais dans la fonction seulement. PHP obtient le filetime du fichier et renvoie le filepath+name+"?"+time de la dernière modification

1
répondu user1944129 2016-07-26 14:03:42

ASP.NET Core via un helper tag traitera cela pour vous et permettra à votre navigateur de garder les scripts/css en cache jusqu'à ce que le fichier change. Il suffit d'ajouter la balise Helper asp-append-version="true" à votre balise script (js) ou link (css):

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

Dave Paquette a un bon exemple et une bonne explication de l'arrêt de cache ici (bas de la page) arrêt de Cache

1
répondu ccherwin 2017-06-29 22:30:36

une solution est d'ajouter une chaîne de requête avec un horodatage à L'URL lors de la recherche de la ressource. Cela profite du fait qu'un navigateur ne cache pas les ressources récupérées à partir d'URLs avec des chaînes de requête.

vous ne voulez probablement pas que le navigateur ne cache pas du tout ces ressources; il est plus probable que vous les voulez cachées, mais vous voulez que le navigateur récupère une nouvelle version du fichier quand il est disponible.

la solution la plus courante semble être d'inclure un numéro de timestamp ou de révision dans le nom de fichier lui-même. C'est un peu plus de travail, parce que votre code doit être modifié pour demander les bons fichiers, mais cela signifie que, par exemple, la version 7 de votre snazzy_javascript_file.js (i.e. snazzy_javascript_file_7.js ) est caché sur le navigateur jusqu'à ce que vous Version 8, puis votre code change pour aller chercher snazzy_javascript_file_8.js à la place.

0
répondu Richard Turner 2008-09-17 14:31:11

la solution la plus simple? Ne laissez pas le navigateur mettre en cache. Ajoutez l'heure courante (en ms) comme une requête.

(vous êtes toujours en bêta, donc vous pourriez faire un cas raisonnable pour ne pas optimiser pour la performance. Mais YMMV ici.)

0
répondu pcorcoran 2008-09-17 15:55:01

l'avantage d'utiliser un file.js?V=1 par rapport à un fileV1.js est que vous n'avez pas besoin de stocker plusieurs versions des fichiers JavaScript sur le serveur.

le problème que je vois avec file.js?V=1 est que vous pouvez avoir du code de personne à charge dans un autre fichier JavaScript qui casse en utilisant la nouvelle version des utilitaires de la bibliothèque.

pour des raisons de rétrocompatibilité, je pense qu'il est beaucoup mieux d'utiliser jQuery.1.3.js pour vos nouvelles pages et laisser les pages existantes utilisent jQuery.1.1.js , jusqu'à ce que vous soyez prêt à mettre à jour les anciennes pages, si nécessaire.

0
répondu 2009-05-13 12:00:19

la manière la plus simple. Edit 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]
0
répondu Goran Siriev 2017-01-06 08:41:38

la pratique courante de nos jours est de générer un code de hachage de contenu comme partie du nom de fichier pour forcer le navigateur en particulier IE pour recharger les fichiers javascript ou les fichiers css.

par exemple,

vendeur. a7561fb0e9a071baadb9 .js

principal. b746e3eb72875af2caa9 .js

il est généralement le travail pour les outils de construction tels que webpack. Ici, c'est plus détails si quelqu'un veut essayer si vous utilisez webpack.

0
répondu schrodinger's code 2018-09-27 11:00:25