Evite que la respuesta de jQuery .load se almacene en caché

244

Tengo el siguiente código haciendo una solicitud GET en una URL:

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

Pero el resultado devuelto no siempre se refleja. Por ejemplo, hice un cambio en la respuesta que escupió un seguimiento de la pila, pero el seguimiento de la pila no apareció cuando hice clic en el botón de búsqueda. Miré el código PHP subyacente que controla la respuesta ajax y tenía el código correcto y al visitar la página directamente se mostró el resultado correcto, pero el resultado devuelto por .load era antiguo.

Si cierro el navegador y lo vuelvo a abrir, funciona una vez y luego comienza a devolver la información obsoleta. ¿Puedo controlar esto mediante jQuery o necesito tener mis encabezados de salida de script PHP para controlar el almacenamiento en caché?

dragonmantank
fuente

Respuestas:

419

Debe utilizar una función más compleja, como $.ajax()si desea controlar el almacenamiento en caché por solicitud. O, si solo quieres desactivarlo para todo, coloca esto en la parte superior de tu script:

$.ajaxSetup ({
    // Disable caching of AJAX responses
    cache: false
});
John Millikin
fuente
2
¡gracias! ¿Esto incluso se encuentra en la documentación de jQuery? Ahh ... lo encontré. Tipo de baya. Esto había estado pateando traseros la mayor parte del día ... ¡Gracias de nuevo!
bytebender
35
Todo este caché: falso hace es agregar un número (creo que es una marca de tiempo) al final de una url al hacer la solicitud. El otro lugar para manejar la configuración de la caché es desde el servidor o la aplicación web configurando varios encabezados de respuesta HTTP, como Expires, Pragma, etc ...
Bryan Rehbein
1
Esta información me ayudó mucho: me ayudó a localizar un error realmente molesto
Luke101
¡Quiéralo! ¡Ahora no tengo que usar llamadas .ajax demasiado detalladas y puedo usar los atajos!
Gattster
1
Brillante: encontré esta función pero no sabía que funcionaría en algo tan simple como cargar un documento de texto en un div usando .load
Dan
107

Aquí hay un ejemplo de cómo controlar el almacenamiento en caché por solicitud

$.ajax({
    url: "/YourController",
    cache: false,
    dataType: "html",
    success: function(data) {
        $("#content").html(data);
    }
});
Marshall
fuente
77
Me gusta mucho más que simplemente desactivar todo el almacenamiento en caché.
Paul Tomblin
También me gusta esto por no desactivar todo el almacenamiento en caché. Además, mire esta publicación también [link] stackoverflow.com/questions/4245231/… para filtrar.
Dan Doyon
@Marshall el código aquí que no mencionaste POST o Get type ...... ¿cuál es el valor predeterminado para jquery?
Thomas
el método predeterminado es GET
Rich T.
35

Una forma es agregar un número único al final de la url:

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

Donde escribe uniqueId () para devolver algo diferente cada vez que se llama.

Lou Franco
fuente
1
Aún más fácil, solo use (+new Date)(o new Date().getTime()si es un fanático). Vea ¿Cómo se obtiene una marca de tiempo en JavaScript?
Thirdender
Haga una nueva pregunta y vincúlela aquí. Si lo hizo bien, está generando URL completamente nuevas, por lo que el navegador no puede almacenarlas en caché.
Lou Franco
Usé esto para resolver un problema no relacionado. funciona de maravilla.
Alex
9

Otro enfoque para colocar la línea a continuación solo cuando sea necesario obtener datos del servidor, anexe la línea a continuación junto con su url ajax.

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

Gomes
fuente
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
fuente
Esto casi hizo el truco para mí. Excepto que la función de devolución de llamada tiene el valor "this" incorrecto. Cambié la llamada de func () a lo siguiente para solucionar esto: func.call(elem, data, textStatus, XMLHttpRequest);
GeekyMonkey
5

Sasha es buena idea, yo uso una mezcla.

Creo una función

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

E invocar para diferentes partes de mi página, por ejemplo, en init:

Init: function (actionUrl1, actionUrl2, actionUrl3) {

var ExampleJS = {

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

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

NGRAUPEN
fuente
4

Esto es de particular molestia en IE. Básicamente, debe devolver los encabezados HTTP 'sin caché' con su respuesta del servidor.

Xian
fuente
3

Para PHP, agregue esta línea a su script que sirve la información que desea:

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

o bien, agregue una variable única a la cadena de consulta:

"/portal/?f=searchBilling&x=" + (new Date()).getTime()
nickf
fuente
La opción cache: false en la función $ .ajax agrega automáticamente la variable única a la cadena de consulta como su segunda sugerencia.
Bryan Rehbein
2

NO use la marca de tiempo para crear una URL única, ya que cada página que visita se almacena en caché en DOM por jquery mobile y pronto tendrá problemas para quedarse sin memoria en los móviles.

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

Este código se activa antes de cargar la página, puede usar url.indexOf () para determinar si la URL es la que desea almacenar en caché o no y establecer el parámetro de caché en consecuencia.

No use window.location = ""; para cambiar la URL, de lo contrario, navegará a la dirección y la página antes de la carga no se activará. Para solucionar este problema, simplemente use window.location.hash = "";

usuario1545320
fuente
1
¿Cuál es el $ jqm? $ jqm = $? $ .mobile.cache no está definido
Luciuz
2

Si desea seguir con el método .load () de Jquery, agregue algo único a la URL como una marca de tiempo de JavaScript. "+ nueva Fecha (). getTime ()". Tenga en cuenta que tuve que agregar un "& time =" para que no altere su variable pid.

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

Puede reemplazar la función de carga jquery con una versión que tenga caché establecida en falso.

(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);

Coloque esto en un lugar global donde se ejecutará después de que jquery se cargue y debería estar listo. Su código de carga existente ya no se almacenará en caché.

Adam Bell
fuente
0

Prueba esto:

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

Funciona bien cuando lo usé.


fuente
0

Noté que si algunos servidores (como Apache2) no están configurados para permitir o denegar específicamente cualquier "almacenamiento en caché", entonces el servidor puede enviar de forma predeterminada una respuesta "en caché", incluso si configura los encabezados HTTP en "sin caché". Así que asegúrese de que su servidor no esté "almacenando en caché" nada antes de enviar una respuesta:

En el caso de Apache2 tienes que

1) edite el archivo "disk_cache.conf" - para deshabilitar el caché agregue la directiva "CacheDisable / local_files"

2) cargar módulos mod_cache (en Ubuntu "sudo a2enmod cache" y "sudo a2enmod disk_cache")

3) reinicie Apache2 (Ubuntu "sudo service apache2 restart");

Esto debería hacer el truco de deshabilitar el caché en el lado de los servidores. ¡Salud! :)

techexpert
fuente
0

Este código puede ayudarte

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