Stop all active ajax requests in jQuery

JqueryAjax

Jquery Problem Overview


I have a problem, when submitting a form all active ajax request fail, and that triggers error event.

How to stop all active ajax requests in jQuery without trigerring error event?

Jquery Solutions


Solution 1 - Jquery

Every time you create an ajax request you could use a variable to store it:

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

Then you can abort the request:

request.abort();

You could use an array keeping track of all pending ajax requests and abort them if necessary.

Solution 2 - Jquery

The following snippet allows you to maintain a list (pool) of request and abort them all if needed. Best to place in the <HEAD> of your html, before any other AJAX calls are made.

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

Solution 3 - Jquery

Using ajaxSetup is not correct, as is noted on its doc page. It only sets up defaults, and if some requests override them there will be a mess.

I am way late to the party, but just for future reference if someone is looking for a solution to the same problem, here is my go at it, inspired by and largely identical to the previous answers, but more complete

// 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);

Solution 4 - Jquery

Here's what I'm currently using to accomplish that.

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

Note: _.each of underscore.js is present, but obviously not necessary. I'm just lazy and I don't want to change it to $.each(). 8P

Solution 5 - Jquery

Give each xhr request a unique id and store the object reference in an object before sending. Delete the reference after an xhr request completes.

To cancel all request any time:

$.ajaxQ.abortAll();

Returns the unique ids of canceled request. Only for testing purposes.

Working function:

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

})();

Returns an object with single function which can be used to add more functionality when required.

Solution 6 - Jquery

I found it too easy for multiple requests.

step1: define a variable at top of page:

  xhrPool = []; // no need to use **var**

step2: set beforeSend in all ajax requests:

  $.ajax({
   ...
   beforeSend: function (jqXHR, settings) {
        xhrPool.push(jqXHR);
    },
    ...

step3: use it wherever you required:

   $.each(xhrPool, function(idx, jqXHR) {
          jqXHR.abort();
    });

Solution 7 - Jquery

I extended mkmurray and SpYk3HH answer above so that xhrPool.abortAll can abort all pending requests of a given 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;
});

Usage is same except that abortAll can now optionally accept a url as a parameter and will cancel only pending calls to that url

Solution 8 - Jquery

I had some problems with andy's code, but it gave me some great ideas. First problem was that we should pop off any jqXHR objects that successfully complete. I also had to modify the abortAll function. Here is my final working code:

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

I didn't like the ajaxComplete() way of doing things. No matter how I tried to configure .ajaxSetup it did not work.

Solution 9 - Jquery

I have updated the code to make it works for me

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

Solution 10 - Jquery

Throwing my hat in. Offers abort and remove methods against the xhrPool array, and is not prone to issues with ajaxSetup overrides.

/**
 * Ajax Request Pool
 * 
 * @author Oliver Nassar <onassar@gmail.com>
 * @see    http://stackoverflow.com/questions/1802936/stop-all-active-ajax-requests-in-jquery
 */
jQuery.xhrPool = [];

/**
 * jQuery.xhrPool.abortAll
 * 
 * Retrieves all the outbound requests from the array (since the array is going
 * to be modified as requests are aborted), and then loops over each of them to
 * perform the abortion. Doing so will trigger the ajaxComplete event against
 * the document, which will remove the request from the pool-array.
 * 
 * @access public
 * @return void
 */
jQuery.xhrPool.abortAll = function() {
    var requests = [];
    for (var index in this) {
        if (isFinite(index) === true) {
            requests.push(this[index]);
        }
    }
    for (index in requests) {
        requests[index].abort();
    }
};

/**
 * jQuery.xhrPool.remove
 * 
 * Loops over the requests, removes it once (and if) found, and then breaks out
 * of the loop (since nothing else to do).
 * 
 * @access public
 * @param  Object jqXHR
 * @return void
 */
jQuery.xhrPool.remove = function(jqXHR) {
    for (var index in this) {
        if (this[index] === jqXHR) {
            jQuery.xhrPool.splice(index, 1);
            break;
        }
    }
};

/**
 * Below events are attached to the document rather than defined the ajaxSetup
 * to prevent possibly being overridden elsewhere (presumably by accident).
 */
$(document).ajaxSend(function(event, jqXHR, options) {
    jQuery.xhrPool.push(jqXHR);
});
$(document).ajaxComplete(function(event, jqXHR, options) {
    jQuery.xhrPool.remove(jqXHR);
});

Solution 11 - Jquery

Make a pool of all ajax request and abort them.....

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++]);
	}
};

Solution 12 - Jquery

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

whenever you want to abort all the ajax request, you just need call this line

Request.AbortAll()

Solution 13 - Jquery

Better to use independent code.....

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++]);
	}
};

Solution 14 - Jquery

Just as important: say you want to log off and you are generating new requests with timers: because session data is renewed with each new bootstrap (maybe you can tell I am talking Drupal, but this could be any site that uses sessions)... I had to go through all my scripts with a search and replace, cause I had a ton of stuff running in different cases: global variables at the top:

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');
}

Solution 15 - Jquery

Here is a copy past function that refreches all your ajax calls.
The fillCompteList() and fetchAll() must return ajax object :

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

And then use this

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

Solution 16 - Jquery

Here's how to hook this up on any click (useful if your page is placing many AJAX calls and you're trying to navigate away).

$ ->
    $.xhrPool = [];

$(document).ajaxSend (e, jqXHR, options) ->
    $.xhrPool.push(jqXHR)

$(document).ajaxComplete (e, jqXHR, options) ->
    $.xhrPool = $.grep($.xhrPool, (x) -> return x != jqXHR);

$(document).delegate 'a', 'click', ->
    while (request = $.xhrPool.pop())
      request.abort()

Solution 17 - Jquery

There is a dummy solution I use it to abort all ajax requests. This solution is reload the whole page. This solution is good if you don't like to assign an ID to each ajax request, and if you make ajax requests inside for-loop. This will make sure all ajax requests are killed.

location.reload();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionumpirskyView Question on Stackoverflow
Solution 1 - JqueryDarin DimitrovView Answer on Stackoverflow
Solution 2 - JquerymkmurrayView Answer on Stackoverflow
Solution 3 - JquerygrrView Answer on Stackoverflow
Solution 4 - JqueryAndy FerraView Answer on Stackoverflow
Solution 5 - JqueryrefikView Answer on Stackoverflow
Solution 6 - JqueryDharmesh patelView Answer on Stackoverflow
Solution 7 - JquerykofifusView Answer on Stackoverflow
Solution 8 - Jquerythe HampsterView Answer on Stackoverflow
Solution 9 - JqueryStevenView Answer on Stackoverflow
Solution 10 - JqueryonassarView Answer on Stackoverflow
Solution 11 - JqueryZigri2612View Answer on Stackoverflow
Solution 12 - JqueryOmid MatouriView Answer on Stackoverflow
Solution 13 - JqueryZigri2612View Answer on Stackoverflow
Solution 14 - JqueryGoodNewsView Answer on Stackoverflow
Solution 15 - JqueryYasser CHENIKView Answer on Stackoverflow
Solution 16 - JquerydB.View Answer on Stackoverflow
Solution 17 - JqueryASammourView Answer on Stackoverflow