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


当前回答

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

其他回答

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

我试图解决的问题(其他人可能也会遇到)是,当用户在输入字段中输入信息时,我想发出一个请求,请求使用Google Instant类型的感觉。

为了避免发出不必要的请求并保持前端的快速性,我执行了以下操作:

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毫秒发送一个请求(您可以根据自己的需要定制一个变量)。如果您无法理解这里到底发生了什么,请在If块之前将xhrCount和xhrQueue记录到控制台。

大多数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请求而启动了一个非常昂贵的操作,那么您所能做的最好就是打开服务器以侦听取消请求,然后发送一个单独的AJAX请求,通知服务器停止它正在做的任何事情。

否则,只需忽略AJAX响应。

我遇到了轮询的问题,一旦页面关闭,轮询就继续进行,所以在我的原因中,用户会错过一次更新,因为在页面关闭后的下一个50秒内,mysql值被设置,即使我终止了ajax请求,我还是想了想,使用$_SESSION设置一个var。在轮询结束并开始新的轮询之前,所以我所做的是在数据库中设置一个值为0=offpage,当我轮询时,我查询该行并返回false;当它为0时,轮询中的查询将明显地获得当前值。。。

我希望这有帮助

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

按照@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()方法,这可能会导致死锁。在我们的测试中,我们无法再现这种情况。