在jQuery中停止所有活动的ajax请求

ump*_*sky 210 ajax jquery

我有一个问题,当提交表单时,所有活动的ajax请求都会失败,并触发错误事件.

如何在没有trigerring错误事件的情况下停止jQuery中所有活动的ajax请求?

Dar*_*rov 268

每次创建ajax请求时,都可以使用变量来存储它:

var request = $.ajax({
    type: 'POST',
    url: 'someurl',
    success: function(result){}
});
Run Code Online (Sandbox Code Playgroud)

然后你可以中止请求:

request.abort();
Run Code Online (Sandbox Code Playgroud)

您可以使用数组跟踪所有待处理的ajax请求,并在必要时中止它们.


mkm*_*ray 180

以下代码段允许您维护请求列表()并在需要时中止所有请求.在进行任何其他AJAX调用之前<HEAD>,最好放在你的html 中.

<script type="text/javascript">
    $(function() {
        $.xhrPool = [];
        $.xhrPool.abortAll = function() {
            $(this).each(function(i, jqXHR) {   //  cycle through list of recorded connection
                jqXHR.abort();  //  aborts connection
                $.xhrPool.splice(i, 1); //  removes from list by index
            });
        }
        $.ajaxSetup({
            beforeSend: function(jqXHR) { $.xhrPool.push(jqXHR); }, //  annd connection to list
            complete: function(jqXHR) {
                var i = $.xhrPool.indexOf(jqXHR);   //  get index for current connection completed
                if (i > -1) $.xhrPool.splice(i, 1); //  removes from list by index
            }
        });
    })
