是否可以使用jQuery取消/中止尚未收到响应的Ajax请求?


当前回答

做这样的事总是最好的做法。

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

但如果您检查if语句来检查ajax请求是否为空,则效果会更好。

其他回答

AJAX请求可能无法按启动顺序完成。您可以选择忽略除最新的AJAX响应之外的所有AJAX响应,而不是放弃:

创建计数器启动AJAX请求时增加计数器使用计数器的当前值“标记”请求在成功回调中,将标记与计数器进行比较,以检查它是否是最近的请求

代码大纲:

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

jsFiddle演示

我已经分享了一个演示,演示了如何取消AJAX请求——如果在预定义的等待时间内没有从服务器返回数据。

HTML格式:

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

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

大多数jQueryAjax方法都返回XMLHttpRequest(或等效的)对象,因此您可以只使用abort()。

请参阅文档:

中止方法(MSDN)。取消当前HTTP请求。abort()(MDN)。如果请求已经发送,则此方法将中止请求。

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

更新:从jQuery1.5开始,返回的对象是本地XMLHttpRequest对象jqXHR的包装器。此对象似乎公开了所有本机财产和方法,因此上述示例仍然有效。请参阅jqXHR对象(jQuery API文档)。

更新2:从jQuery3开始,ajax方法现在使用额外的方法(如abort)返回一个promise,所以上面的代码仍然有效,尽管返回的对象不再是xhr。请在此处查看3.0博客。

UPDATE3:xhr.abourt()仍然适用于jQuery3.x。不要假设更新2是正确的。有关jQuery Github存储库的更多信息。

以下代码显示了启动和中止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!" >

我们只需要解决这个问题,并测试了三种不同的方法。

按照@meouw的建议取消请求执行所有请求,但只处理最后一次提交的结果在另一个请求仍处于挂起状态时阻止新请求

变量Ajax1={调用:函数(){if(typeof this.xhr!==“undefined”)this.xhr.abourt();this.xhr=$.ajax({url:'您的/long/running/request/path',类型:'GET',成功:函数(数据){//过程响应}});}};变量Ajax2={计数器:0,调用:函数(){var self=此,seq=++此计数器;$.ajax美元({url:'您的/long/running/request/path',类型:'GET',成功:函数(数据){如果(seq==self.counter){//过程响应}}});}};变量Ajax3={活动:假,调用:函数(){如果(this.active==false){this.active=真;var self=this;$.ajax美元({url:'您的/long/running/request/path',类型:'GET',成功:函数(数据){//过程响应},完成:函数(){self.active=假;}});}}};$(函数){$(“#按钮”).click(函数(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”/>

在我们的案例中,我们决定使用方法#3,因为它会减少服务器的负载。但我不能100%确定jQuery是否保证调用.complete()方法,这可能会导致死锁。在我们的测试中,我们无法再现这种情况。