web-dev-qa-db-fra.com

Forcer le navigateur à vider le cache

Existe-t-il un moyen de mettre du code sur ma page pour que, lorsqu'une personne visite un site, elle efface le cache du navigateur afin qu'elle puisse afficher les modifications?

Langues utilisées: ASP.NET, VB.NET, et bien sûr HTML, CSS et jQuery.

245
Adam

S'il s'agit de modifications de .css et de .js, vous pouvez, par exemple, ajouter des informations telles que "_versionNo" au nom de fichier de chaque version. Par exemple:

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 bien le faire après le nom du fichier:

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.

Vous pouvez consulter ce link pour voir comment cela pourrait fonctionner.

292
Fermin

Regardez dans le cache-control et le expire META Tag.

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

Une autre pratique courante consiste à ajouter des chaînes changeant constamment à la fin des fichiers demandés. Par exemple:

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

92
Sampson

Mise à jour 2012

C'est une vieille question, mais je pense qu'il faut une réponse plus à jour, car il existe désormais un moyen de mieux contrôler la mise en cache des sites Web.

Dans Applications Web hors connexion (ce qui est vraiment un site Web HTML5) applicationCache.swapCache() peut être utilisé pour mettre à jour la version en cache de votre site Web sans qu'il soit nécessaire de recharger manuellement la page.

Ceci est un exemple de code extrait du Guide du débutant sur l'utilisation du cache d'applications sur HTML5 Rocks et expliquant comment mettre à jour les utilisateurs vers la dernière version de votre 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);

Voir aussi Utilisation du cache d'applications sur le réseau de développeurs Mozilla pour plus d'informations.

Mise à jour 2016

Les choses changent rapidement sur le Web. Cette question a été posée en 2009 et, en 2012, j'ai publié une mise à jour sur une nouvelle façon de traiter le problème décrit dans la question. Quatre autres années ont passé et maintenant, il semble que ce soit déjà obsolète. Merci à cgaldiolo pour l’avoir signalé dans les commentaires.

Actuellement, à compter de juillet 2016, le HTML Standard, Section 7.9, Applications Web hors connexion comprend un avertissement de désapprobation:

Cette fonctionnalité est en cours de suppression de la plate-forme Web . (Il s’agit d’un long processus qui prend plusieurs années.) Utiliser l’un des fichiers Les fonctionnalités d'applications Web hors connexion sont très déconseillées pour le moment . Utilisez des travailleurs de service à la place.

Il en va de même Utilisation du cache d'applications sur le réseau de développeurs Mozilla auquel j'ai fait référence en 2012:

Obsolète
Cette fonctionnalité a été supprimée des normes Web . Bien que certains navigateurs puissent encore le supporter, il est en train de être laissé tomber. Ne l'utilisez pas dans des projets anciens ou nouveaux. Pages ou applications Web l'utiliser peut casser à tout moment.

Voir aussi Bogue 1204581 - Ajout d'un avis de dépréciation pour AppCache si l'interception d'extraction de l'agent de service est activée .

71
rsp

Pas comme tel. Une méthode consiste à envoyer les en-têtes appropriés lors de la livraison de contenu pour forcer le navigateur à recharger:

S'assurer qu'une page Web n'est pas mise en cache, sur tous les navigateurs.

Si votre recherche de "cache header" ou de quelque chose de similaire sur SO, vous trouverez des exemples spécifiques à ASP.NET.

Un autre moyen, moins clair mais parfois seulement si vous ne pouvez pas contrôler les en-têtes côté serveur, consiste à ajouter un paramètre GET aléatoire à la ressource appelée:

myimage.gif?random=1923849839
26
Pekka 웃

Pour ressources statiques, la mise en cache correcte consisterait à utiliser les paramètres de requête avec la valeur de chaque déploiement ou version de fichier. Cela aura pour effet d'effacer le cache après chaque déploiement. 

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

Voici un exemple ASP.NET MVC.

<link href="@Url.Content("~/Content/Css/Reset.css")[email protected]().Assembly.GetName().Version" rel="stylesheet" type="text/css" />

N'oubliez pas de mettre à jour la version de l'assembly.

13

