javascript - stop - xhr onabort




Abort Ajax richiede l'uso di jQuery (12)

È possibile interrompere qualsiasi chiamata ajax continua utilizzando questo

<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>

Usando jQuery, come posso annullare / annullare una richiesta Ajax dalla quale non ho ancora ricevuto risposta?


È sempre consigliabile fare qualcosa del genere.

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

Ma è molto meglio se si controlla una dichiarazione if per verificare se la richiesta Ajax è nullo o no.


Abbiamo solo dovuto risolvere questo problema e testato tre diversi approcci.

  1. annulla la richiesta come suggerito da @meouw
  2. esegue tutte le richieste ma elabora solo il risultato dell'ultima sottomissione
  3. impedisce nuove richieste fino a quando un altro è ancora in sospeso

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" />

Nel nostro caso abbiamo deciso di utilizzare l'approccio n. 3 in quanto produce meno carico per il server. Ma non sono sicuro al 100% se jQuery garantisce la chiamata del metodo .complete () -, questo potrebbe produrre una situazione di deadlock. Nei nostri test non siamo riusciti a riprodurre una situazione del genere.


Basta chiamare xhr. abort () se si tratta di oggetti jquery ajax o nativi XMLHTTPRequest.

esempio:

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

Come molte persone sul thread hanno notato, solo perché la richiesta è stata interrotta sul lato client, il server continuerà a elaborare la richiesta. Questo crea un carico non necessario sul server perché sta facendo del lavoro che abbiamo smesso di ascoltare sul front-end.

Il problema che stavo tentando di risolvere (che altri potrebbero eseguire anche in) è che quando l'utente immetteva informazioni in un campo di input, volevo attivare una richiesta per un tipo di sensazione di Google Instant.

Per evitare di lanciare richieste non necessarie e mantenere la reattività del front-end, ho fatto quanto segue:

var xhrQueue = [];
var xhrCount = 0;

$('#search_q').keyup(function(){

    xhrQueue.push(xhrCount);

    setTimeout(function(){

        xhrCount = ++xhrCount;

        if (xhrCount === xhrQueue.length) {
            // Fire Your XHR //
        }

    }, 150);

});

In pratica invierà una richiesta ogni 150 ms (una variabile che è possibile personalizzare in base alle proprie esigenze). Se hai difficoltà a capire cosa sta succedendo esattamente qui, registra xhrCount e xhrQueue nella console subito prima del blocco if.


Ho avuto il problema del polling e una volta chiusa la pagina il sondaggio è continuato, quindi nella mia causa un utente perderebbe un aggiornamento poiché un valore mysql veniva impostato per i successivi 50 secondi dopo la chiusura della pagina, anche se ho ucciso la richiesta Ajax capito, usando $ _SESSION per impostare una var non si aggiornerà nel sondaggio fino al suo termine e ne è iniziato uno nuovo, quindi quello che ho fatto è stato impostare un valore nel mio database come 0 = offpage, mentre io sono polling chiedo quella riga e restituisco false; quando è 0, l'interrogazione nel polling ti porterà ovviamente i valori correnti ...

Spero che questo sia stato d'aiuto


Il seguente codice mostra l'avvio e l'interruzione di una richiesta 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!" >

La maggior parte dei metodi jQuery Ajax restituisce un oggetto XMLHttpRequest (o equivalente), quindi puoi semplicemente usare abort() .

Vedi la documentazione:

  • abort Method ( MSDN ). Annulla la richiesta HTTP corrente.
  • abort() ( MDN ). Se la richiesta è già stata inviata, questo metodo interromperà la richiesta.
var xhr = $.ajax({
    type: "POST",
    url: "some.php",
    data: "name=John&location=Boston",
    success: function(msg){
       alert( "Data Saved: " + msg );
    }
});

//kill the request
xhr.abort()

AGGIORNAMENTO: A partire da jQuery 1.5, l'oggetto restituito è un wrapper per l'oggetto XMLHttpRequest nativo chiamato jqXHR. Questo oggetto sembra esporre tutte le proprietà e i metodi nativi, quindi l'esempio precedente funziona ancora. Vedi L'oggetto jqXHR (documentazione dell'API jQuery).

AGGIORNAMENTO 2: A partire da jQuery 3, il metodo ajax ora restituisce una promessa con metodi aggiuntivi (come abort), quindi il codice sopra riportato funziona ancora, sebbene l'oggetto che viene restituito non sia più un xhr . Vedi il blog 3.0 qui .

AGGIORNAMENTO 3 : xhr.abort() funziona ancora su jQuery 3.x. Non dare per scontato che l' aggiornamento 2 sia corretto. Maggiori informazioni sul repository Greeub di jQuery .


Non è possibile richiamare la richiesta ma è possibile impostare un valore di timeout dopo il quale la risposta verrà ignorata. Vedi questa page per le opzioni jQuery AJAX. Credo che il tuo callback di errore verrà chiamato se il periodo di timeout viene superato. Esiste già un timeout predefinito per ogni richiesta AJAX.

È anche possibile utilizzare il metodo abort() sull'oggetto request ma, mentre causerà l'interruzione dell'ascolto da parte del client per l'evento, è probabile che non interromperà il server dall'elaborarlo.


Salva le chiamate che fai in un array, quindi chiama xhr.abort () su ognuna.

HAVE CAVEAT: puoi annullare una richiesta, ma è solo il lato client. Il lato server potrebbe ancora elaborare la richiesta. Se stai usando qualcosa come PHP o ASP con i dati di sessione, i dati della sessione sono bloccati fino a quando l'ajax non è terminato. Pertanto, per consentire all'utente di continuare a navigare nel sito Web, è necessario chiamare session_write_close (). Ciò salva la sessione e la sblocca in modo che le altre pagine in attesa di continuare procedano. Senza questo, diverse pagine possono essere in attesa di rimozione del blocco.


Stavo facendo una soluzione di ricerca in tempo reale e avevo bisogno di cancellare le richieste in sospeso che potrebbero aver richiesto più tempo della richiesta più recente / più recente.

Nel mio caso ho usato qualcosa del genere:

//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 

non esiste un modo affidabile per farlo, e non lo proverei nemmeno, una volta che la richiesta è in movimento; l' unico modo per reagire ragionevolmente è ignorare la risposta.

nella maggior parte dei casi, può accadere in situazioni come: un utente fa clic troppo spesso su un pulsante che attiva molti XHR consecutivi, qui hai molte opzioni, o blocca il pulsante finché non viene restituito XHR, o non innesca nemmeno il nuovo XHR mentre un altro sta facendo accenno l'utente a rilassarsi - o scartare qualsiasi risposta XHR in sospeso ma quella recente.





ajax