Empêcher la réponse jload de .load d'être mise en cache

244

J'ai le code suivant faisant une demande GET sur une URL:

$('#searchButton').click(function() {
    $('#inquiry').load('/portal/?f=searchBilling&pid=' + $('#query').val());            
});

Mais le résultat renvoyé n'est pas toujours reflété. Par exemple, j'ai modifié la réponse qui a craché une trace de pile, mais la trace de pile ne s'est pas affichée lorsque j'ai cliqué sur le bouton de recherche. J'ai regardé le code PHP sous-jacent qui contrôle la réponse ajax et il avait le bon code et visiter la page a montré directement le résultat correct mais la sortie retournée par .load était ancienne.

Si je ferme le navigateur et le rouvre, cela fonctionne une fois, puis commence à renvoyer les informations périmées. Puis-je contrôler cela par jQuery ou dois-je avoir mes en-têtes de sortie de script PHP pour contrôler la mise en cache?

dragonmantank
la source

Réponses:

419

Vous devez utiliser une fonction plus complexe comme $.ajax()si vous souhaitez contrôler la mise en cache sur une base par demande. Ou, si vous voulez simplement le désactiver pour tout, mettez ceci en haut de votre script:

$.ajaxSetup ({
    // Disable caching of AJAX responses
    cache: false
});
John Millikin
la source
2
Merci! Est-ce même situé dans la documentation jQuery? Ahh ... je l'ai trouvé. Genre de baies. Cela avait donné des coups de pied pendant la majeure partie de la journée ... Merci encore!
bytebender
35
Tout ce cache: false ne fait qu'ajouter un nombre (je crois que c'est un horodatage) à la fin d'une URL lors de la demande. L'autre endroit pour gérer les paramètres du cache provient du serveur ou de l'application Web en définissant divers en-têtes de réponse HTTP, comme Expires, Pragma, etc ...
Bryan Rehbein
1
Cette information m'a beaucoup aidé - elle m'a aidé à localiser un bug vraiment lancinant
Luke101
Aimer! Maintenant, je n'ai plus à utiliser d'appels .ajax trop verbeux et je peux utiliser les raccourcis!
Gattster
1
Brillant - j'avais trouvé cette fonction mais je ne savais pas qu'elle fonctionnerait sur quelque chose d'aussi simple que de charger un document texte dans une div en utilisant .load
Dan
107

Voici un exemple de la façon de contrôler la mise en cache sur une base par demande

$.ajax({
    url: "/YourController",
    cache: false,
    dataType: "html",
    success: function(data) {
        $("#content").html(data);
    }
});
Marshall
la source
7
J'aime bien mieux que de désactiver la mise en cache.
Paul Tomblin
J'aime aussi cela pour ne pas désactiver toute mise en cache. Consultez également cet article [link] stackoverflow.com/questions/4245231/… pour le filtrage.
Dan Doyon
@Marshall le code ici u n'a pas mentionné le type POST ou Get ...... alors quel est le défaut pour jquery?
Thomas
la méthode par défaut est GET
Rich T.
35

Une façon consiste à ajouter un numéro unique à la fin de l'URL:

$('#inquiry').load('/portal/?f=searchBilling&pid=' + $('#query').val()+'&uid='+uniqueId());

Où vous écrivez uniqueId () pour retourner quelque chose de différent chaque fois qu'il est appelé.

Lou Franco
la source
1
Encore plus facile, utilisez-le (+new Date)(ou new Date().getTime()si vous êtes un adepte). Voir Comment obtenir un horodatage en JavaScript?
Thirdender
Posez une nouvelle question et liez-la ici. Si vous l'avez fait correctement, vous générez des URL complètement nouvelles, donc elles ne peuvent pas être mises en cache par le navigateur.
Lou Franco
utilisé pour résoudre un problème sans rapport. fonctionne un régal.
Alex
9

Une autre approche pour mettre la ligne ci-dessous uniquement lorsque vous avez besoin d'obtenir des données du serveur, ajoutez la ligne ci-dessous avec votre URL ajax.

'? _ =' + Math.round (Math.random () * 10000)

Gomes
la source
6
/**
 * Use this function as jQuery "load" to disable request caching in IE
 * Example: $('selector').loadWithoutCache('url', function(){ //success function callback... });
 **/
$.fn.loadWithoutCache = function (){
 var elem = $(this);
 var func = arguments[1];
 $.ajax({
     url: arguments[0],
     cache: false,
     dataType: "html",
     success: function(data, textStatus, XMLHttpRequest) {
   elem.html(data);
   if(func != undefined){
    func(data, textStatus, XMLHttpRequest);
   }
     }
 });
 return elem;
}
Sasha
la source
Cela a presque fait l'affaire pour moi. Sauf que la fonction de rappel a la valeur "this" incorrecte. J'ai changé l'appel func () comme suit pour résoudre ce problème: func.call(elem, data, textStatus, XMLHttpRequest);
GeekyMonkey
5

Sasha est une bonne idée, j'utilise un mix.

Je crée une fonction

LoadWithoutCache: function (url, source) {
    $.ajax({
        url: url,
        cache: false,
        dataType: "html",
        success: function (data) {
            $("#" + source).html(data);
            return false;
        }
    });
}

Et invoquer pour différentes parties de ma page par exemple sur init:

Init: fonction (actionUrl1, actionUrl2, actionUrl3) {

var ExampleJS = {

Init: function (actionUrl1, actionUrl2, actionUrl3)           ExampleJS.LoadWithoutCache(actionUrl1, "div1");

ExampleJS.LoadWithoutCache (actionUrl2, "div2"); ExampleJS.LoadWithoutCache (actionUrl3, "div3"); }},

