$ .getJSON renvoyant les données mises en cache dans IE8

102

Je joue avec ASP.net MVC et JQuery pour le moment. J'ai rencontré un comportement qui ne semble pas logique.

J'appelle la $.getJSONfonction de JQuery pour remplir certains div. L'événement est déclenché sur l' $(document).readyévénement. Cela fonctionne parfaitement.

Il y a un petit AJAX.BeginFormqui ajoute une autre valeur à utiliser lors du remplissage des divs. Il appelle la fonction distante correctement et en cas de succès appelle la fonction javascript d'origine pour repeupler les divs.

Voici la partie étrange: Dans FireFox et Chrome - Tout fonctionne. MAIS Dans IE8 (bêta), ce deuxième appel au script populate Div (qui appelle la fonction $ .getJSON) obtient les données en cache et ne demande pas au serveur!

J'espère que cette question a du sens: En bref - Pourquoi $.getJSONobtenir des données en cache? Et pourquoi n'affecte-t-il que IE8?

Andrew Harry
la source
Étrangement, je vois ce bogue non seulement dans IE, mais aussi dans Firefox. La désactivation de la mise en cache ajax dans jquery m'a aidé.
Josef Sábl

Réponses:

67

Juste pour vous le faire savoir, Firefox et Chrome considèrent toutes les requêtes Ajax comme non cachable. IE (toutes les versions) traite l'appel Ajax comme toute autre requête Web. C'est pourquoi vous voyez ce comportement.
Comment forcer IE à télécharger des données à chaque demande:

  • Comme vous l'avez dit, utilisez l'option 'cache' ou 'nocache' dans JQuery
  • Ajoutez un paramètre aléatoire à la requête (moche, mais fonctionne :))
  • Côté serveur, définissez la cachabilité (par exemple en utilisant un attribut, voir ci-dessous)

Code:

public class NoCacheAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        context.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    }
}
Nico
la source
1
Cette solution me plaît. J'aime vraiment l'élégance de l'application d'un attibute dans MVC
Andrew Harry
1
Il existe aujourd'hui un OutputCacheAttribute OOTB.
bzlm
1
@bzlm mais c'est plus facile à rechercher
Simon_Weaver
consultez formatinternet.wordpress.com/2010/01/14/… pour une solution côté client
Ivo
1
En fait, c'est l'inverse, mais je suis d'accord en tant que développeur IE nécessite de la patience :)
Nico
107

Voilà comment cela a fonctionné pour moi ...

$.ajaxSetup({ cache: false });
$.getJSON("/MyQueryUrl",function(data,item) {
     // do stuff with callback data
     $.ajaxSetup({ cache: true });
   });
Jitesh Patil
la source
J'avais du mal avec ce problème et votre solution m'a permis de le résoudre rapidement. :) J'ai une question, savez-vous quelles options peuvent être utilisées pour $ .ajaxSetup? La documentation jQuery ne fournit malheureusement pas de détails ...
Achimnol
1
Les options disponibles sont identiques à $ .ajax Voir docs.jquery.com/Ajax/jQuery.ajax#options pour plus d'informations
Dan Esparza
12
Un petit avertissement pour le code ci-dessus - il contient une condition de concurrence. Étant donné que l'appel et sa réponse sont asynchrones, vous devez appeler $.ajaxSetup({ cache: true });juste après le getJSON()et non dans le rappel.
sax
16

Merci Kent pour votre réponse. Utilisation de $ .ajax ('{cache: no}'); a parfaitement fonctionné. [Éditer]

Ou du moins je pensais l'avoir fait. Il semble que le jquery $ .getJSON ne lit pas les modifications apportées à l'objet $ .ajax.

La solution qui a fini par fonctionner était d'ajouter un nouveau paramètre manuellement

var noCache = Date();
$.getJSON("/somepage/someaction", { "noCache": noCache }, Callback);

la résolution de la date est seulement à la minute; ce qui signifie effectivement que cette solution reste en cache pendant jusqu'à une minute. Ceci est acceptable pour mes besoins.

Andrew Harry
la source
9
var noCache = nouvelle Date (). getTime (); // vous donnera le ms
scunliffe
merci Scunliffe! - Je suis assez nouveau en javascript, ASP MVC m'a ouvert de nouveaux horizons
Andrew Harry
Vous pouvez également essayer quelque chose comme Math.Random ().
Falkayn
@Falkayn - difficile Math.Random()pourrait être utilisé, ses résultats seront inconnus et vous pourriez obtenir le même nombre deux fois de suite (ou plus). l'utilisation new Date().getTime()garantira qu'il ne sera jamais répété. (à moins que vous ne puissiez remonter le temps;))
Dementic
11

J'ai résolu ce même problème en plaçant l'attribut suivant sur l'action dans le contrôleur:

[OutputCache(Duration = 0, VaryByParam = "None")]
Gars
la source
Merveilleux! Super d'avoir des alternatives (j'ai choisi celle-ci). Merci à tous les contributeurs!
Anders Juul
Fonctionne très bien avec Asp.Net MVC 4.0
Mayank
4

Si vous utilisez ASP.net MVC, envisagez d'ajouter une méthode d'extension pour implémenter facilement aucune mise en cache comme ceci:

    public static void NoCache(this HttpResponse Response)
    {
        Response.Cache.SetNoStore();
        Response.Cache.SetExpires(DateTime.MinValue);
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Response.Cache.SetValidUntilExpires(false);

        Response.Expires = -1;
        Response.ExpiresAbsolute = DateTime.MinValue;
        Response.AddHeader("Cache-Control", "no-cache");
        Response.AddHeader("Pragma", "no-cache");
    }
Josh
la source
Bonne idée - vous appelez donc cette méthode d'extension sur le serveur pendant le rappel, n'est-ce pas?
Guy
2

Vous devrez peut-être envoyer un disjoncteur de cache.

Je recommanderais d'utiliser $ .ajax ({cache: no}) au cas où (ajoute un suffixe aléatoire à la requête get)

(J'ai tendance à utiliser $ .ajax partout ces jours-ci, plus accordable)

Kent Fredric
la source
Merci pour votre réponse! ... je ne l'ai pas encore essayé. Fournira des commentaires sous peu
Andrew Harry