it-swarm.com.de

Ajax-Anfragen mit jQuery abbrechen

Wie kann ich mit jQuery Abbrechen/Abbrechen einer Ajax-Anfrage die Antwort von noch nicht erhalten haben?

1760
lukewm

Die meisten jQuery Ajax-Methoden geben ein XMLHttpRequest-Objekt (oder das entsprechende Objekt) zurück, sodass Sie nur abort() verwenden können.

Siehe die Dokumentation:

  • Abbruchmethode ( MSDN ). Bricht die aktuelle HTTP-Anfrage ab.
  • abort () ( MDN ). Wenn die Anfrage bereits gesendet wurde, bricht diese Methode die Anfrage ab.
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()

UPDATE: Ab jQuery 1.5 ist das zurückgegebene Objekt ein Wrapper für das native XMLHttpRequest-Objekt mit dem Namen jqXHR. Dieses Objekt macht anscheinend alle nativen Eigenschaften und Methoden verfügbar, sodass das obige Beispiel weiterhin funktioniert. Siehe Das jqXHR-Objekt (jQuery-API-Dokumentation).

UPDATE 2: Ab jQuery 3 gibt die ajax-Methode jetzt ein Versprechen mit zusätzlichen Methoden zurück (z. B. abort), sodass der obige Code immer noch funktioniert Das zurückgegebene Objekt ist kein xhr mehr. Siehe das .0 Blog hier .

UPDATE 3 : xhr.abort() funktioniert immer noch mit jQuery 3.x. Nehmen Sie nicht an, dass das Update 2 korrekt ist. Weitere Informationen zum jQuery Github-Repository .

1688
meouw

Sie können die Anforderung nicht zurückrufen, aber Sie können einen Zeitlimitwert festlegen, nach dem die Antwort ignoriert wird. Siehe diese Seite für jquery AJAX Optionen. Ich glaube, dass Ihr Fehlerrückruf aufgerufen wird, wenn die Timeout-Zeit überschritten wird. Es gibt bereits ein Standardzeitlimit für jede AJAX Anforderung.

Sie können auch die abort () -Methode für das Anforderungsobjekt verwenden. Dies führt jedoch dazu, dass der Client nicht mehr auf das Ereignis wartet kann Vermutlich wird der Server nicht an der Verarbeitung gehindert.

111
tvanfosson

Es ist eine asynchrone Anfrage, dh sobald sie gesendet wurde, ist sie da draußen.

Falls Ihr Server aufgrund der Anforderung AJAX einen sehr kostspieligen Vorgang startet, können Sie Ihren Server am besten öffnen, um auf Abbruchanforderungen zu warten, und eine separate Benachrichtigung über AJAX senden der Server zu stoppen, was auch immer es tut.

Andernfalls ignorieren Sie einfach die Antwort AJAX.

72
Yuval Adam

Speichern Sie die von Ihnen getätigten Aufrufe in einem Array und rufen Sie dann jeweils xhr.abort () auf.

HUGE CAVEAT: Sie können eine Anfrage abbrechen, aber das ist nur die Client-Seite. Die Serverseite kann die Anforderung noch verarbeiten. Wenn Sie mit Sitzungsdaten etwas wie PHP oder ASP verwenden, werden die Sitzungsdaten gesperrt, bis der Ajax abgeschlossen ist. Damit der Benutzer weiterhin auf der Website surfen kann, müssen Sie session_write_close () aufrufen. Dadurch wird die Sitzung gespeichert und entsperrt, sodass andere Seiten, die auf die Fortsetzung warten, fortgesetzt werden. Andernfalls können mehrere Seiten darauf warten, dass die Sperre aufgehoben wird.

66
Tei

AJAX-Anforderungen werden möglicherweise nicht in der Reihenfolge ausgeführt, in der sie gestartet wurden. Anstatt den Vorgang abzubrechen, können Sie festlegen, dass ignorieren alle AJAX Antworten mit Ausnahme der letzten:

  • Erstellen Sie einen Zähler
  • Erhöhen Sie den Zähler, wenn Sie eine AJAX -Anforderung einleiten
  • Verwenden Sie den aktuellen Wert des Zählers, um die Anforderung zu "stempeln"
  • Vergleichen Sie im Erfolgsrückruf den Stempel mit dem Zähler, um zu prüfen, ob es sich um die letzte Anforderung handelt

Grobe Gliederung des Codes:

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

55
Salman A

Wir mussten dieses Problem einfach umgehen und drei verschiedene Ansätze testen.

  1. bricht die Anfrage ab, wie von @meouw vorgeschlagen
  2. alle Anfragen ausführen, aber nur das Ergebnis der letzten Übermittlung verarbeiten
  3. verhindert neue Anfragen, solange noch eine ansteht
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" />