NGRAUPEN
la source
4

C'est particulièrement gênant dans IE. Fondamentalement, vous devez renvoyer les en-têtes HTTP «sans cache» avec votre réponse du serveur.

Xian
la source
3

Pour PHP, ajoutez cette ligne à votre script qui fournit les informations que vous souhaitez:

header("cache-control: no-cache");

ou, ajoutez une variable unique à la chaîne de requête:

"/portal/?f=searchBilling&x=" + (new Date()).getTime()
nickf
la source
L'option cache: false de la fonction $ .ajax ajoute automatiquement la variable unique à la chaîne de requête comme votre deuxième suggestion.
Bryan Rehbein
2

N'utilisez PAS d'horodatage pour créer une URL unique car chaque page que vous visitez est mise en cache dans DOM par jquery mobile et vous rencontrez rapidement des problèmes de manque de mémoire sur les mobiles.

$jqm(document).bind('pagebeforeload', function(event, data) {
    var url = data.url;
    var savePageInDOM = true;

    if (url.toLowerCase().indexOf("vacancies") >= 0) {
        savePageInDOM = false;
    }

    $jqm.mobile.cache =  savePageInDOM;
})

Ce code s'active avant le chargement de la page, vous pouvez utiliser url.indexOf () pour déterminer si l'URL est celle que vous souhaitez mettre en cache ou non et définir le paramètre de cache en conséquence.

N'utilisez pas window.location = ""; pour changer l'URL, sinon vous accédez à l'adresse et pagebeforeload ne se déclenche pas. Pour contourner ce problème, utilisez simplement window.location.hash = "";

user1545320
la source
1
qu'est-ce que le $ jqm? $ jqm = $? $ .mobile.cache n'est pas défini
Luciuz
2

Si vous souhaitez vous en tenir à la méthode .load () de Jquery, ajoutez quelque chose d'unique à l'URL comme un horodatage JavaScript. msgstr "+ nouveau Date (). getTime ()". Remarquez que j'ai dû ajouter un "& time =" afin qu'il ne modifie pas votre variable pid.

$('#searchButton').click(function() {
$('#inquiry').load('/portal/?f=searchBilling&pid=' + $('#query').val()+'&time='+new Date().getTime());            
});
NickStees
la source
1

Vous pouvez remplacer la fonction de chargement jquery par une version dont le cache est défini sur false.

(function($) {
  var _load = jQuery.fn.load;
  $.fn.load = function(url, params, callback) {
  if ( typeof url !== "string" && _load ) {
        return _load.apply( this, arguments );
  }
    var selector, type, response,
      self = this,
      off = url.indexOf(" ");

    if (off > -1) {
      selector = stripAndCollapse(url.slice(off));
      url = url.slice(0, off);
    }

    // If it's a function
    if (jQuery.isFunction(params)) {

      // We assume that it's the callback
      callback = params;
      params = undefined;

      // Otherwise, build a param string
    } else if (params && typeof params === "object") {
      type = "POST";
    }

    // If we have elements to modify, make the request
    if (self.length > 0) {
      jQuery.ajax({
        url: url,

        // If "type" variable is undefined, then "GET" method will be used.
        // Make value of this field explicit since
        // user can override it through ajaxSetup method
        type: type || "GET",
        dataType: "html",
        cache: false,
        data: params
      }).done(function(responseText) {

        // Save response for use in complete callback
        response = arguments;

        self.html(selector ?

          // If a selector was specified, locate the right elements in a dummy div
          // Exclude scripts to avoid IE 'Permission Denied' errors
          jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) :

          // Otherwise use the full result
          responseText);

        // If the request succeeds, this function gets "data", "status", "jqXHR"
        // but they are ignored because response was set above.
        // If it fails, this function gets "jqXHR", "status", "error"
      }).always(callback && function(jqXHR, status) {
        self.each(function() {
          callback.apply(this, response || [jqXHR.responseText, status, jqXHR]);
        });
      });
    }

    return this;
  }
})(jQuery);

Placez-le quelque part dans le monde où il s'exécutera après le chargement de jquery et vous devriez être prêt. Votre code de chargement existant ne sera plus mis en cache.

Adam Bell
la source
0

Essaye ça:

$("#Search_Result").load("AJAX-Search.aspx?q=" + $("#q").val() + "&rnd=" + String((new Date()).getTime()).replace(/\D/gi, ''));

Cela fonctionne bien quand je l'ai utilisé.


la source
0

J'ai remarqué que si certains serveurs (comme Apache2) ne sont pas configurés pour autoriser ou refuser spécifiquement toute "mise en cache", le serveur peut par défaut envoyer une réponse "en cache", même si vous définissez les en-têtes HTTP sur "no-cache". Assurez-vous donc que votre serveur ne "cache" rien avant d'envoyer une réponse:

Dans le cas d'Apache2, vous devez

1) éditez le fichier "disk_cache.conf" - pour désactiver le cache ajoutez la directive "CacheDisable / local_files"

2) charger les modules mod_cache (Sur Ubuntu "sudo a2enmod cache" et "sudo a2enmod disk_cache")

3) redémarrez Apache2 (Ubuntu "sudo service apache2 restart");

Cela devrait faire l'affaire en désactivant le cache du côté des serveurs. À votre santé! :)

techexpert
la source
0

Ce code peut vous aider

var sr = $("#Search Result");
sr.load("AJAX-Search.aspx?q=" + $("#q")
.val() + "&rnd=" + String((new Date).getTime())
.replace(/\D/gi, ""));
Ahmad Dwaik 'Warlock'
la source