Vider le cache en JavaScript


179

Comment vider le cache d'un navigateur avec JavaScript?

Nous avons déployé le dernier code JavaScript, mais nous ne pouvons pas obtenir le dernier code JavaScript.

Note éditoriale: Cette question est semi-dupliquée aux endroits suivants, et la réponse à la première des questions suivantes est probablement la meilleure. Cette réponse acceptée n'est plus la solution idéale.

Comment forcer le navigateur à recharger les fichiers CSS / JS en cache?

Comment puis-je forcer les clients à actualiser les fichiers JavaScript?

Recharger dynamiquement les données source Javascript / json locales


5
Cela me trouble: "Nous avons déployé le dernier code javascript mais nous n'avons pas pu obtenir le dernier code javascript"
instanceof me

14
Je suppose que vous voulez dire, comment forcer les navigateurs clients à utiliser votre dernière version de javascript et non leur version en cache - dans ce cas, vous avez besoin de la réponse de Greg. Si vous voulez savoir comment le faire dans votre propre navigateur, c'est la réponse de David Johnstone.
Benjol


4
Une approche courante consiste à attacher un ?version=xxxà vos fichiers liés JS via une étape de génération. Chaque nouvelle version demandera une nouvelle version du fichier JS.
Juan Mendes le

1
@JuanMendes Cela ne fonctionne pas toujours. Cette même étape est suggérée lorsque les gens ont des problèmes pour voir le dernier favicon. Il n'est tout simplement pas garanti de fonctionner.
uSeRnAmEhAhAhAhAhA

Réponses:


202

Vous pouvez appeler window.location.reload (true) pour recharger la page actuelle. Il ignorera tous les éléments mis en cache et récupérera de nouvelles copies de la page, des css, des images, du JavaScript, etc. du serveur. Cela n'efface pas tout le cache, mais a pour effet de vider le cache de la page sur laquelle vous vous trouvez.

Cependant, votre meilleure stratégie consiste à créer une version du chemin ou du nom de fichier comme mentionné dans diverses autres réponses. En outre, consultez Revving Filenames: n'utilisez pas de chaîne de requête pour des raisons de ne pas l'utiliser ?v=ncomme schéma de version.


6
Ouah merci! Cela fonctionne également pour un cache d'application HTML5 chargé à partir d'un fichier cache.manifest. J'avais un ancien manifeste qui n'était pas supprimé de la mémoire, donc un navigateur qui l'avait mis en cache ne montrerait tout simplement pas les fichiers plus récents. J'ai tapé ceci dans la console javascript et j'ai bien fonctionné. Merci!
JayCrossler

2
mais revving en changeant le nom de fichier ... est-ce que vous ne garderez pas toutes les versions précédentes en place? sinon, vous aurez beaucoup de tentatives infructueuses de la part des moteurs de recherche et de quoi ne pas lire les anciennes versions (ou les images mises en signet / liées)
Rodolfo

1
comment est-ce que je n'ai pas pensé à ça, tank you
osdamv

1
Est-ce la même chose que l'utilisateur clique sur le bouton d'actualisation?
GMsoF

2
@Manuel Cela désactivera uniquement l'accès à la page à partir du cache de l'url exacte que vous avez appelée location.reload (true) sur. Il n'efface jamais la page d'origine du cache car il ajoute simplement un horodatage à la nouvelle demande, et s'il y a d'autres appels effectués de manière asynchrone par cette page, ces demandes n'auront PAS leur comportement de mise en cache désactivé. Par exemple. Si vous actualisez une page avec reload (true) qui charge du HTML, et que cette page a un script qui effectue un deuxième appel ajax pour que plus de HTML s'affiche sur la même page, la deuxième demande n'aura pas sa mise en cache désactivée.
J.Schei

114

Vous ne pouvez pas vider le cache avec javascript. Une méthode courante consiste à ajouter le numéro de révision ou l'horodatage de la dernière mise à jour au fichier, comme ceci:

myscript.123.js

ou

myscript.js?updated=1234567890


9
Notez cependant que de nombreux proxys ne mettent pas en cache un fichier lorsqu'il contient une chaîne de requête. Voir la réponse de Kevin Hakanson .
chiborg

4
Comment puis-je vider le cache lorsque tout le code HTML a été mis en cache? Cela n'affectera pas même lorsque le numéro de version est ajouté à cause du HTML mis en cache.Veuillez aider
Nandakumar

