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?

Dragonmantank
źródło

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
});
John Millikin
źródło
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);
    }
});
Marshall
źródło
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

Lou Franco
źródło
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)

Gomes
źródło
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
źródło
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”); }},

NGRAUPEN
źródło
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.

Xian
źródło
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()
pseudonim
źródło
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 = "";

użytkownik1545320
źródło
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());            
});
NickStees
źródło
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.

Adam Bell
źródło
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.


źródło
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! :)

techexpert
źródło
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, ""));
Ahmad Dwaik „Warlock”
źródło