2008-10-03 6 views
228

Mam następujący kod dokonywania żądanie GET na URL:Zatrzymaj jQuery .load odpowiedzi przed buforowane

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

Ale zwrócony wynik nie zawsze jest odbicie. Na przykład wprowadziłem zmianę w odpowiedzi, 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 wynik zwracany przez .load był stary.

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

Odpowiedz

399

Musisz użyć bardziej złożonej funkcji, takiej jak $.ajax(), jeśli chcesz kontrolować buforowanie na żądanie. Albo, jeśli chcesz po prostu wyłączyć go za wszystko, umieścić to na górze skryptu:

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

dziękuję! Czy to jest nawet zawarte w dokumentacji jQuery? Ahh ... znalazłem to. Trochę nałogowo.To było kopanie przez tyłek przez większość dnia ... Jeszcze raz dziękuję! – bytebender

+34

Cała ta pamięć podręczna: wartość false powoduje dodanie numeru (uważam, że jest to sygnatura czasowa) na końcu adresu URL podczas wysyłania żądania. Innym miejscem, w którym można zarządzać ustawieniami pamięci podręcznej, jest serwer lub aplikacja internetowa, ustawiając różne nagłówki odpowiedzi HTTP, takie jak Expires, Pragma itp. –

+1

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

33

Jednym ze sposobów jest dodanie unikalnego numeru do końca URL:

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

Jeżeli piszesz uniqueId(), aby za każdym razem to się nazywa powrót coś innego.

+3

funkcja uniqueId() {return new Date.getTime(); }; – Adam

+1

Jeszcze łatwiej, po prostu użyj '(+ new Date)' (lub 'new Date(). GetTime()' jeśli jesteś pedantą). Zobacz [Jak uzyskać znacznik czasu w JavaScript?] (Http://stackoverflow.com/questions/221294/how-do-you-get-a-timestamp-in-javascript) – thirdender

+0

To rozwiązanie nie działa dla mnie . – spadelives

4

Jest to szczególnie irytujące w IE. Zasadniczo musisz wysyłać nagłówki HTTP bez bufora z odpowiedzią z serwera.

2

dla PHP, dodać tę linię do skryptu, który służy żądane informacje:

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

lub dodaj unikalną zmienną łańcucha zapytania:

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

Opcja cache: false w funkcji $ .ajax automatycznie dodaje zmienną unikatową do ciągu zapytania, tak jak twoja druga sugestia. –

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żywam.

101

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

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

Podoba mi się ta droga o wiele lepiej niż po prostu wyłączenie buforowania. –

+0

Podoba mi się także to, że nie wyłączam buforowania. Zobacz również ten post [link] http://stackoverflow.com/questions/4245231/how-do-i-filter-turn-detail-data-from-jquery-ajax do filtrowania. –

+0

@Marshall kod tutaj dał nie wspominając POST lub Get type ...... więc co jest domyślne dla jquery? – Thomas

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

To prawie załatwiło sprawę. Poza tym funkcja zwrotna ma niepoprawną "tę" wartość. Zmieniłem wywołanie func() na następujące: 'func.call (elem, data, textStatus, XMLHttpRequest);' – GeekyMonkey

4

Sasha jest dobrym pomysłem, używam mieszanki.

utworzyć funkcję

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

i wywołać dla diferents części mojej strony na przykład w pliku init:

Init: function (actionUrl1, actionUrl2, actionUrl3) {

var ExampleJS = {

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

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

0

Zauważyłem, że jeśli niektóre serwery (jak Apache2) nie są skonfigurowane tak, aby specyficznie lub odmówić żadnej „buforowanie”, a następnie serwer może domyślnie wysłać „pamięci podręcznej” odpowiedzi, nawet jeśli ustawić Nagłówki HTTP na "brak pamięci podręcznej". Więc upewnij się, że serwer nie jest „buforowanie” niczego zanim on- ków odpowiedź:

W przypadku Apache2 trzeba

1) edycji „disk_cache.conf” plik - aby wyłączyć cache dodać " CacheDisable/local_files”dyrektywą

2) moduły mod_cache obciążenie (na Ubuntu "sudo a2enmod cache" i "sudo a2enmod disk_cache")

3) ponownie uruchomić Apache2 (Ubuntu "sudo service apache2 restart");

To powinno zrobić sztuczkę wyłączającą pamięć podręczną po stronie serwerów. Pozdrawiam! :)

2

NIE używaj znacznika czasu do tworzenia unikatowego adresu URL, ponieważ każda odwiedzana strona jest buforowana w DOM przez jquery mobile i wkrótce napotkasz problemy z wyczerpaniem pamięci w 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 zanim strona zostanie załadowana, można użyć url.indexOf() w celu określenia, czy adres URL jest jeden chcesz buforować lub nie i ustawić parametr cache odpowiednio.

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

+0

wygląda dobrze, ale nie są wysyłane żadne żądania ajaxowe – Luciuz

+1

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

7

Kolejne podejście do umieszczenia poniższej linii tylko wtedy, gdy jest wymagane uzyskanie danych z serwera, Dołącz poniższą linię wraz z adresem URL ajax. Metoda

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

0

Kod ten może pomóc

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

Jeśli chcesz trzymać się z .load jQuery() , dodaj coś unikatowego do adresu URL, np. znacznik czasu JavaScript. "+ nowa data(). getTime()". Zauważ, że musiałem dodać "& time =", więc nie zmienia 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ą, która ma ustawioną wartość bufora 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ś globalne, gdzie będzie działać po ładowaniu jquery i powinieneś wszystko ustawić. Twój istniejący kod obciążenia nie będzie już buforowany.