Si je ne peux pas effacer un élément du cache, pourquoi MDN dit-il que je le peux? Qu'est-ce que je rate? J'ai essayé ce que MDN dit mais pas de chance.
Sнаđошƒаӽ

41

Essayez de changer le src du fichier JavaScript? De ceci:

<script language="JavaScript" src="js/myscript.js"></script>

Pour ça:

<script language="JavaScript" src="js/myscript.js?n=1"></script>

Cette méthode devrait forcer votre navigateur à charger une nouvelle copie du fichier JS.


Que fait le n = 1?
KyelJmD

cela ne fait rien d'autre que quelque chose de différent. ça pourrait être? 12345 ou? Kyle
Oneezy

Donc, le nom du fichier doit également être changé? Ou juste le chemin src qui doit être changé?
Fred A

20

Autre que la mise en cache toutes les heures ou toutes les semaines, vous pouvez mettre en cache en fonction des données du fichier.

Exemple (en PHP):

<script src="js/my_script.js?v=<?=md5_file('js/my_script.js')?>"></script>

ou même utiliser l'heure de modification du fichier:

<script src="js/my_script.js?v=<?=filemtime('js/my_script.js')?>"></script>

3
Puis-je vérifier que je comprends bien?: Avec l'option 1, lorsque le fichier change, le hachage de la somme de contrôle md5 change, ce qui change ensuite l'URL. Le navigateur voit une nouvelle URL et lance un nouveau chargement du fichier. Les données get ajoutées à l'URL sont ignorées par le serveur. Si tel est le cas, c'est vraiment super.
Colin Brogan

1
De plus, est-ce que MD5 est un processeur de fichiers entier intensif? J'envisage de faire cela pour toujours les fichiers css et js, mais je détesterais voir un coup à la vitesse du serveur à cause de cela.
Colin Brogan

2
Utiliser une somme de contrôle est une bonne idée, mais cela doit être bien fait. Le calcul de chaque demande pour chaque fichier affectera considérablement vos performances. Querystring n'est pas bon pour la mise en cache également, voir d'autres réponses. La bonne utilisation est d'ajouter une somme de contrôle (une partie de?) Ou un numéro de version au nom de fichier et d'utiliser ce nouveau nom à la place (vous pouvez utiliser un script de construction pour le faire automatiquement lors du déploiement). Voir grunt , rev et usemin .
Frizi

10

Vous pouvez également forcer le rechargement du code toutes les heures, comme ceci, en PHP:

<?php
echo '<script language="JavaScript" src="js/myscript.js?token='.date('YmdH').'">';
?>

ou

<script type="text/javascript" src="js/myscript.js?v=<?php echo date('YmdHis'); ?>"></script>

1
salut, que signifient "v" et "token"?
GMsoF

4
@GMsoF qui est juste un paramètre get supplémentaire qui est utilisé (dans ce cas) pour indiquer au navigateur qu'il s'agit d'un fichier "différent". Pour que le navigateur supprime la version mise en cache et charge celle-ci à la place. Ceci est souvent utilisé avec la «date de la dernière modification» d'un fichier. J'espère que cela a du sens ;-)
Jelmer

6

mettez ceci à la fin de votre modèle:

var scripts =  document.getElementsByTagName('script');
var torefreshs = ['myscript.js', 'myscript2.js'] ; // list of js to be refresh
var key = 1; // change this key every time you want force a refresh
for(var i=0;i<scripts.length;i++){ 
   for(var j=0;j<torefreshs;j++){ 
      if(scripts[i].src && (scripts[i].src.indexOf(torefreshs[j]) > -1)){
        new_src = scripts[i].src.replace(torefreshs[j],torefreshs[j] + 'k=' + key );
        scripts[i].src = new_src; // change src in order to refresh js
      } 
   }
}

1
Veuillez fournir quelques explications sur votre solution
Gabriel Espinoza

@GabrielEspinoza il recharge les fichiers en utilisant javascript, ce qui permet de mettre à jour les caches.
Neo Morina

6

essayez d'utiliser ceci

 <script language="JavaScript" src="js/myscript.js"></script>

Pour ça:

 <script language="JavaScript" src="js/myscript.js?n=1"></script>

5

Voici un extrait de ce que j'utilise pour mon dernier projet.

Du contrôleur:

if ( IS_DEV ) {
    $this->view->cacheBust = microtime(true);
} else {
    $this->view->cacheBust = file_exists($versionFile) 
        // The version file exists, encode it
        ? urlencode( file_get_contents($versionFile) )
        // Use today's year and week number to still have caching and busting 
        : date("YW");
}

De la vue:

