Caching inattendu des résultats d’AJAX dans IE8

J’ai un problème sérieux avec les résultats de mise en cache d’Internet Explorer à partir d’une requête JQuery Ajax.

J’ai un en-tête sur ma page Web qui est mis à jour chaque fois qu’un utilisateur navigue vers une nouvelle page. Une fois la page chargée, je le fais

$.get("/game/getpuzzleinfo", null, function(data, status) { var content = "

Wikipedia Maze

"; content += "

Looking for " + data.EndTopic + "

"; content += "

Step " + data.StepCount + "

"; content += "

Level " + data.PuzzleLevel.toSsortingng() + "

"; content += "

Start Over

"; $("#wikiheader").append(content); }, "json");

Il injecte simplement les informations d’en-tête dans la page. Vous pouvez le vérifier en allant sur www.wikipediamaze.com , puis en vous connectant et en lançant un nouveau puzzle.

Dans tous les navigateurs que j’ai testés (Google Chrome, Firefox, Safari, Internet Explorer), cela fonctionne très bien sauf dans IE. La première fois, tout est injecté dans IE, mais après cela, il ne fait même plus appel à /game/getpuzzleinfo . C’est comme s’il avait mis en cache les résultats ou quelque chose.

Si je change l’appel à $.post("/game/getpuzzleinfo", ... IE le récupère très bien, mais Firefox arrête de fonctionner.

Quelqu’un peut-il s’il vous plaît faire la lumière sur pourquoi IE met en cache mes appels $.get ajax?

METTRE À JOUR

Conformément à la suggestion ci-dessous, j’ai modifié ma requête ajax en y ajoutant mon problème:

 $.ajax({ type: "GET", url: "/game/getpuzzleinfo", dataType: "json", cache: false, success: function(data) { ... } }); 

IE est notoire pour sa mise en cache agressive des réponses Ajax. Comme vous utilisez jQuery, vous pouvez définir une option globale:

 $.ajaxSetup({ cache: false }); 

jQuery ajoute alors une valeur aléatoire à la chaîne de requête de requête, empêchant ainsi IE de mettre en cache la réponse.

Notez que si vous avez d’autres appels Ajax sur lesquels vous voulez mettre en cache, cela les désactivera également. Dans ce cas, passez à la méthode $ .ajax () et activez cette option explicitement pour les requêtes nécessaires.

Voir http://docs.jquery.com/Ajax/jQuery.ajaxSetup pour plus d’informations.

Comme mentionné plus haut , les GET sont mis en cache.

Il y a plusieurs façons de lutter contre cela. En plus de modifier l’en-tête de réponse, vous pouvez également append une variable de chaîne de requête générée de manière aléatoire à la fin de l’URL ciblée. De cette façon, IE pensera qu’il s’agit d’une URL différente chaque fois qu’elle est demandée.

Il existe plusieurs façons de le faire (par exemple, utiliser Math.random() , une variante de la date, etc.).

Voici une façon de le faire:

 var oDate = new Date(); var sURL = "/game/getpuzzleinfo?randomSeed=" + oDate.getMilliseconds(); $.get(sURL, null, function(data, status) { // your work }); 

Gets sont toujours mis en cache. Une stratégie qui peut fonctionner consiste à éditer l’en-tête de réponse et à indiquer au client de ne pas mettre les informations en cache ou d’expirer le cache très bientôt.

Si vous appelez la page ashx, vous pouvez également désactiver la mise en cache sur le serveur avec le code suivant:

 context.Response.Cache.SetCacheability(HttpCacheability.NoCache); context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); 

c’est ce que je fais pour les appels ajax:

 var url = "/mypage.aspx"; // my other vars i want to add go here url = url + "&sid=" + Math.random(); // make ajax call 

Cela marche plutôt bien pour moi.

NickFitz donne une bonne réponse, mais vous devrez également désactiver la mise en cache dans IE9. Pour cibler uniquement IE8 et IE9, vous pouvez le faire.

  

Les réponses ici sont très utiles pour ceux qui utilisent jQuery ou, pour une raison quelconque, utilisent directement l’object xmlHttpRequest …

Si vous utilisez le proxy de service Microsoft généré automatiquement, il n’est pas aussi simple à résoudre.

L’astuce consiste à utiliser la méthode Sys.Net.WebRequestManager.add_invokingRequest dans le gestionnaire d’événements pour modifier l’URL de la requête:

 networkRequestEventArgs._webRequest._url = networkRequestEventArgs._webRequest._url + '&nocache=' + new Date().getMilliseconds(); 

J’ai blogué à ce sujet: http://yoavniran.wordpress.com/2010/04/27/ie-caching-ajax-results-how-to-fix/

Je viens juste d’écrire un blog sur ce problème précis en utilisant uniquement ExtJS ( http://thecodeabode.blogspot.com/2010/10/cache-busting-ajax-requests-in-ie.html )

Le problème était que j’utilisais un format de réécriture d’url spécifique, je ne pouvais pas utiliser les parameters de chaîne de requête classiques (? Param = value), donc j’avais écrit le paramètre de contournement de cache en tant que variable postée. que l’utilisation des variables POST est un peu plus sûre que GET, simplement parce que beaucoup de frameworks MVC utilisent le pattern

protocole: // host / controller / action / param1 / param2

et donc le mappage du nom de la variable à la valeur est perdu, et les parameters sont simplement empilés … donc lors de l’utilisation d’un paramètre de buster de cache GET

ie protocole: // host / controller / action / param1 / param2 / no_cache122300201

no_cache122300201 peut être confondu avec un paramètre $ param3 qui pourrait avoir une valeur par défaut

c’est à dire

action de la fonction publique ($ param1, $ param2, $ param3 = “valeur par défaut”) {//..//}

aucune chance que cela se produise avec les bloqueurs de cache POSTED

Si vous utilisez Asp.net MVC, il suffit d’append cette ligne en haut de l’action du contrôleur

  [OutputCache(NoStore=true, Duration = 0, VaryByParam = "None")] public ActionResult getSomething() { } 

IE a le droit de faire cette mise en cache; Pour que l’élément ne soit pas mis en cache, les en-têtes doivent être définis en conséquence.

Si vous utilisez ASP.NET MVC, vous pouvez écrire un ActionFilter ; Dans OnResultExecuted , vérifiez filterContext.HttpContext.Request.IsAjaxRequest() . Si c’est le cas, définissez l’en-tête d’expiration de la réponse: filterContext.HttpContext.Response.Expires = -1;

Selon http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/ :

Certaines personnes préfèrent utiliser l’en-tête Cache-Control: no-cache au lieu d’expirer. Voici la différence:
Cache-Control: no-cache – absolument pas de cache
Expire: -1 – le navigateur contacte généralement le serveur Web pour les mises à jour de cette page via une demande conditionnelle If-Modified-Since. Toutefois, la page rest dans le cache du disque et est utilisée dans des situations appropriées sans contacter le serveur Web distant, par exemple lorsque les boutons BACK et FORWARD sont utilisés pour accéder à l’historique de navigation ou lorsque le navigateur est en mode hors connexion.