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

如何在jQuery中停止所有活动ajax请求而不触发错误事件?


当前回答

安迪的代码有一些问题,但它给了我一些很好的想法。第一个问题是,我们应该弹出任何成功完成的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();
            });

我不喜欢ajaxComplete()做事情的方式。无论我如何尝试配置. ajaxsetup,它都不工作。

其他回答

使用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);

我已经更新了代码,使它为我工作

$.xhrPool = [];
$.xhrPool.abortAll = function() {
    $(this).each(function(idx, jqXHR) {
        jqXHR.abort();
    });
    $(this).each(function(idx, jqXHR) {
        var index = $.inArray(jqXHR, $.xhrPool);
        if (index > -1) {
            $.xhrPool.splice(index, 1);
        }
    });
};

$.ajaxSetup({
    beforeSend: function(jqXHR) {
        $.xhrPool.push(jqXHR);
    },
    complete: function(jqXHR) {
        var index = $.inArray(jqXHR, $.xhrPool);
        if (index > -1) {
            $.xhrPool.splice(index, 1);
        }
    }
});

安迪的代码有一些问题,但它给了我一些很好的想法。第一个问题是,我们应该弹出任何成功完成的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();
            });

我不喜欢ajaxComplete()做事情的方式。无论我如何尝试配置. ajaxsetup,它都不工作。

var Request = {
    List: [],
    AbortAll: function () {
        var _self = this;
        $.each(_self.List, (i, v) => {
            v.abort();
        });
    }
}
var settings = {
    "url": "http://localhost",
    success: function (resp) {
        console.log(resp)
    }
}

Request.List.push($.ajax(settings));

每当您想要中止所有ajax请求时,只需调用这一行

Request.AbortAll()

下面的代码片段允许您维护一个请求列表(池),并在需要时中止它们。最好放在html的<HEAD>中,在任何其他AJAX调用之前。

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