web-dev-qa-db-fra.com

Mise en cache inattendue de AJAX résulte en IE8

Je rencontre un problème sérieux avec les résultats de mise en cache d'Internet Explorer à partir d'une demande JQuery Ajax.

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

$.get("/game/getpuzzleinfo", null, function(data, status) {
    var content = "<h1>Wikipedia Maze</h1>";
    content += "<p class='endtopic'>Looking for <span><a title='Opens the topic you are looking for in a separate tab or window' href='" + data.EndTopicUrl + "' target='_blank'>" + data.EndTopic + "<a/></span></p>";
    content += "<p class='step'>Step <span>" + data.StepCount + "</span></p>";
    content += "<p class='level'>Level <span>" + data.PuzzleLevel.toString() + "</span></p>";
    content += "<p class='startover'><a href='/game/start/" + data.PuzzleId.toString() + "'>Start Over</a></p>";

    $("#wikiheader").append(content);

}, "json");

Il injecte simplement des 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. Tout est injecté très bien dans IE la première fois mais après cela, il ne fait même jamais appel à /game/getpuzzleinfo. C'est comme s'il avait mis en cache les résultats ou quelque chose.

Si je change l'appel en $.post("/game/getpuzzleinfo", ... IE le récupère très bien. Mais Firefox cesse de fonctionner.

Quelqu'un peut-il nous éclairer sur la raison pour laquelle IE met en cache mon $.get appels ajax?

[~ # ~] mise à jour [~ # ~]

Selon la suggestion ci-dessous, j'ai changé ma demande ajax en ceci, ce qui a résolu mon problème:

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

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

$.ajaxSetup({
    cache: false
});

ce qui amènera jQuery à ajouter une valeur aléatoire à la chaîne de requête, empêchant ainsi IE de mettre en cache la réponse.

Notez que si vous avez d'autres appels Ajax en cours là où vous souhaitez mettre en cache, cela le désactivera également pour ceux-ci. Dans ce cas, passez à l'utilisation de 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.

176
NickFitz

Comme marr75 mentionné, les GET sont mis en cache.

Il existe deux façons de lutter contre cela. Outre la modification de l'en-tête de réponse, vous pouvez également ajouter 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 que c'est une URL différente chaque fois qu'elle est demandée.

Il existe plusieurs façons de le faire (comme l'utilisation de Math.random(), une variation de la date, etc.).

Voici une façon de procéder:

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

Obtient toujours en cache. Une stratégie qui peut fonctionner consiste à modifier l'en-tête de réponse et à dire au client de ne pas mettre en cache les informations ou de faire expirer le cache très bientôt.

3
marr75

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); 
2
Andrej Benedik

voici 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.

1
Jason

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;

<!--[if lte IE 9]>
<script>
    $.ajaxSetup({
        cache: false
    });
</script>
<![endif]-->
1
Stuart Hallows

Les réponses ici sont très utiles pour ceux qui utilisent jQuery ou pour une raison quelconque utilisent directement l'objet xmlHttpRequest ...

Si vous utilisez le proxy de service Microsoft généré automatiquement, ce 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 demande:

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/

0
poeticGeek

Si vous utilisez ASP.NET MVC, il suffit d'ajouter cette ligne au-dessus de l'action du contrôleur:

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

}
0
batmaci

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

Le problème était que lorsque j'utilisais un format de réécriture d'URL spécifique, je ne pouvais pas utiliser les paramètres de chaîne de requête conventionnels (? Param = valeur), j'ai donc dû écrire le paramètre de contournement du cache en tant que variable publiée à la place ..... J'aurais pensé qu'en utilisant POST sont un peu plus sûres que GET, simplement parce que beaucoup de frameworks MVC utilisent le modèle

protocole: // Hôte/contrôleur/action/param1/param2

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

par exemple, protocole: // Hôte/contrôleur/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 fonction publique ($ param1, $ param2, $ param3 = "valeur par défaut") {//..//}

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

0
Ben