135 votes

Mise en cache inattendue des résultats AJAX dans IE8

J'ai un sérieux problème avec Internet Explorer qui met en cache les résultats 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 fais ceci

$.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='http://stackoverflow.com/game/start/" + data.PuzzleId.toString() + "'>Start Over</a></p>";

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

}, "json");

Il ne fait qu'injecter des informations d'en-tête dans la page. Vous pouvez le vérifier en allant sur www.wikipediamaze.com et ensuite se connecter et commencer un nouveau puzzle.

Dans tous les navigateurs que j'ai testés (Google Chrome, Firefox, Safari, Internet Explorer), il fonctionne parfaitement. sauf en IE. Tout est injecté sans problème dans IE. la première fois mais après cela, il ne fait même pas l'appel à /game/getpuzzleinfo . C'est comme s'il avait mis les résultats en cache ou quelque chose comme ça.

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

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

UPDATE

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

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

8 votes

Merci de poser cette question. Je suis sans voix face au comportement de ce navigateur.

1 votes

Bonne question, et site web vraiment cool. Bonne idée.

177voto

NickFitz Points 14977

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

$.ajaxSetup({
    cache: false
});

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

Notez que si vous avez d'autres appels Ajax en cours pour lesquels vous souhaitez une mise en cache, cela désactivera également la mise en cache pour ces appels. Dans ce cas, utilisez 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.

1 votes

Vous pouvez également ajouter un horodatage à la fin de vos urls. Je ne sais pas pourquoi jQuery n'utilise pas plutôt cette approche.

14 votes

@Eric : c'est ce que jQuery fait en interne - l'option "cache : false" lui indique simplement de le faire.

0 votes

Pourquoi jquery ne l'active-t-il pas par défaut ?

8voto

Tom Points 5872

Como marr75 mentionnés, GET sont mis en cache.

Il existe plusieurs façons de lutter contre ce problème. 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 qu'il s'agit d'une URL différente à chaque fois qu'elle sera demandée.

Il existe plusieurs façons de procéder (par exemple en utilisant Math.random() une variation 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
});

3voto

marr75 Points 4127

Les données récupérées peuvent toujours être mises en cache. Une stratégie qui peut fonctionner consiste à modifier l'en-tête de la réponse et à indiquer au client de ne pas mettre l'information en cache ou d'expirer le cache très bientôt.

0 votes

Ça semble être une bonne idée. Comment dois-je m'y prendre ?

1 votes

C'est une question délicate, qui dépend de votre code côté serveur. Voir l'entrée wikipedia "List of HTTP headers" pour un peu d'orientation. Exemples : Cache-Control : no-cache Expires : Thu, 01 Dec 1994 16:00:00 GMT En gros, vous devez ajouter ces en-têtes de réponse à votre réponse http. C'est assez simple en ASP.NET, Ruby et PHP. Il suffit de consulter le langage côté serveur que vous utilisez + modifier les en-têtes de réponse.

3 votes

Par ailleurs, et ce n'est pas du tout une critique de Jquery (j'adore cette bibliothèque), la méthode consistant à ajouter un paramètre de chaîne de requête aléatoire est sûre mais impolie pour le client (elle peut le conduire à conserver dans le cache des éléments qui ne seront plus jamais utilisés).

2voto

Andrej Benedik Points 31

Si vous appelez une 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);

1voto

Jason Points 20255

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

ça marche plutôt bien pour moi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X