<script type="text/javascript" src="/javascript/somefile.js?v=<?= $this->cacheBust; ?>"></script>
<link rel="stylesheet" type="text/css" href="/css/layout.css?v=<?= $this->cacheBust; ?>">

Notre processus de publication génère un fichier avec le numéro de révision de la version actuelle. Cela fonctionne en encodant l'URL de ce fichier et en l'utilisant comme un buster de cache. En cas de basculement, si ce fichier n'existe pas, l'année et le numéro de semaine sont utilisés pour que la mise en cache fonctionne toujours, et il sera actualisé au moins une fois par semaine.

En outre, cela fournit un contournement du cache pour chaque chargement de page dans l'environnement de développement afin que les développeurs n'aient pas à se soucier de vider le cache pour toutes les ressources (javascript, css, appels ajax, etc.).


5

ou vous pouvez simplement lire le fichier js par serveur avec file_get_contets puis mettre en écho dans l'en-tête le contenu de js


4

Peut-être que "vider le cache" n'est pas aussi simple qu'il devrait l'être. Au lieu de vider le cache de mes navigateurs, j'ai réalisé que "toucher" le fichier changerait en fait la date du fichier source mis en cache sur le serveur (Testé sur Edge, Chrome et Firefox) et la plupart des navigateurs téléchargeront automatiquement la nouvelle copie la plus récente de ce qui est sur votre serveur (code, graphiques tout multimédia aussi). Je vous suggère de simplement copier les scripts les plus récents sur le serveur et la solution «faire la chose tactile» avant que votre programme ne s'exécute, de sorte qu'il changera la date de tous vos fichiers problématiques en une date et une heure les plus récentes, puis il téléchargera une nouvelle copie à votre navigateur:

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

... le reste de votre programme ...

Il m'a fallu un certain temps pour résoudre ce problème (car de nombreux navigateurs agissent différemment pour différentes commandes, mais ils vérifient tous l'heure des fichiers et se comparent à votre copie téléchargée dans votre navigateur, si la date et l'heure sont différentes, feront l'actualisation), si vous ne peut pas aller dans le bon sens, il y a toujours une autre solution utilisable et meilleure. Meilleures salutations et bon camping.


1
J'aime cette approche, mais je la mets peut-être en œuvre dans le mauvais domaine? Est-ce que quelqu'un sait où ajouter cela dans une configuration WordPress? Je l'ai ajouté au fichier functions.php, avec des liens directs vers les fichiers JavaScript et CSS, mais je devais encore faire un rechargement dur pour que les changements soient remarqués.
flipflopmedia

1
Ce que vous devez faire, c'est dans votre répertoire wordpress html principal, éditez votre index.php pour appeler ou exécuter la commande Touch () sur les fichiers que vous devez actualiser et télécharger. J'ai eu des problèmes avec de petites images et des fichiers js qui sont restés bloqués dans le cache. J'ai essayé la plupart des méthodes décrites pour libérer de la mémoire, mais le meilleur moyen est de charger une nouvelle et correcte. Vous pouvez accomplir cela en faisant simplement le "Touch Thing" car il ne modifie rien sur le fichier, met simplement à jour l'heure et la date actuelles afin de tromper votre navigateur pour penser que c'est une autre version du fichier et le problème est résolu. Fonctionne sur la plupart des navigateurs
Luis H Cabrejo

3

J'ai eu quelques soucis avec le code proposé par yboussard. La boucle j interne ne fonctionnait pas. Voici le code modifié que j'utilise avec succès.

function reloadScripts(toRefreshList/* list of js to be refresh */, key /* change this key every time you want force a refresh */) {
    var scripts = document.getElementsByTagName('script');
    for(var i = 0; i < scripts.length; i++) {
        var aScript = scripts[i];
        for(var j = 0; j < toRefreshList.length; j++) {
            var toRefresh = toRefreshList[j];
            if(aScript.src && (aScript.src.indexOf(toRefresh) > -1)) {
                new_src = aScript.src.replace(toRefresh, toRefresh + '?k=' + key);
                // console.log('Force refresh on cached script files. From: ' + aScript.src + ' to ' + new_src)
                aScript.src = new_src;
            }
        }
    }
}

3

Si vous utilisez php, vous pouvez faire:

 <script src="js/myscript.js?rev=<?php echo time();?>"
    type="text/javascript"></script>

6
Non seulement cette question a été posée il y a quatre ans, mais elle avait aussi une meilleure réponse, même si elle n'était pas acceptée.

