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


当前回答

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

然后,您可以在中止前设置onreadystatechange以防止:

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

其他回答

我已经分享了一个演示,演示了如何取消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.art()。

巨大的漏洞:你可以中止请求,但这只是客户端。服务器端可能仍在处理请求。如果您对会话数据使用PHP或ASP之类的东西,那么会话数据将被锁定,直到ajax完成。因此,为了允许用户继续浏览网站,必须调用session_write_close()。这将保存会话并将其解锁,以便等待继续的其他页面将继续。如果没有这一点,可能会有多个页面等待解除锁定。

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

我试图解决的问题(其他人可能也会遇到)是,当用户在输入字段中输入信息时,我想发出一个请求,请求使用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记录到控制台。

没有可靠的方法可以做到这一点,一旦请求得到满足,我甚至不会尝试;唯一合理反应的方法就是忽略反应。

在大多数情况下,这可能会发生在这样的情况下:用户太频繁地点击一个按钮,触发许多连续的XHR,这里有很多选项,要么在XHR返回之前阻止该按钮,要么在另一个正在运行时甚至不触发新的XHR(提示用户向后倾斜),要么丢弃除最近的XHR响应之外的任何未决XHR响应。

大多数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存储库的更多信息。