J'ai eu un problème similaire et voici comment je l'ai résolu:

  1. Dans le fichier index.html j'ai ajouté le manifeste:

    <html manifest="cache.manifest">
    
  2. Dans la section <head> script inclus mettant à jour le cache:

    <script type="text/javascript" src="update_cache.js"></script>
    
  3. Dans la section <body> j'ai inséré la fonction onload:

    <body onload="checkForUpdate()">
    
  4. Dans cache.manifest j'ai mis tous les fichiers que je veux mettre en cache. Il est important maintenant que cela fonctionne dans mon cas (Apache) en mettant à jour à chaque fois le commentaire "version". C'est aussi une option pour nommer les fichiers avec "? Ver = 001" ou quelque chose à la fin du nom mais c'est pas nécessaire . Changer uniquement # version 1.01 déclenche un événement de mise à jour du cache.

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

    Il est important d'inclure 1., 2. et 3. points seulement dans index.html. Autrement

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

    se produit car chaque fichier "enfant" tente de mettre en cache la page alors que celle-ci est déjà en cache.

  5. Dans le fichier update_cache.js j'ai mis ce code:

    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();
    }
    

Maintenant, il ne vous reste plus qu'à modifier les fichiers et dans manifeste, vous devez mettre à jour le commentaire de version. Maintenant, visiter la page index.html mettra à jour le cache.

Les parties de la solution ne sont pas les miennes mais je les ai trouvées via Internet et mises en place pour que cela fonctionne.

6
Wojtek Mazurek

Dans certains cas, je prenais des photos de clients en ligne et devais mettre à jour la division si une photo était modifiée. Le navigateur montrait toujours l'ancienne photo. J'ai donc utilisé le hack d'appeler une variable aléatoire GET, qui serait unique à chaque fois. La voici si cela peut aider quelqu'un

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

EDIT Comme d’autres l'ont souligné, la solution suivante est bien plus efficace car elle ne rechargera les images que lorsqu'elles seront modifiées, en identifiant cette modification par la taille du fichier:

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

Il manque de nombreuses réponses - la plupart des développeurs savent bien que désactiver le cache est inefficace. Cependant, il existe de nombreuses circonstances courantes dans lesquelles l'efficacité est sans importance et le comportement du cache par défaut est gravement perturbé.

Celles-ci incluent des tests de script itératifs imbriqués (le plus important!) Et des solutions de contournement de logiciels tiers défectueux. Aucune des solutions présentées ici ne permet de résoudre de tels scénarios courants. La plupart des navigateurs Web utilisent une mise en cache beaucoup trop agressive et ne fournissent aucun moyen sensé d'éviter ces problèmes.

4
John

Mettre à jour l'URL avec les éléments suivants fonctionne pour moi:

/custom.js?id=1

En ajoutant un numéro unique après ?id= et en l'incrémentant pour les nouvelles modifications, les utilisateurs ne doivent pas appuyer sur CTRL + F5 pour actualiser le cache. Vous pouvez également ajouter une version de hachage ou de chaîne de l’heure ou de l’époque après ?id=.

Quelque chose comme ?id=1520606295

2
nPcomp
2
S Pangborn

Vous ne savez pas si cela peut vraiment vous aider, mais c'est ainsi que la mise en cache devrait fonctionner sur n'importe quel navigateur. Lorsque le navigateur demande un fichier, il doit toujours envoyer une demande au serveur sauf s’il existe un mode "hors ligne". Le serveur lira certains paramètres tels que la date de modification ou etags. 

Le serveur renverra une réponse d'erreur 304 pour NOT MODIFIED et le navigateur devra utiliser son cache. Si etag ne valide pas côté serveur ou si la date de modification est inférieure à la date de modification actuelle, le serveur doit renvoyer le nouveau contenu avec la nouvelle date de modification, etags ou les deux. 

S'il n'y a pas de données de cache envoyées au navigateur, le comportement est indéterminé. Le navigateur peut ou non mettre en cache des fichiers qui n'indiquent pas comment ils sont mis en cache. Si vous définissez des paramètres de mise en cache dans la réponse, vos fichiers sont mis en cache correctement et le serveur peut alors choisir de renvoyer une erreur 304 ou le nouveau contenu. 

Voici comment cela devrait être fait. Utiliser des paramètres aléatoires ou un numéro de version dans les URL ressemble davantage à un piratage qu'à autre chose. 

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/

Après avoir lu, j'ai vu qu'il y avait aussi une date d'expiration. Si vous avez un problème, il se peut que vous ayez une date d'expiration configurée. En d’autres termes, lorsque le navigateur mettra votre fichier en cache, car il a une date d’expiration, il ne devrait pas avoir à le demander à nouveau avant cette date. En d'autres termes, il ne demandera jamais le fichier au serveur et ne recevra jamais un 304 non modifié. Il utilisera simplement le cache jusqu'à ce que la date d'expiration soit atteinte ou que le cache soit effacé.