In unserem Fall haben wir uns für Ansatz 3 entschieden, da dieser weniger Last für den Server erzeugt. Ich bin mir aber nicht hundertprozentig sicher, ob jQuery den Aufruf der .complete () - Methode garantiert, da dies zu einem Deadlock führen kann. In unseren Tests konnten wir eine solche Situation nicht reproduzieren.

40
oyophant

Es ist immer empfehlenswert, so etwas zu tun.

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

Es ist jedoch viel besser, wenn Sie eine if-Anweisung überprüfen, um zu überprüfen, ob die Ajax-Anforderung null ist oder nicht.

35
Tharindu Kumara

meouws Lösung ist richtig, aber wenn Sie an mehr Kontrolle interessiert sind, können Sie das Ajax Manager-Plugin für jQuery ausprobieren.

20
Prestaul

Rufen Sie einfach xhr .abort () auf, ob es sich um ein jquery-Ajax-Objekt oder ein natives XMLHTTPRequest-Objekt handelt.

beispiel:

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

Ich habe eine Live-Suche durchgeführt und musste ausstehende Anfragen stornieren, die möglicherweise länger als die letzte/aktuellste Anfrage gedauert haben.

In meinem Fall habe ich so etwas verwendet:

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

Wie viele Personen im Thread bemerkt haben, wird der Server die Anforderung weiterhin verarbeiten, nur weil die Anforderung auf der Clientseite abgebrochen wird. Dadurch wird der Server unnötig belastet, da er Arbeit leistet, die wir im Front-End nicht mehr hören.

Das Problem, das ich zu lösen versucht habe (auf das auch andere möglicherweise stoßen), ist, dass ich, als der Benutzer Informationen in ein Eingabefeld eingab, eine Anfrage nach einem Google Instant-Feel abfeuern wollte.

Um unnötige Anfragen zu vermeiden und die Aktualität des Frontends zu erhalten, habe ich Folgendes getan:

var xhrQueue = [];
var xhrCount = 0;

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

    xhrQueue.Push(xhrCount);

    setTimeout(function(){

        xhrCount = ++xhrCount;

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

    }, 150);

});

Dies sendet im Wesentlichen alle 150 ms eine Anforderung (eine Variable, die Sie für Ihre eigenen Anforderungen anpassen können). Wenn Sie Probleme haben zu verstehen, was genau hier passiert, melden Sie xhrCount und xhrQueue an der Konsole kurz vor dem if-Block an.

12
brianrhea

Verwenden Sie einfach ajax.abort (), um beispielsweise eine ausstehende Ajax-Anfrage abzubrechen, bevor Sie eine andere wie diese senden

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

es gibt keinen verlässlichen Weg, und ich würde es nicht einmal versuchen, wenn die Anfrage einmal unterwegs ist. die nur Möglichkeit, vernünftig zu reagieren, ist ignorieren die Antwort.

in den meisten Fällen kann es vorkommen, dass ein Benutzer zu oft auf eine Schaltfläche klickt, um mehrere aufeinanderfolgende XHR-Vorgänge auszulösen. Hier haben Sie viele Möglichkeiten: Blockieren Sie die Schaltfläche, bis XHR zurückgegeben wird, oder lösen Sie nicht einmal neue XHR-Vorgänge aus, während ein anderer XHR-Vorgang ausgeführt wird Der Benutzer kann sich zurücklehnen oder alle ausstehenden XHR-Antworten außer den letzten verwerfen.

10
comeGetSome

Sie können damit jeden fortlaufenden Ajax-Anruf abbrechen

<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>
8
Soubhagya Kumar

Der folgende Code zeigt das Einleiten und Abbrechen einer Ajax-Anfrage:

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!" >
7
zloctb

Ich hatte das Problem der Abfrage und nachdem die Seite geschlossen wurde, wurde die Abfrage fortgesetzt, sodass ein Benutzer eine Aktualisierung verpassen würde, da für die nächsten 50 Sekunden nach dem Schließen der Seite ein MySQL-Wert festgelegt wurde, obwohl ich die Ajax-Anforderung beendet habe Ich habe herausgefunden, dass die Verwendung von $ _SESSION zum Festlegen einer Variablen in der Umfrage erst dann automatisch aktualisiert wird, wenn sie beendet ist und eine neue gestartet wurde. Daher habe ich in meiner Datenbank den Wert 0 = offpage festgelegt, während ich aktiv bin Polling Ich frage diese Zeile ab und gebe false zurück. Wenn der Wert 0 ist, erhalten Sie beim Abfragen offensichtlich die aktuellen Werte ...

Ich hoffe das hat geholfen

5
Marcus

Ich habe ein Demo geteilt, das zeigt, wie eine AJAX -Anforderung abgebrochen wird - wenn innerhalb einer vordefinierten Wartezeit keine Daten vom Server zurückgegeben werden.

HTML:

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

JS-CODE:

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

Wenn xhr.abort(); das Neuladen der Seite verursacht,

Dann können Sie onreadystatechange vor dem Abbruch einstellen, um Folgendes zu verhindern:

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