14 ответов:
каждый раз, когда вы создаете запрос ajax, вы можете использовать переменную для его хранения:
var request = $.ajax({ type: 'POST', url: 'someurl', success: function(result){} });затем вы можете прервать запрос:
request.abort();вы можете использовать массив, отслеживающий все ожидающие запросы ajax и прерывать их при необходимости.
следующий фрагмент кода позволяет вести список (бассейн) запроса и прервать их все, если это необходимо. Лучше всего разместить в
<HEAD>вашего html,до выполняются любые другие вызовы 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>
С помощью ajaxSetup не является правильным, как отмечено на его странице doc. Он только устанавливает значения по умолчанию, и если некоторые запросы переопределяют их, будет беспорядок.
Я опаздываю на вечеринку, но только для дальнейшего использования, если кто-то ищет решение той же проблемы, вот мой подход к ней, вдохновленный и во многом идентичный предыдущим ответам, но более полный
// 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() { _.each(this, function(jqXHR) { jqXHR.abort(); }); }; $.ajaxSetup({ beforeSend: function(jqXHR) { $.xhrPool.push(jqXHR); } });Примечание: _.каждый из них подчеркнет.js присутствует, но явно не нужен. Я просто ленив, и я не хочу менять его на $.каждый.)( 8P
дайте каждому запросу xhr уникальный идентификатор и сохраните ссылку на объект в объекте перед отправкой. Удалите ссылку после завершения запроса xhr.
чтобы отменить все запросы в любое время:
$.ajaxQ.abortAll();возвращает уникальные идентификаторы отмененного запроса. Только для целей тестирования.
функция:
$.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; } }; })();возвращает объект с одной функцией, которая может быть использована для добавления дополнительных функций при необходимости.
Я нашел это слишком легко для нескольких запросов.
Шаг 1: определить переменную в верхней части страницы:
xhrPool = []; // no need to use **var**Шаг 2: установить beforeSend во всех ajax-запросах:
$.ajax({ ... beforeSend: function (jqXHR, settings) { xhrPool.push(jqXHR); }, ...Шаг 3: используйте его везде, где вам требуется:
$.each(xhrPool, function(idx, jqXHR) { jqXHR.abort(); });
я расширил 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-адрес
У меня были некоторые проблемы с кодом Энди, но это дало мне некоторые отличные идеи. Первая проблема заключалась в том, что мы должны выскочить любые объекты 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 это не сработало.
я обновил код, чтобы он работал для меня
$.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); } } });
бросаю свою шляпу. Предложения
abortиremoveметоды противxhrPoolмассив, и не склонен к проблемам сajaxSetupпереопределяет./** * Ajax Request Pool * * @author Oliver Nassar <[email protected]> * @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); });
создайте пул всех запросов 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++]); } };
лучше использовать независимый код.....
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++]); } };
так же важно: скажите, что вы хотите выйти из системы, и вы генерируете новые запросы с помощью таймеров: потому что данные сеанса обновляются с каждой новой загрузкой (возможно, вы можете сказать, что я говорю 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, и вы пытаетесь перейти).
$ -> $.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()
Comments