Donc, je suppose que vous avez une sorte de date d'expiration et que vous devez utiliser une dernière balise modifiée ou un mélange de toutes ces fonctions et vous assurer qu'il n'y a pas de date d'expiration. 

Si les personnes ont tendance à actualiser beaucoup et que le fichier n'est pas très modifié, il peut être judicieux de définir une grande date d'expiration. 

Mes 2 centimes!

2
Loïc Faure-Lacroix

J'ai implémenté cette solution simple qui fonctionne pour moi (pas encore dans l'environnement de production):

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);
        }
    });
}

J'ai un petit fichier situé où le HTML sont:

"versio.txt":

v00.5.0014

Cette fonction est appelée dans toutes mes pages. Par conséquent, lors du chargement, elle vérifie si la valeur de la version de localStorage est inférieure à la version actuelle et effectue un test. 

location.reload(true);

... pour forcer le rechargement du serveur à la place du cache.

(évidemment, au lieu de localStorage, vous pouvez utiliser des cookies ou un autre stockage client persistant)

J'ai opté pour cette solution pour sa simplicité, car conserver uniquement un fichier "versio.txt" obligera le site complet à recharger.

La méthode queryString est difficile à mettre en œuvre et est également mise en cache (si vous passez de la version 1.1 à une version précédente, le chargement se fera à partir du cache, cela signifie que le cache n'est pas vidé, toutes les versions précédentes étant conservées en cache).

Je suis un petit débutant et j'apprécierais votre vérification et votre examen professionnels pour m'assurer que ma méthode est une bonne approche.

J'espère que ça aide.

1
Seak

Ici est la page MDSN sur la définition de la mise en cache dans 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
Dave Swersky

Forcer les navigateurs à vider le cache ou à recharger les données correctes? J'ai essayé la plupart des solutions décrites dans stackoverflow, certaines fonctionnent, mais au bout d'un moment, elles finissent par mettre en cache et affichent le script ou le fichier chargé précédemment. Existe-t-il un autre moyen d'effacer le cache (css, js, etc.) et de fonctionner avec tous les navigateurs?

J'ai trouvé jusqu'à présent que des ressources spécifiques peuvent être rechargées individuellement si vous modifiez la date et l'heure sur vos fichiers sur le serveur. "Effacer le cache" n'est pas aussi facile qu'il devrait l'être. Au lieu de vider le cache sur mes navigateurs, je me suis rendu compte qu'en "touchant" les fichiers du serveur mis en cache changeraient la date et l'heure du fichier source mis en cache sur le serveur (Testé sur Edge, Chrome et Firefox) et que la plupart des navigateurs téléchargeraient automatiquement la plupart des fichiers. nouvelle copie actuelle de ce qui se trouve sur votre serveur (code, graphiques, multimédia également). Je vous suggère simplement de copier les scripts les plus récents sur le serveur et "touchez-le au toucher" solution avant que votre programme ne s'exécute, de sorte que la date de tous vos fichiers problématiques sera remplacée par la date et l'heure les plus récentes. télécharge une nouvelle copie sur votre navigateur:

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

alors ... le reste de votre programme ...

Il a fallu un certain temps pour résoudre ce problème (de nombreux navigateurs agissant différemment selon les commandes, mais ils vérifient tous l’heure des fichiers et se comparent à la copie téléchargée dans votre navigateur. Si la date et l’heure sont différentes, l’actualisation s’effectue). ne peut pas aller dans le bon sens, il y a toujours une autre solution utilisable et meilleure. Cordialement et bon camping. Au fait, touchez (); ou des alternatives fonctionnent dans de nombreux langages de programmation inclus dans javascript en bash sh php javascript et vous pouvez les inclure ou les appeler en html.

0
Luis H Cabrejo

Outre la définition de Cache-control: no-cache, vous devez également définir l'en-tête Expires sur -1 si vous souhaitez que la copie locale soit actualisée à chaque fois (certaines versions de IE semblent l'exiger).

Voir Cache HTTP - vérifie auprès du serveur, en envoyant toujours If-Modified-Since

0
danben

Il y a une astuce qui peut être utilisée. L'astuce consiste à ajouter un paramètre/une chaîne au nom de fichier dans la balise de script et à le changer lorsque vous modifiez le fichier.

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

Le navigateur interprète la chaîne entière comme le chemin du fichier, même si ce qui suit le "?" sont des paramètres. La prochaine fois que vous mettrez votre fichier à jour, changez simplement le numéro dans la balise script de votre site Web (exemple <script src="myfile.js?version=1.0.1"></script>) et le navigateur de chaque utilisateur verra que le fichier a été modifié et récupérera une nouvelle copie.

0
Joish