Zatrzymaj buforowanie odpowiedzi jQuery .load


244

Mam następujący kod wysyłający żądanie GET na adres URL:

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

Ale zwracany wynik nie zawsze jest odzwierciedlany. Na przykład zmieniłem odpowiedź, która wypluła ślad stosu, ale ślad stosu nie pojawił się po kliknięciu przycisku wyszukiwania. Spojrzałem na podstawowy kod PHP, który kontroluje odpowiedź ajax i miał poprawny kod, a odwiedzenie strony bezpośrednio pokazało poprawny wynik, ale dane wyjściowe zwrócone przez .load były stare.

Jeśli zamknę przeglądarkę i otworzę ją ponownie, działa to raz, a następnie zaczyna zwracać nieaktualne informacje. Czy mogę to kontrolować za pomocą jQuery, czy muszę mieć nagłówki wyjściowe skryptu PHP, aby kontrolować buforowanie?

Odpowiedzi:


419

Musisz użyć bardziej złożonej funkcji, np. $.ajax()Jeśli chcesz kontrolować buforowanie na podstawie żądania. Lub, jeśli chcesz to wszystko wyłączyć, umieść to na górze skryptu:

$.ajaxSetup ({
    // Disable caching of AJAX responses
    cache: false
});

2
Dziękuję Ci! Czy to nawet znajduje się w dokumentacji jQuery? Ahh ... znalazłem to. Niby berried. To było kopanie w tyłek przez większość dnia ... Jeszcze raz dziękuję!
bytebender

35
Cała ta pamięć podręczna: false robi, dodając liczbę (uważam, że jest to znacznik czasu) na końcu adresu URL podczas wysyłania żądania. Innym miejscem do obsługi ustawień pamięci podręcznej są ustawienia serwera lub aplikacji internetowej poprzez ustawienie różnych nagłówków odpowiedzi HTTP, takich jak Expires, Pragma itp.
Bryan Rehbein

1
Ta informacja bardzo mi pomogła - pomogła mi zlokalizować naprawdę dokuczliwy błąd
Luke101

Kocham to! Teraz nie muszę używać zbyt szczegółowych połączeń .ajax i mogę korzystać ze skrótów!
Gattster,

1
Genialne - znalazłem tę funkcję, ale nie wiedziałem, że zadziała na czymś tak prostym, jak załadowanie dokumentu tekstowego do div za pomocą .load
Dan

107

Oto przykład, jak kontrolować buforowanie na podstawie żądania

$.ajax({
    url: "/YourController",
    cache: false,
    dataType: "html",
    success: function(data) {
        $("#content").html(data);
    }
});

7
Podoba mi się to w ten sposób o wiele lepiej niż wyłączenie całego buforowania.
Paul Tomblin

Podoba mi się również to, że nie wyłączam całego buforowania. Zobacz także ten post [link] stackoverflow.com/questions/4245231/... do filtrowania.
Dan Doyon

@Marshall kod tutaj nie podałeś, nie wspominając POST lub Get type ...... więc co jest domyślnym dla jquery?
Thomas

domyślną metodą jest GET
Rich T.

35

Jednym ze sposobów jest dodanie unikalnego numeru na końcu adresu URL:

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

Gdzie piszesz unikat (), aby zwracać coś innego za każdym razem, gdy jest wywoływane


1
Jeszcze łatwiejsze, po prostu użyj (+new Date)(lub new Date().getTime()jeśli jesteś trymerem). Zobacz Jak uzyskać znacznik czasu w JavaScript?
trzeci trzeci

Zadaj nowe pytanie i umieść je tutaj. Jeśli zrobiłeś to dobrze, generujesz zupełnie nowe adresy URL, więc przeglądarka nie może ich buforować.
Lou Franco

wykorzystał to do rozwiązania niezwiązanego problemu. działa uczta.
Alex

9

Inne podejście do umieszczenia poniższego wiersza tylko wtedy, gdy wymaga uzyskania danych z serwera, dołącz poniższy wiersz wraz ze swoim adresem URL ajax.

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


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;
}

