JQuery में सभी सक्रिय ajax अनुरोधों को रोकें


216

मुझे एक समस्या है, जब एक फॉर्म सबमिट करने से सभी सक्रिय अजाक्स अनुरोध विफल हो जाते हैं, और यह त्रुटि घटना को ट्रिगर करता है।

त्रुटि घटना को ट्रिगर किए बिना jQuery में सभी सक्रिय ajax अनुरोधों को कैसे रोकें?

जवाबों:


273

हर बार जब आप एक अजाक्स अनुरोध बनाते हैं तो आप इसे स्टोर करने के लिए एक चर का उपयोग कर सकते हैं:

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

तब आप अनुरोध को निरस्त कर सकते हैं:

request.abort();

आप सभी लंबित अजाक्स अनुरोधों पर नज़र रखने वाले सरणी का उपयोग कर सकते हैं और यदि आवश्यक हो तो उन्हें रोक सकते हैं।


THXs, मैंने एक FLAG जोड़ा क्योंकि मैंने एक ही समय में कई अनुरोधों का उपयोग किया था
jcho360

यहाँ सरल कार्य उदाहरण है: stackoverflow.com/a/42312101/3818394
धर्मेश पटेल

मेरे पास फ़ंक्शन में अजाक्स कॉल है मैं इसे कैसे गर्भपात कर सकता हूं?
कलारिया_एम

जब अजाक्स कॉल जारी है, तो चर को दूसरे फ़ंक्शन से इसे एक्सेस करने के लिए वैश्विक घोषित किया जाना है। उदाहरण: एक बहु-फ़ाइल अपलोड प्रक्रिया।
क्लिन डीसिल्वा

180

निम्नलिखित स्निपेट आपको अनुरोध की एक सूची ( पूल ) को बनाए रखने और यदि आवश्यक हो तो उन सभी को निरस्त करने की अनुमति देता है । किसी भी अन्य AJAX कॉल करने से पहले<HEAD> , अपने html में रखने के लिए सबसे अच्छा है ।

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

2
@mkmurray - IE8 में initalization पर मुझे लगता है Object doesn't support property or method 'indexOf'? मुझे संदेह है कि यह stackoverflow.com/a/2608601/181971 या हो सकता है कि बस stackoverflow.com/a/2608618/181971 पर स्वैप हो ?
टिम

3
@grr सही है, उसका उत्तर देखें और ajaxSetup के लिए डॉक्स जांचें
kzfabi

@Tim - जैसा कि स्टीवन ने सुझाव दिया था, var index = $ .xhrPool.indexOf (jqXHR) के बजाय; उपयोग: var इंडेक्स = $ .inArray (jqXHR, $ .xhrPool);
क्रिस्टोफर

1
@mkmurray: यह TypeError दिखाता है: jqXHR.abort मेरे लिए कोई फ़ंक्शन नहीं है। :(
शेषा

AbortAll पद्धति में थोड़ी सी तार्किक त्रुटि है, जो इस उत्तर में यहां बताई गई है stackoverflow.com/a/45500874/1041341
सरीन JS

122

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

कोई अन्य कार्यों से गर्भपात () विधि कैसे कहता है?
स्टेन जेम्स

गर्भपात एक कार्य है, विधि नहीं। आप इसे सामान्य रूप से एक ही एनकैप्सुलेशन के भीतर से कॉल करते हैं, यदि आपको इसे एनकैप्सुलेशन के बाहर उपयोग करने की आवश्यकता है, तो आप फ़ंक्शन नाम से पहले "var" को हटा सकते हैं और यह विश्व स्तर पर उपलब्ध कवक बन जाएगा
Trey

हाय, कोई समझा सकता है कि आर अपरिभाषित कब होगा?
वरुण

36

यहाँ है कि मैं वर्तमान में उपयोग कर रहा हूँ कि पूरा करने के लिए।

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

नोट: _.each of underscore.js मौजूद है, लेकिन स्पष्ट रूप से आवश्यक नहीं है। मैं सिर्फ आलसी हूं और मैं इसे $ .each () में बदलना नहीं चाहता। 8P


2
मुझे थोड़ा संशोधित समाधान मिला है जो बहुत अच्छा काम करता है जो मैं अभी पोस्ट करने वाला हूं।
19km

7
यह स्मृति लीक करती है। aboutAllतत्वों को सरणी से निकालना चाहिए। प्लस जब एक अनुरोध समाप्त हो जाता है, तो उसे सूची से खुद को हटा देना चाहिए।
बेहरंग सईदज़ादेह

5
@BehrangSaeedzadeh आपको तब एक बेहतर संस्करण भी पोस्ट करना चाहिए था।
मैट्सवेन

19

प्रत्येक 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;
    }
  };

})();