4
En outre, cette méthode téléchargerait à nouveau le fichier à chaque fois, quel que soit le numéro de révision réel ou les modifications apportées au fichier, ce qui désactiverait complètement la mise en cache.
Antti29

2

Cache.delete () peut être utilisé pour les nouveaux Chrome, Firefox et Opera.


N'est-ce pas juste une partie de l'API Service Workers?
BanksySan

@BanksySan de la documentation MDN:You don't have to use it in conjunction with service workers, even though it is defined in the service worker spec.
Madbreaks

2

Veuillez ne pas donner d'informations erronées. L'API du cache est un autre type de cache du cache http

Le cache HTTP est déclenché lorsque le serveur envoie les en- têtes corrects , vous ne pouvez pas accéder avec javasvipt.

L'api du cache en revanche est déclenchée quand vous le souhaitez, elle est utile lorsque vous travaillez avec un service worker afin que vous puissiez intersecter la requête et y répondre à partir de ce type de cache voir: ilustration 1 ilustration 2 cours

Vous pouvez utiliser ces techniques pour avoir toujours un nouveau contenu sur vos utilisateurs:

  1. Utilisez location.reload (true) cela ne fonctionne pas pour moi, donc je ne le recommanderais pas.
  2. Utilisez Cache api afin de sauvegarder dans le cache et intersecter la demande avec le service worker , soyez prudent avec celui-ci car si le serveur a envoyé les en- têtes de cache pour les fichiers que vous souhaitez actualiser, le navigateur répondra en premier à partir du cache HTTP, et s'il ne le trouve pas, il ira sur le réseau, vous pourriez donc vous retrouver avec un ancien fichier
  3. Changez l'url de vos fichiers stactics, ma recommandation est que vous devez le nommer avec le changement de contenu de vos fichiers, j'utilise md5 puis je le convertis en chaîne et URL conviviale, et le md5 changera avec le contenu du fichier, là vous peut envoyer librement des en-têtes de cache HTTP assez longtemps

Je recommanderais le troisième voir


2

Vous pouvez également désactiver la mise en cache du navigateur avec des balises méta HTML, il suffit de mettre des balises html dans la section head pour éviter que la page Web ne soit mise en cache pendant que vous codez / testez et lorsque vous avez terminé, vous pouvez supprimer les balises méta.

(dans la section tête)

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0"/>

Actualisez votre page après l'avoir collé dans la tête et devrait également actualiser le nouveau code javascript.

Ce lien vous donnera d'autres options si vous en avez besoin http://cristian.sulea.net/blog/disable-browser-caching-with-meta-html-tags/

ou vous pouvez simplement créer un bouton comme ça

<button type="button" onclick="location.reload(true)">Refresh</button>

il s'actualise et évite la mise en cache, mais il sera là sur votre page jusqu'à ce que vous ayez terminé le test, alors vous pouvez le retirer. La meilleure option est ce que je pense.


1

J'ai tendance à versionner mon framework puis à appliquer le numéro de version aux chemins de script et de style

<cfset fw.version = '001' />
<script src="/scripts/#fw.version#/foo.js"/>

3
OP n'a pas mentionné Coldfusion.
marctrem

@VijayDev 404 pour votre lien
smarber

1
window.parent.caches.delete("call")

fermez et ouvrez le navigateur après avoir exécuté le code dans la console.


1
Quelques explications s'il vous plaît, qu'est-ce que «appeler» dans le code ci-dessus?
Anand Rockzz

@AnandRockzz ce n'est pas possible, le cache api est juste un nouveau type de cache qui peut être géré avec javascipt, donc pour supprimer quelque chose de là, vous l'avez enregistré avant voir developer.mozilla.org/en-US/docs/ Web / API / Cache
John Balvin Arias

1

window.location.reload(true)semble avoir été déconseillé par la norme HTML5. Une façon de faire cela sans utiliser de chaînes de requête consiste à utiliser l'en- Clear-Site-Datatête , qui semble normalisé .


0

Parce que le navigateur cache le même lien, vous devez ajouter une fin de nombre aléatoire de l'URL. new Date().getTime()générer un nombre différent.

Ajoutez simplement la new Date().getTime()fin du lien comme un appel

'https://stackoverflow.com/questions.php?' + new Date().getTime()

Production: https://stackoverflow.com/questions.php?1571737901173


Bienvenue à SO! Votre réponse n'est pas claire. Veuillez le modifier. Ce type de réponse, basé sur le lien, doit être commenté au cas où le lien disparaîtrait.
David García Bodego
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.