javascript - w3schools - request using ajax




Abortar pedidos do Ajax usando jQuery (12)

Usando jQuery, como posso cancelar / anular uma requisição Ajax da qual ainda não recebi a resposta?


É sempre uma boa prática fazer algo assim.

var $request;
if ($request != null){ 
    $request.abort();
    $request = null;
}

$request = $.ajax({
    type : "POST", //TODO: Must be changed to POST
    url : "yourfile.php",
    data : "data"
    }).done(function(msg) {
        alert(msg);
    });

Mas é muito melhor se você verificar uma declaração if para verificar se a requisição ajax é nula ou não.


É uma solicitação assíncrona , ou seja, uma vez enviada, está lá fora.

Caso seu servidor esteja iniciando uma operação muito cara devido à solicitação AJAX, o melhor que você pode fazer é abrir o servidor para escutar as solicitações de cancelamento e enviar uma solicitação AJAX separada, notificando o servidor para interromper o que estiver fazendo.

Caso contrário, simplesmente ignore a resposta do AJAX.


Apenas chame xhr. abort () se é objeto jquery ajax ou objeto XMLHTTPRequest nativo.

exemplo:

//jQuery ajax
$(document).ready(function(){
    var xhr = $.get('/server');
    setTimeout(function(){xhr.abort();}, 2000);
});

//native XMLHTTPRequest
var xhr = new XMLHttpRequest();
xhr.open('GET','/server',true);
xhr.send();
setTimeout(function(){xhr.abort();}, 2000);

Basta usar ajax.abort () por exemplo, você poderia abortar qualquer pedido de ajax pendente antes de enviar outro como este

//check for existing ajax request
if(ajax){ 
 ajax.abort();
 }
//then you make another ajax request
$.ajax(
 //your code here
  );

Eu compartilhei uma demo que demonstra como cancelar uma solicitação AJAX - se os dados não forem retornados do servidor dentro de um tempo de espera predefinido.

HTML:

<div id="info"></div>

CÓDIGO JS:

var isDataReceived= false, waitTime= 1000; 
$(function() {
    // Ajax request sent.
     var xhr= $.ajax({
      url: 'http://api.joind.in/v2.1/talks/10889',
      data: {
         format: 'json'
      },     
      dataType: 'jsonp',
      success: function(data) {      
        isDataReceived= true;
        $('#info').text(data.talks[0].talk_title);        
      },
      type: 'GET'
   });
   // Cancel ajax request if data is not loaded within 1sec.
   setTimeout(function(){
     if(!isDataReceived)
     xhr.abort();     
   },waitTime);   
});

Eu estava fazendo uma solução de pesquisa ao vivo e precisava cancelar solicitações pendentes que poderiam demorar mais do que a solicitação mais recente / mais atual.

No meu caso eu usei algo assim:

//On document ready
var ajax_inprocess = false;

$(document).ajaxStart(function() {
ajax_inprocess = true;
});

$(document).ajaxStop(function() {
ajax_inprocess = false;
});

//Snippet from live search function
if (ajax_inprocess == true)
{
    request.abort();
}
//Call for new request 

Nós apenas tivemos que contornar este problema e testamos três abordagens diferentes.

  1. cancela o pedido como sugerido por @meouw
  2. executar todos os pedidos, mas processa apenas o resultado do último envio
  3. impede novos pedidos enquanto outro ainda estiver pendente

var Ajax1 = {
  call: function() {
    if (typeof this.xhr !== 'undefined')
      this.xhr.abort();
    this.xhr = $.ajax({
      url: 'your/long/running/request/path',
      type: 'GET',
      success: function(data) {
        //process response
      }
    });
  }
};
var Ajax2 = {
  counter: 0,
  call: function() {
    var self = this,
      seq = ++this.counter;
    $.ajax({
      url: 'your/long/running/request/path',
      type: 'GET',
      success: function(data) {
        if (seq === self.counter) {
          //process response
        }
      }
    });
  }
};
var Ajax3 = {
  active: false,
  call: function() {
    if (this.active === false) {
      this.active = true;
      var self = this;
      $.ajax({
        url: 'your/long/running/request/path',
        type: 'GET',
        success: function(data) {
          //process response
        },
        complete: function() {
          self.active = false;
        }
      });
    }
  }
};
$(function() {
  $('#button').click(function(e) {
    Ajax3.call();
  });
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="button" type="button" value="click" />

No nosso caso, decidimos usar a abordagem # 3, pois ela produz menos carga para o servidor. Mas não tenho 100% de certeza se o jQuery garante a chamada do método .complete (), isso pode gerar uma situação de deadlock. Em nossos testes, não conseguimos reproduzir tal situação.


O código a seguir mostra iniciando e abortando uma requisição Ajax:

function libAjax(){
  var req;
  function start(){

  req =    $.ajax({
              url: '1.php',
              success: function(data){
                console.log(data)
              }
            });

  }

  function stop(){
    req.abort();
  }

  return {start:start,stop:stop}
}

var obj = libAjax();

 $(".go").click(function(){


  obj.start();


 })



 $(".stop").click(function(){

  obj.stop();


 })
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" class="go" value="GO!" >
   <input type="button" class="stop" value="STOP!" >

Se xhr.abort(); faz com que a página seja recarregada

Então você pode definir onreadystatechange antes de abortar para prevenir:

// ↓ prevent page reload by abort()
xhr.onreadystatechange = null;
// ↓ may cause page reload
xhr.abort();

Solicitações AJAX podem não ser concluídas na ordem em que foram iniciadas. Em vez de abortar, você pode optar por ignorar todas as respostas AJAX, exceto a mais recente:

  • Crie um contador
  • Incrementar o contador quando você iniciar o pedido AJAX
  • Use o valor atual do contador para "carimbar" a solicitação
  • No callback de sucesso, compare o carimbo com o contador para verificar se foi o pedido mais recente

Esboço áspero do código:

var xhrCount = 0;
function sendXHR() {
    // sequence number for the current invocation of function
    var seqNumber = ++xhrCount;
    $.post("/echo/json/", { delay: Math.floor(Math.random() * 5) }, function() {
        // this works because of the way closures work
        if (seqNumber === xhrCount) {
            console.log("Process the response");
        } else {
            console.log("Ignore the response");
        }
    });
}
sendXHR();
sendXHR();
sendXHR();
// AJAX requests complete in any order but only the last 
// one will trigger "Process the response" message

Demo no jsFiddle


Você pode cancelar qualquer chamada contínua de ajax usando este

<input id="searchbox" name="searchbox" type="text" />

<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>

<script type="text/javascript">
     var request = null;
        $('#searchbox').keyup(function () {
            var id = $(this).val();
            request = $.ajax({
                type: "POST", //TODO: Must be changed to POST
                url: "index.php",
                data: {'id':id},
                success: function () {

                },
                beforeSend: function () {
                    if (request !== null) {
                        request.abort();
                    }
                }
            });
        });

</script>

não há maneira confiável de fazê-lo, e eu nem tentaria, uma vez que o pedido está em andamento; a única maneira de reagir razoavelmente é ignorar a resposta.

na maioria dos casos, pode acontecer em situações como: um usuário clica com muita frequência em um botão que aciona vários XHRs consecutivos, aqui você tem muitas opções, ou bloqueia o botão até que XHR seja retornado ou não ative o novo XHR enquanto outro está rodando insinuando o usuário se inclinar para trás - ou descartar qualquer resposta XHR pendente, mas a recente.





ajax