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

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


当前回答

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

$.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);
        }
    }
});

其他回答

同样重要的是:假设您想要注销,并且正在使用计时器生成新的请求:因为会话数据会随着每次新的引导而更新(也许您可以告诉我说的是Drupal,但这可能是任何使用会话的站点)……我必须通过搜索和替换我所有的脚本,因为我有大量的东西在不同的情况下运行:全局变量在顶部:

var ajReq = [];
var canAj = true;
function abort_all(){
 for(x in ajReq){
    ajReq[x].abort();
    ajReq.splice(x, 1)
 }
 canAj = false;
}
function rmvReq(ranNum){
 var temp = [];
 var i = 0;
 for(x in ajReq){
    if(x == ranNum){
     ajReq[x].abort();
     ajReq.splice(x, 1);
    }
    i++;
 }
}
function randReqIndx(){
 if(!canAj){ return 0; }
 return Math.random()*1000;
}
function getReqIndx(){
 var ranNum;
 if(ajReq.length){
    while(!ranNum){
     ranNum = randReqIndx();
     for(x in ajReq){
    if(x===ranNum){
     ranNum = null;
    }
     }
    }
    return ranMum;
 }
 return randReqIndx();
}
$(document).ready(function(){
 $("a").each(function(){
    if($(this).attr('href').indexOf('/logout')!=-1){          
     $(this).click(function(){
    abort_all();                 
     });
    }
 })
});
// Then in all of my scripts I wrapped my ajax calls... If anyone has a suggestion for a 
    // global way to do this, please post
var reqIndx = getReqIndx();
if(reqIndx!=0){
ajReq[reqIndx] = $.post(ajax, { 'action': 'update_quantities', iids:iidstr, qtys:qtystr },  
function(data){
 //..do stuff
 rmvReq(reqIndx);
 },'json');
}

做一个池的所有ajax请求和中止他们.....

var xhrQueue = []; 

$(document).ajaxSend(function(event,jqxhr,settings){
    xhrQueue.push(jqxhr); //alert(settings.url);
});

$(document).ajaxComplete(function(event,jqxhr,settings){
    var i;   
    if((i=$.inArray(jqxhr,xhrQueue)) > -1){
        xhrQueue.splice(i,1); //alert("C:"+settings.url);
    }
});

ajaxAbort = function (){  //alert("abortStart");
    var i=0;
    while(xhrQueue.length){ 
        xhrQueue[i++] .abort(); //alert(i+":"+xhrQueue[i++]);
    }
};

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

这里是一个复制过去的函数,刷新所有的ajax调用。 fillCompteList()和fetchAll()必须返回ajax对象:

function fillCompteList() {
   return $.ajax({
            url: 'www.somewhere.com' ,
            method: 'GET',
            success: function(res){
            ...
          });

然后用这个

var xhrPool = [fillCompteList(inisial), fetchAll(params)] ;//old
function refrechAllUsing(SOME , params){
    xhrPool.forEach(function(request){
        request.abort();
    });
    xhrPool = [fillCompteList(SOME), fetchAll(params)]//new with other parameters
    Promise.all(xhrPool).then(() => {
        $('#loadding').undisplay();//remove the loadding screen 

    }).catch(() => {
        warning("Some problem happened");
        $('#loadding').undisplay();//remove the loadding screen 
    });
}

我扩展了mkmurray和SpYk3HH回答上面的xhrPool。abortAll可以中止所有给定url的挂起请求:

$.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;
});

除了abortAll现在可以选择接受url作为参数并只取消对该url的挂起调用之外,其他用法是相同的