javascript - jquery abort




使用jQuery中止Ajax请求 (12)

使用jQuery,我如何取消/中止我还没有收到响应的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上演示



保存你在一个数组中所做的调用,然后在每个数组上调用xhr.abort()。

巨大的CAVEAT:您可以放弃请求,但这只是客户端。 服务器端可能仍然在处理请求。 如果您使用PHP或ASP等会话数据,会话数据将被锁定,直到ajax完成。 因此,要允许用户继续浏览网站,您必须调用session_write_close ()。 这会保存会话并将其解锁,以等待继续的其他页面继续。 没有这个,几个页面可能正在等待锁被删除。


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

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请求是否为null,则会好得多。


只需致电xhr。 abort()是否是jquery ajax对象或本机XMLHTTPRequest对象。

例:

//jQuery ajax
$(document).ready(
    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);

大多数jQuery Ajax方法返回一个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()

更新:从jQuery 1.5开始,返回的对象是一个名为jqXHR的原生XMLHttpRequest对象的包装器。 这个对象似乎公开了所有的本地属性和方法,所以上面的例子仍然有效。 请参阅jqXHR对象 (jQuery API文档)。

更新2:截至jQuery 3,ajax方法返回一个没有额外方法的承诺(如中止),所以这将不再工作。 在这里查看3.0博客 。 解决这个问题的一个方法是通过xhr属性来控制xhr对象。 这是一个简单的例子:

var xhr = new window.XMLHttpRequest();
var request = $.ajax({
    url : url,
    xhr : function(){
        return xhr;
    }
});
xhr.abort();

您无法记起请求,但可以设置一个超时值,之后响应将被忽略。 看到这个page的jQuery AJAX选项。 我相信如果超时超时,你的错误回调将被调用。 每个AJAX请求都有一个默认的超时时间。

您也可以在请求对象上使用abort()方法,但是,虽然它会导致客户端停止监听事件,但它可能不会阻止服务器处理它。


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

  1. 根据@meouw的建议取消请求
  2. 执行所有请求,但仅处理上次提交的结果
  3. 只要另一个仍在等待,就可以阻止新的请求

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

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


我正在做一个实时搜索解决方案,并需要取消可能需要比最新/最新请求更长的未决请求。

在我的情况下,我使用了这样的东西:

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

我遇到了轮询的问题,一旦页面关闭,投票继续进行,因此在我的原因中,用户会错过更新,因为在关闭页面后的下一个50秒内将设置一个mysql值,即使我杀了ajax请求,I在使用$ _SESSION来设置一个var时,它不会在它自己的poll中更新,直到它结束并且一个新的开始,所以我所做的就是在我的数据库中将值设置为0 = offpage,而我轮询我查询该行并返回false; 当它为0,因为在轮询中查询会明显得到当前值......

我希望这有助于


没有可靠的方法来做到这一点,而且一旦请求在移动中,我甚至不会去尝试; 唯一合理反应的方法是忽略回应。

在大多数情况下,它可能发生在如下情况中:用户在按钮上点击过多会触发许多连续的XHR,这里有很多选项,要么阻止按钮直到返回XHR,要么在另一个运行提示时甚至不触发新的XHR用户靠后 - 或放弃任何未决的XHR响应,但最近。


这是一个异步请求,意思是一旦它被发送出去。

如果您的服务器由于AJAX请求而开始非常昂贵的操作,那么您可以做的最好的方法是打开服务器以侦听取消请求,并发送单独的AJAX请求,通知服务器停止正在进行的操作。

否则,只需忽略AJAX响应。





ajax