使用jQuery中止Ajax请求

使用jQuery,我如何取消/中止我还没有收到回应的Ajax请求

大多数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(); 

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

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

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

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

否则,只需忽略AJAX响应。

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

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

AJAX请求可能无法按照开始的顺序完成。 除了中止,您可以select忽略除最近一个之外的所有AJAX响应:

  • 创build一个计数器
  • 在启动AJAX请求时增加计数器
  • 使用计数器的当前值“加盖”请求
  • 在成功callback比较印记与计数器,以检查是否是最近的请求

代码的粗略轮廓:

 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

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

  1. 根据@meouw的build议取消请求
  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" /> 

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

 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,则会好得多。

meouw的解决scheme是正确的,但如果你对更多的控制感兴趣,那么你可以尝试jQuery的Ajaxpipe理器插件 。

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

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

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

正如线程中的许多人所指出的,仅仅因为请求在客户端被中止,服务器仍然会处理请求。 这会在服务器上造成不必要的负载,因为它正在做我们已经放弃在前端监听的工作。

我试图解决的问题(其他人也可能会遇到)是,当用户在input字段中input信息时,我想要发出Google即时types的请求。

为了避免发出不必要的请求,并保持前端的快乐,我做了以下工作:

 var xhrQueue = []; var xhrCount = 0; $('#search_q').keyup(function(){ xhrQueue.push(xhrCount); setTimeout(function(){ xhrCount = ++xhrCount; if (xhrCount === xhrQueue.length) { // Fire Your XHR // } }, 150); }); 

这将基本上每150毫秒发送一个请求(一个variables,您可以根据自己的需要进行自定义)。 如果您无法理解这里发生了什么, xhrCountxhrQueue到if块之前的控制台。

只要使用ajax.abort()例如你可以放弃任何未决的Ajax请求,然后再发送这样的一个

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

没有可靠的方法去做,而且一旦请求被移走,我甚至不会去尝试。 唯一合理的反应就是忽视这个反应。

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

只要打电话给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); 

我有轮询的问题,一旦页面closures,民意调查继续进行,所以在我的原因中,用户会错过更新,因为在closures页面后的下一个50秒,将会设置一个mysql值,即使我杀了ajax请求,我弄清楚,使用$ _SESSION来设置一个var不会更新自己的轮询,直到它结束,并开始一个新的,所以我所做的是在我的数据库中设置一个值为0 = offpage,而我轮询我查询该行并返回false; 当它是0,因为在轮询中查询会显示当前值…

我希望这有助于

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

我已经分享了演示如何取消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); }); 

如果xhr.abort(); 导致页面重新加载,

那么你可以在中止之前设置onreadystatechange来防止:

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