एकल फ़ंक्शन के साथ एक ऑब्जेक्ट देता है जिसका उपयोग आवश्यकता होने पर अधिक कार्यक्षमता जोड़ने के लिए किया जा सकता है।


17

मुझे कई अनुरोधों के लिए यह बहुत आसान लगा।

चरण 1: पृष्ठ के शीर्ष पर एक चर को परिभाषित करें:

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

Step2 : पहले सेट करें सभी ajax अनुरोधों में भेजें:

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

चरण 3: जहां भी आपको आवश्यक हो, इसका उपयोग करें:

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

यह मेमोरी लीक होती है, जैसे कि stackoverflow.com/a/6618288/1772379 और ठीक उसी कारणों से।
बेन जॉनसन

जावास्क्रिप्ट लिखने के लिए वास्तव में भयानक तरीका है।
ओजिल

1
अंत में हो सकता है आप xhrPool सरणी को खाली / खाली कर सकते हैं
अंतरिक्ष पृथ्वी

6

मैंने 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 के लंबित कॉल को रद्द कर देगा


5

मुझे andy कोड के साथ कुछ समस्याएं थीं, लेकिन इसने मुझे कुछ बेहतरीन विचार दिए। पहली समस्या यह थी कि हमें सफलतापूर्वक पूरा होने वाले किसी भी 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 यह काम नहीं किया।


7
मुझे लगता है कि यदि आप किसी विशेष क्रम में पूरा नहीं करते हैं तो आप गलत अनुरोध पर पॉप कह सकते हैं?
jjmontes

1
हां, आप पॉप के बजाय स्लाइस करना चाहते हैं। मुझे थोड़ा संशोधित समाधान मिला है जो मैं पोस्ट करने वाला हूं।
19km

4

मैंने अपने लिए काम करने के लिए कोड को अपडेट कर दिया है

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

4

मेरी टोपी को फेंकता है। ऑफ़र abortऔर removeतरीके xhrPoolसरणी के विरुद्ध हैं , और ajaxSetupओवरराइड के साथ समस्याओं का खतरा नहीं है ।

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

2

सभी ऐजैक्स अनुरोधों का एक पूल बनाएं और उन्हें निरस्त करें ....।

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

1

स्वतंत्र कोड का उपयोग करने के लिए बेहतर है .....

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

0

बस के रूप में महत्वपूर्ण: कहते हैं कि आप लॉग इन करना चाहते हैं और आप टाइमर के साथ नए अनुरोध उत्पन्न कर रहे हैं: क्योंकि सत्र डेटा को प्रत्येक नए बूटस्ट्रैप के साथ नवीनीकृत किया जाता है (शायद आप बता सकते हैं कि मैं ड्रुपल बात कर रहा हूं, लेकिन यह कोई भी साइट हो सकती है जो सत्र का उपयोग करती है) ।। मुझे अपनी सभी लिपियों को एक खोज और प्रतिस्थापित करके जाना था, क्योंकि मेरे पास विभिन्न मामलों में एक टन सामान था: शीर्ष पर वैश्विक चर:

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

0
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()

-2

एक डमी समाधान है मैं इसका उपयोग सभी अजाक्स अनुरोधों को समाप्त करने के लिए करता हूं। यह समाधान पूरे पृष्ठ को पुनः लोड कर रहा है। यदि आप प्रत्येक ajax अनुरोध के लिए एक आईडी असाइन करना पसंद नहीं करते हैं, और यदि आप लूप के अंदर ajax अनुरोध करते हैं तो यह समाधान अच्छा है। यह सुनिश्चित करेगा कि सभी अजाक्स अनुरोध मारे गए हैं।

location.reload();

-3

यहां किसी भी क्लिक पर इसे हुक करने का तरीका बताया गया है (यदि आपका पेज कई 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()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.