Detener todas las solicitudes ajax activas en jQuery

Tengo un problema, al enviar un formulario, todas las solicitudes activas de ajax fallan y eso desencadena un evento de error.

¿Cómo detener todas las solicitudes ajax activas en jQuery sin un evento de error trigerring?

Cada vez que creas una solicitud ajax puedes usar una variable para almacenarla:

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

Entonces puedes abortar la solicitud:

 request.abort(); 

Puede usar una matriz para hacer un seguimiento de todas las solicitudes ajax pendientes y cancelarlas si es necesario.

El siguiente fragmento le permite mantener una lista ( grupo ) de solicitudes y cancelarlas todas si es necesario. Lo mejor es colocarlo en de su html, antes de realizar cualquier otra llamada AJAX.

  

El uso de ajaxSetup no es correcto , como se indica en su página de documento. Solo configura los valores predeterminados, y si algunas solicitudes los reemplazan, habrá un desastre.

Llego muy tarde a la fiesta, pero para futuras referencias si alguien está buscando una solución para el mismo problema, aquí está mi opinión, inspirada y en gran parte idéntica a las respuestas anteriores, pero más completa

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

Esto es lo que estoy usando actualmente para lograr eso.

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

Nota: _each de underscore.js está presente, pero obviamente no es necesario. Solo soy flojo y no quiero cambiarlo a $ .each (). 8P

Dé a cada solicitud xhr un ID único y almacene la referencia del objeto en un objeto antes de enviarlo. Elimine la referencia después de completar una solicitud xhr.

Para cancelar todas las solicitudes en cualquier momento:

 $.ajaxQ.abortAll(); 

Devuelve los id únicos de solicitud cancelada. Solo para fines de prueba.

Función de trabajo:

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

Devuelve un objeto con una sola función que se puede usar para agregar más funcionalidad cuando sea necesario.

Me pareció demasiado fácil para múltiples solicitudes.

paso1: define una variable en la parte superior de la página:

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

step2: configure beforeSend en todas las solicitudes ajax:

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

paso 3: utilícelo donde lo requiera:

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

Extendí mkmurray y SpYk3HH la respuesta anterior para que xhrPool.abortAll pueda cancelar todas las solicitudes pendientes de una URL determinada :

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

El uso es el mismo excepto que abortAll ahora puede aceptar opcionalmente una url como parámetro y cancelará solo las llamadas pendientes a esa url

Tuve algunos problemas con el código de andy, pero me dio algunas ideas geniales. El primer problema fue que deberíamos desconectar cualquier objeto jqXHR que se complete con éxito. También tuve que modificar la función abortAll. Aquí está mi código de trabajo final:

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

No me gustó la forma de hacer las cosas ajaxComplete (). No importa cómo intenté configurar .ajaxSetup, no funcionó.

He actualizado el código para que funcione para mí

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

Lanzando mi sombrero. Ofrece abort y remove métodos contra la matriz xhrPool , y no es propenso a problemas con ajaxSetup reemplaza.

 /** * Ajax Request Pool * * @author Oliver Nassar  * @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 (presumbly by accident). */ $(document).ajaxSend(function(event, jqXHR, options) { jQuery.xhrPool.push(jqXHR); }); $(document).ajaxComplete(function(event, jqXHR, options) { jQuery.xhrPool.remove(jqXHR); }); 

Haga una agrupación de todas las solicitudes de ajax y abortarlas …..

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

Es mejor usar código independiente …

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

Tan importante como decir que quieres cerrar sesión y estás generando nuevas solicitudes con temporizadores: porque los datos de sesión se renuevan con cada nuevo arranque (quizás puedas decir que estoy hablando de Drupal, pero este podría ser cualquier sitio que use sesiones). Tuve que revisar todos mis scripts con una búsqueda y reemplazo, porque tenía un montón de cosas en ejecución en diferentes casos: variables globales en la parte superior:

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

A continuación, le mostramos cómo conectar esto en cualquier clic (útil si su página está realizando muchas llamadas AJAX y está intentando navegar).

 $ -> $.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()