</script>
Run Code Online (Sandbox Code Playgroud)

  • @grr是对的,请参阅他的回答并查看[ajaxSetup](http://api.jquery.com/jQuery.ajaxSetup/)的文档. (3认同)
  • @mkmurray - 关于IE8中的初始化我似乎得到`对象不支持属性或方法'indexOf'`?我怀疑它可能是http://stackoverflow.com/a/2608601/181971或者只是简单地交换到http://stackoverflow.com/a/2608618/181971? (2认同)
  • @mkmurray:它显示 TypeError: jqXHR.abort 对我来说不是一个函数。:( (2认同)

grr*_*grr 121

使用ajaxSetup是不正确的,正如其文档页面上所述.它只设置默认值,如果某些请求覆盖它们,则会出现问题.

我迟到了派对,但是如果有人正在寻找同一问题的解决方案,那么只是为了将来参考,这是我的观点,受到启发并且与之前的答案基本相同,但更完整

// Automatically cancel unfinished ajax requests 
// when the user navigates elsewhere.
(function($) {
  var xhrPool = [];
  $(document).ajaxSend(function(e, jqXHR, options){
    xhrPool.push(jqXHR);
  });
  $(document).ajaxComplete(function(e, jqXHR, options) {
    xhrPool = $.grep(xhrPool, function(x){return x!=jqXHR});
  });
  var abort = function() {
    $.each(xhrPool, function(idx, jqXHR) {
      jqXHR.abort();
    });
  };

  var oldbeforeunload = window.onbeforeunload;
  window.onbeforeunload = function() {
    var r = oldbeforeunload ? oldbeforeunload() : undefined;
    if (r == undefined) {
      // only cancel requests if there is no prompt to stay on the page
      // if there is a prompt, it will likely give the requests enough time to finish
      abort();
    }
    return r;
  }
})(jQuery);
Run Code Online (Sandbox Code Playgroud)


And*_*rra 36

这是我目前用来实现的目标.

$.xhrPool = [];
$.xhrPool.abortAll = function() {
  _.each(this, function(jqXHR) {
    jqXHR.abort();
  });
};
$.ajaxSetup({
  beforeSend: function(jqXHR) {
    $.xhrPool.push(jqXHR);
  }
});
Run Code Online (Sandbox Code Playgroud)

注意:_.each of underscore.js存在,但显然不是必需的.我只是懒惰而且我不想把它改成$ .each().8P

  • 这会泄漏内存.`aboutAll`应该从数组中删除元素.另外,当请求完成时,它应该从列表中删除它自己. (7认同)
  • @BehrangSaeedzadeh你应该也发布一个改进版本. (5认同)
  • 我有一个稍微修改过的解决方案非常适合我即将发布. (2认同)

ref*_*fik 18

为每个xhr请求提供唯一的id,并在发送之前将对象引用存储在对象中.xhr请求完成后删除引用.

要随时取消所有请求:

$.ajaxQ.abortAll();
Run Code Online (Sandbox Code Playgroud)

返回已取消请求的唯一ID.仅用于测试目的.

工作功能:

$.ajaxQ = (function(){
  var id = 0, Q = {};

  $(document).ajaxSend(function(e, jqx){
    jqx._id = ++id;
    Q[jqx._id] = jqx;
  });
  $(document).ajaxComplete(function(e, jqx){
    delete Q[jqx._id];
  });

  return {
    abortAll: function(){
      var r = [];
      $.each(Q, function(i, jqx){
        r.push(jqx._id);
        jqx.abort();
      });
      return r;
    }
  };

})();
Run Code Online (Sandbox Code Playgroud)

返回具有单个函数的对象,可用于在需要时添加更多功能.


小智 15

我发现它对于多个请求来说太容易了.

step1:在页面顶部定义一个变量:

  xhrPool = []; // no need to use **var**
Run Code Online (Sandbox Code Playgroud)

step2:在所有ajax请求中设置beforeSend:

  $.ajax({
   ...
   beforeSend: function (jqXHR, settings) {
        xhrPool.push(jqXHR);
    },
    ...
Run Code Online (Sandbox Code Playgroud)

第3步:在您需要的时候使用它:

   $.each(xhrPool, function(idx, jqXHR) {
          jqXHR.abort();
    });
Run Code Online (Sandbox Code Playgroud)

  • 可能最后你可以清除/清空 xhrPool 数组 (2认同)

the*_*ter 5

我和安迪的代码有些问题,但它给了我一些很棒的想法.第一个问题是我们应该弹出任何成功完成的jqXHR对象.我还必须修改abortAll函数.这是我最后的工作代码:

$.xhrPool = [];
$.xhrPool.abortAll = function() {
            $(this).each(function(idx, jqXHR) {
                        jqXHR.abort();
                        });
};
$.ajaxSetup({
    beforeSend: function(jqXHR) {
            $.xhrPool.push(jqXHR);
            }
});
$(document).ajaxComplete(function() {
            $.xhrPool.pop();
            });
Run Code Online (Sandbox Code Playgroud)

我不喜欢ajaxComplete()做事的方式.无论我如何配置.ajaxSetup,它都无法正常工作.

  • 如果他们没有以特定的顺序完成,我想你可能会在错误的请求上调用pop? (7认同)

kof*_*fus 5

我将mkmurray和SpYk3HH的答案扩展到上面,以便xhrPool.abortAll可以中止给定网址的所有待处理请求:

$.xhrPool = [];
$.xhrPool.abortAll = function(url) {
    $(this).each(function(i, jqXHR) { //  cycle through list of recorded connection
        console.log('xhrPool.abortAll ' + jqXHR.requestURL);
        if (!url || url === jqXHR.requestURL) {
            jqXHR.abort(); //  aborts connection
            $.xhrPool.splice(i, 1); //  removes from list by index
        }
    });
};
$.ajaxSetup({
    beforeSend: function(jqXHR) {
        $.xhrPool.push(jqXHR); //  add connection to list
    },
    complete: function(jqXHR) {
        var i = $.xhrPool.indexOf(jqXHR); //  get index for current connection completed
        if (i > -1) $.xhrPool.splice(i, 1); //  removes from list by index
    }
});
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    console.log('ajaxPrefilter ' + options.url);
    jqXHR.requestURL = options.url;
});
Run Code Online (Sandbox Code Playgroud)

用法相同,但abortAll现在可以选择接受url作为参数,并且只取消对该url的挂起调用