Impedir que a resposta do jQuery .load seja armazenada em cache

244

Eu tenho o seguinte código fazendo uma solicitação GET em uma URL:

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

Mas o resultado retornado nem sempre é refletido. Por exemplo, eu fiz uma alteração na resposta que cuspiu um rastreamento de pilha, mas o rastreamento de pilha não apareceu quando eu cliquei no botão de pesquisa. Eu olhei para o código PHP subjacente que controla a resposta ajax e ele tinha o código correto e, visitando a página diretamente, mostrou o resultado correto, mas a saída retornada por .load era antiga.

Se eu fechar o navegador e reabri-lo, ele funcionará uma vez e começará a retornar as informações obsoletas. Posso controlar isso pelo jQuery ou preciso ter meus cabeçalhos de saída de script PHP para controlar o cache?

dragonmantank
fonte

Respostas:

419

É necessário usar uma função mais complexa, como $.ajax()se você deseja controlar o armazenamento em cache por solicitação. Ou, se você quiser desativá-lo para tudo, coloque isso na parte superior do seu script:

$.ajaxSetup ({
    // Disable caching of AJAX responses
    cache: false
});
John Millikin
fonte
2
obrigado! Isso está localizado na documentação do jQuery? Ahh ... encontrei. Tipo de berried. Isso foi chutado pela maior parte do dia ... Mais uma vez obrigado!
Bytebender
35
Todo esse cache: false do é anexar um número (acredito que seja um carimbo de data / hora) ao final de um URL ao fazer a solicitação. O outro lugar para lidar com as configurações de cache são do aplicativo do servidor ou web, definindo vários cabeçalhos de resposta HTTP, como expirar, Pragma, etc ...
Bryan Rehbein
1
Este pedaço de informação me hepled muito - ele me ajudou a localizar um bug realmente irritante
Luke101
Adoro! Agora não preciso usar chamadas .ajax excessivamente detalhadas e posso usar os atalhos!
Gattster
1
Brilliant - Eu encontrei esta função, mas não sabia que ele iria trabalhar em algo tão simples como colocar um documento de texto em uma div usando .load
Dan
107

Aqui está um exemplo de como controlar o armazenamento em cache por solicitação

$.ajax({
    url: "/YourController",
    cache: false,
    dataType: "html",
    success: function(data) {
        $("#content").html(data);
    }
});
Marshall
fonte
7
Eu gosto dessa maneira muito melhor do que simplesmente desligar todo o cache.
Paul Tomblin
Também gosto disso por não desativar todo o cache. Além disso, veja esta postagem também [link] stackoverflow.com/questions/4245231/… para filtragem.
Dan Doyon 14/03
@Marshall o código aqui vc não mencionou POST ou Get type ...... então qual é o padrão para jquery?
Thomas Thomas
método padrão é GET
rico T.
35

Uma maneira é adicionar um número exclusivo ao final do URL:

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

Onde você escreve uniqueId () para retornar algo diferente cada vez que é chamado.

Lou Franco
fonte
1
Ainda mais fácil, basta usar (+new Date)(ou new Date().getTime()se você é um defensor). Consulte Como você obtém um registro de data e hora em JavaScript?
thirdender
Faça uma nova pergunta e vincule-a aqui. Se você fez certo, está gerando URLs completamente novos, para que não possam ser armazenados em cache pelo navegador.
Lou Franco
usou isso para resolver um problema não relacionado. funciona um deleite.
1428 Alex
9

Outra abordagem para colocar a linha abaixo somente quando for necessário obter dados do servidor, anexe a linha abaixo junto com seu URL do ajax.

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

Gomes
fonte
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
fonte
Isso quase fez o truque para mim. Exceto que a função de retorno de chamada possui o valor "this" incorreto. func.call(elem, data, textStatus, XMLHttpRequest);
Alterei
5

Sasha é uma boa ideia, eu uso uma mistura.

Eu crio uma função

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

E invoque para diferentes partes da minha página, por exemplo, no 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"); }}

NGRAUPEN
fonte
4

Isso é particularmente irritante no IE. Basicamente, você deve enviar os cabeçalhos HTTP 'sem cache' de volta com sua resposta do servidor.

Xian
fonte
3

Para PHP, adicione esta linha ao seu script, que serve as informações que você deseja:

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

ou adicione uma variável exclusiva à string de consulta:

"/portal/?f=searchBilling&x=" + (new Date()).getTime()
nickf
fonte
A opção cache: false na função $ .ajax adiciona automaticamente a variável exclusiva à string de consulta, como sua segunda sugestão.
Bryan Rehbein
2

NÃO use o carimbo de data / hora para criar um URL exclusivo, pois todas as páginas visitadas são armazenadas em cache no DOM pelo jquery mobile e, em breve, você terá problemas para ficar sem memória nos celulares.

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

Esse código é ativado antes do carregamento da página. Você pode usar url.indexOf () para determinar se a URL é a que você deseja armazenar em cache ou não e definir o parâmetro de cache de acordo.

Não use window.location = ""; para alterar o URL, caso contrário, você navegará até o endereço e o pagebeforeload não será acionado. Para contornar esse problema, basta usar window.location.hash = "";

user1545320
fonte
1
qual é o $ jqm? $ jqm = $? $ .mobile.cache é indefinido
Luciuz
2

Se você deseja manter o método .load () do Jquery, adicione algo exclusivo à URL, como um carimbo de data / hora do JavaScript. "+ nova Data (). getTime ()". Observe que eu precisei adicionar um "& time =" para que não altere sua variável pid.

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

Você pode substituir a função de carregamento do jquery por uma versão que tenha o cache definido como 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);

Coloque isso em algum lugar global onde será executado após o carregamento do jquery e você deverá estar pronto. Seu código de carregamento existente não será mais armazenado em cache.

Adam Bell
fonte
0

Tente o seguinte:

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

Funciona bem quando eu o usei.


fonte
0

Percebi que se alguns servidores (como o Apache2) não estiverem configurados para permitir ou negar especificamente "armazenamento em cache", o servidor poderá, por padrão, enviar uma resposta "em cache", mesmo se você definir os cabeçalhos HTTP como "sem cache". Portanto, verifique se o servidor não está "armazenando em cache" nada antes de enviar uma resposta:

No caso do Apache2, você precisa

1) edite o arquivo "disk_cache.conf" - para desativar o cache, adicione a diretiva "CacheDisable / local_files"

2) carregar módulos mod_cache (no Ubuntu "sudo a2enmod cache" e "sudo a2enmod disk_cache")

3) reinicie o Apache2 (Ubuntu "serviço sudo apache2 restart");

Isso deve fazer o truque para desativar o cache no lado dos servidores. Felicidades! :)

techexpert
fonte
0

Este código pode ajudá-lo

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