To prawie załatwiło sprawę. Tyle że funkcja zwrotna ma niepoprawną wartość „to”. Zmieniłem wywołanie func () na następujące, aby to naprawić: func.call(elem, data, textStatus, XMLHttpRequest);
GeekyMonkey

5

Sasha to dobry pomysł, używam miksu.

Tworzę funkcję

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

I wywołuj dla różnych części mojej strony, na przykład na init:

Init: function (actionUrl1, actionUrl2, actionUrl3) {

var Przykład JS = {

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

PrzykładJS.LoadWithoutCache (actionUrl2, „div2”); PrzykładJS.LoadWithoutCache (actionUrl3, „div3”); }},


4

Jest to szczególnie denerwujące w IE. Zasadniczo musisz odesłać nagłówki HTTP „bez pamięci podręcznej” z odpowiedzią z serwera.


3

W przypadku PHP dodaj ten wiersz do skryptu, który udostępnia żądane informacje:

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

lub dodaj unikalną zmienną do ciągu zapytania:

"/portal/?f=searchBilling&x=" + (new Date()).getTime()

Opcja cache: false w funkcji $ .ajax automatycznie dodaje unikalną zmienną do ciągu zapytania, tak jak druga sugestia.
Bryan Rehbein

2

NIE używaj znacznika czasu do utworzenia unikalnego adresu URL, ponieważ każda odwiedzana strona jest buforowana w DOM przez jquery mobile i wkrótce masz problemy z brakiem pamięci na telefonach komórkowych.

$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;
})

Ten kod aktywuje się przed załadowaniem strony, możesz użyć url.indexOf (), aby ustalić, czy adres URL to ten, który chcesz buforować, czy nie, i odpowiednio ustawić parametr pamięci podręcznej.

Nie używaj window.location = ""; aby zmienić adres URL, w przeciwnym razie przejdziesz do adresu, a strona przed załadowaniem się nie uruchomi. Aby obejść ten problem, wystarczy użyć window.location.hash = "";


1
co to jest $ jqm? $ jqm = $? $ .mobile.cache jest niezdefiniowany
Luciuz

2

Jeśli chcesz trzymać się metody .load () Jquery, dodaj do adresu URL coś unikatowego, na przykład znacznik czasu JavaScript. „+ new Date (). getTime ()”. Zauważ, że musiałem dodać „& time =”, aby nie zmieniało to twojej zmiennej pid.

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

1

Można zastąpić funkcję ładowania jquery wersją z ustawioną pamięcią podręczną na 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);

Umieść to gdzieś globalnie, gdzie będzie działać po ładowaniu jquery i powinieneś być gotowy. Twój istniejący kod ładowania nie będzie już buforowany.


0

Spróbuj tego:

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

Działa dobrze, gdy go użyłem.


0

Zauważyłem, że jeśli niektóre serwery (takie jak Apache2) nie są skonfigurowane tak, aby zezwalały lub odmawiały jakiegokolwiek „buforowania”, wówczas serwer może domyślnie wysyłać odpowiedź „buforowaną”, nawet jeśli ustawisz nagłówki HTTP na „brak pamięci podręcznej”. Upewnij się więc, że Twój serwer niczego nie „buforuje”, zanim wyśle ​​odpowiedź:

W przypadku Apache2 musisz

1) edytuj plik „disk_cache.conf” - aby wyłączyć pamięć podręczną dodaj dyrektywę „CacheDisable / local_files”

2) załaduj moduły mod_cache (na Ubuntu „sudo a2enmod cache” i „sudo a2enmod disk_cache”)

3) zrestartuj Apache2 (Ubuntu „sudo service apache2 restart”);

To powinno załatwić sprawę, wyłączając pamięć podręczną po stronie serwerów. Twoje zdrowie! :)


0

Ten kod może ci pomóc

var sr = $("#Search Result");
sr.load("AJAX-Search.aspx?q=" + $("#q")
.val() + "&rnd=" + String((new Date).getTime())
.replace(/\D/gi, ""));
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.