Il semble que si je charge du contenu dynamique à l'aide de $.get()
, le résultat est mis en cache dans le navigateur.
Ajouter une chaîne aléatoire dans QueryString semble résoudre ce problème (j'utilise new Date().toString()
), mais cela ressemble à un hack.
Y a-t-il un autre moyen d'y parvenir? Ou, si une chaîne unique est le seul moyen d'y parvenir, des suggestions autres que new Date()
?
J'utilise new Date().getTime()
, ce qui évitera les collisions à moins que plusieurs requêtes ne se produisent dans la même milliseconde:
$.get('/getdata?_=' + new Date().getTime(), function(data) {
console.log(data);
});
Edit: Cette réponse a plusieurs années. Cela fonctionne toujours (donc je ne l'ai pas supprimé), mais il existe des moyens meilleurs/plus propres de réaliser cela maintenant . Ma préférence va à la méthode this , mais la réponse this est également utile si vous souhaitez désactiver la mise en cache pour chaque requête au cours de la durée de vie d'une page.
Les éléments suivants empêcheront la mise en cache de toutes les futures demandes AJAX, quelle que soit la méthode jQuery que vous utilisez ($ .get, $ .ajax, etc.)
$.ajaxSetup({ cache: false });
$ .Get () de JQuery mettra en cache les résultats. Au lieu de
$.get("myurl", myCallback)
vous devriez utiliser $ .ajax, ce qui vous permettra de désactiver le cache:
$.ajax({url: "myurl", success: myCallback, cache: false});
une autre solution consiste à ne fournir aucun en-tête de cache côté serveur dans le code qui génère la réponse à l'appel ajax:
response.setHeader( "Pragma", "no-cache" );
response.setHeader( "Cache-Control", "no-cache" );
response.setDateHeader( "Expires", 0 );
Toutes les réponses ici laissent une empreinte sur l'URL demandée qui apparaîtra dans les journaux d'accès du serveur.
J'avais besoin d'une solution basée sur les en-têtes, sans effet secondaire, et j'ai trouvé que cela pouvait être réalisé en configurant les en-têtes mentionnés dans Comment contrôler la mise en cache des pages Web, sur tous les navigateurs? .
Le résultat, fonctionnant pour Chrome au moins, serait:
$.ajax({
url: url,
headers: {
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0'
}
});
Personnellement, j'estime que la méthode de la chaîne de requête est plus fiable que d'essayer de définir des en-têtes sur le serveur - rien ne garantit qu'un proxy ou un navigateur ne le mettra pas en cache de toute façon (certains navigateurs sont pires que d'autres - ne nommant aucun nom).
J'utilise habituellement Math.random()
mais je ne vois pas d'inconvénient à utiliser la date (vous ne devriez pas faire les requêtes AJAX assez rapidement pour obtenir la même valeur deux fois).
Après la documentation: http://api.jquery.com/jquery.ajax/
vous pouvez utiliser la propriété cache
avec:
$.ajax({
method: "GET",
url: "/Home/AddProduct?",
data: { param1: value1, param2: value2},
cache: false,
success: function (result) {
// TODO
}
});
Bien sûr, les techniques de "suppression du cache" feront le travail, mais cela ne se produira pas si le serveur indique au client que la réponse ne doit pas être mise en cache. Dans certains cas, il est avantageux de mettre en cache les réponses, parfois pas. Laissez le serveur décider de la durée de vie correcte des données. Vous voudrez peut-être le changer plus tard. Beaucoup plus facile à faire depuis le serveur que depuis de nombreux endroits différents dans votre code d'interface utilisateur.
Bien sûr, cela n’aide en rien si vous n’avez aucun contrôle sur le serveur.
Qu'en est-il de l'utilisation d'une demande POST au lieu d'un GET ...? (Ce que vous devriez de toute façon ...)
Peut-être devriez-vous plutôt regarder $ .ajax () (si vous utilisez jQuery, à quoi il ressemble). Jetez un coup d'œil à: http://docs.jquery.com/Ajax/jQuery.ajax#options et à l'option "cache".
Une autre approche consisterait à examiner comment mettre en cache des éléments côté serveur.
Un petit ajout aux excellentes réponses fournies: Si vous utilisez une solution de sauvegarde non-ajax pour les utilisateurs sans JavaScript, vous devrez quand même corriger ces en-têtes côté serveur. Ce n'est pas impossible, bien que je comprenne ceux qui l'abandonnent;)
Je suis sûr qu'il y a une autre question sur SO qui vous donnera l'ensemble des en-têtes appropriés. Je ne suis pas entièrement convaincu que la réponse de miceus couvre toutes les bases à 100%.
Pour ceux d'entre vous qui utilisent l'option cache
de $.ajaxSetup()
sur Safari mobile, il semble que vous deviez peut-être utiliser un horodatage pour les POST, car Safari le met également en cache. Selon la documentation sur $.ajax()
(vers laquelle vous êtes dirigé à partir de $.ajaxSetup()
):
Définir le cache sur false ne fonctionnera correctement qu'avec les requêtes HEAD et GET. Cela fonctionne en ajoutant "_ = {timestamp}" aux paramètres GET. Le paramètre n'est pas nécessaire pour les autres types de demandes, sauf dans IE8 lorsqu'un POST est appliqué à une URL déjà demandée par un GET.
Donc, définir cette option seule ne vous aidera pas dans le cas que j'ai mentionné ci-dessus.
Maintenant, il est facile de le faire en activant/désactivant l'option de cache dans votre demande ajax, comme ceci
$(function () {
var url = 'your url goes here';
$('#ajaxButton').click(function (e) {
$.ajax({
url: url,
data: {
test: 'value'
},
cache: true, //cache enabled, false to reverse
complete: doSomething
});
});
});
//ToDo after ajax call finishes
function doSomething(data) {
console.log(data);
}
});
Fondamentalement, ajoutez simplement cache:false;
dans l'ajax où vous pensez que le contenu changera au fur et à mesure de l'avancement. Et l'endroit où le contenu ne changera pas, vous pouvez l'omettre. De cette façon, vous obtiendrez la nouvelle réponse à chaque fois
Ajax Caching d’Internet Explorer: Qu'allez-vous faire à ce sujet? suggère trois approches:
- Ajoutez un jeton de contournement du cache à la chaîne de requête, par exemple? Date = [timestamp]. Dans jQuery et YUI, vous pouvez leur dire de le faire automatiquement.
- Utilisez POST au lieu d'un GET
- Envoyer un en-tête de réponse HTTP qui interdit spécifiquement aux navigateurs de le mettre en cache
Comme @Athasach l'a dit, selon la documentation jQuery, $.ajaxSetup({cache:false})
ne fonctionnera pas pour les requêtes autres que GET et HEAD.
Vous feriez mieux de renvoyer un en-tête Cache-Control: no-cache
de votre serveur quand même. Il offre une séparation plus nette des préoccupations.
Bien entendu, cela ne fonctionnerait pas pour les URL de service qui n'appartiennent pas à votre projet. Dans ce cas, vous pouvez envisager de remplacer le service tiers par un code serveur à partir du code du serveur plutôt que de l'appeler à partir du code client.
Si vous utilisez IE 9, vous devez utiliser les éléments suivants devant la définition de la classe de votre contrôleur:
[OutputCache (NoStore = true, Duration = 0, VaryByParam = "*")]
classe publique TestController: Controller
Cela empêchera le navigateur de se mettre en cache.
Détails sur ce lien: http://dougwilsonsa.wordpress.com/2011/04/29/disabling-a9-ajax-response-caching-asp-net-mvc-3-jquery/
En fait, cela a résolu mon problème.
Si vous utilisez .net ASP MVC, désactivez la mise en cache de l'action du contrôleur en ajoutant l'attribut suivant à la fonction de point de terminaison: [OutputCacheAttribute (VaryByParam = "*", Duration = 0, NoStore = true) ]