Réponses:
Chaque fois que vous créez une requête ajax, vous pouvez utiliser une variable pour la stocker:
var request = $.ajax({
type: 'POST',
url: 'someurl',
success: function(result){}
});
Ensuite, vous pouvez abandonner la demande:
request.abort();
Vous pouvez utiliser un tableau pour garder une trace de toutes les demandes ajax en attente et les annuler si nécessaire.
L'extrait de code suivant vous permet de conserver une liste ( pool ) de demandes et de les annuler toutes si nécessaire. Il est préférable de le placer dans <HEAD>
votre html, avant tout autre appel 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>
Object doesn't support property or method 'indexOf'
? Je soupçonne que ce pourrait être stackoverflow.com/a/2608601/181971 ou peut-être simplement basculer vers stackoverflow.com/a/2608618/181971 ?
Utiliser ajaxSetup n'est pas correct , comme indiqué sur sa page doc. Il ne définit que les valeurs par défaut, et si certaines demandes les remplacent, il y aura un gâchis.
Je suis bien en retard à la fête, mais juste pour référence future si quelqu'un cherche une solution au même problème, voici mon coup, inspiré et largement identique aux réponses précédentes, mais plus complet
// 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);
Voici ce que j'utilise actuellement pour y parvenir.
$.xhrPool = [];
$.xhrPool.abortAll = function() {
_.each(this, function(jqXHR) {
jqXHR.abort();
});
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR);
}
});
Remarque: _.chaque des underscore.js est présent, mais évidemment pas nécessaire. Je suis juste paresseux et je ne veux pas le changer en $ .each (). 8P
aboutAll
devrait supprimer les éléments du tableau. De plus, lorsqu'une demande est terminée, elle doit se retirer de la liste.
Donnez à chaque requête xhr un identifiant unique et stockez la référence d'objet dans un objet avant de l'envoyer. Supprimez la référence une fois la demande xhr terminée.
Pour annuler toute demande à tout moment:
$.ajaxQ.abortAll();
Renvoie les identifiants uniques de la demande annulée. Uniquement à des fins de test.
Fonction de travail:
$.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;
}
};
})();
Renvoie un objet avec une fonction unique qui peut être utilisé pour ajouter plus de fonctionnalités si nécessaire.
Je l'ai trouvé trop facile pour plusieurs demandes.
étape1: définir une variable en haut de page:
xhrPool = []; // no need to use **var**
step2: définir beforeSend dans toutes les requêtes ajax:
$.ajax({
...
beforeSend: function (jqXHR, settings) {
xhrPool.push(jqXHR);
},
...
étape 3: utilisez-la partout où vous en avez besoin:
$.each(xhrPool, function(idx, jqXHR) {
jqXHR.abort();
});
J'ai étendu la réponse mkmurray et SpYk3HH ci-dessus afin que xhrPool.abortAll puisse abandonner toutes les demandes en attente d'une URL donnée :
$.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;
});
L'utilisation est la même, sauf que abortAll peut désormais éventuellement accepter une URL comme paramètre et n'annulera que les appels en attente vers cette URL
J'ai eu quelques problèmes avec le code d'Andy, mais cela m'a donné de bonnes idées. Le premier problème était que nous devrions supprimer tous les objets jqXHR qui se terminent avec succès. J'ai également dû modifier la fonction abortAll. Voici mon code de travail final:
$.xhrPool = [];
$.xhrPool.abortAll = function() {
$(this).each(function(idx, jqXHR) {
jqXHR.abort();
});
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR);
}
});
$(document).ajaxComplete(function() {
$.xhrPool.pop();
});
Je n'aimais pas la façon de faire les choses ajaxComplete (). Peu importe comment j'ai essayé de configurer .ajaxSetup, cela n'a pas fonctionné.
J'ai mis à jour le code pour le faire fonctionner pour moi
$.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);
}
}
});
Jeter mon chapeau. Offres abort
et remove
méthodes contre le xhrPool
tableau, et n'est pas sujet à des problèmes avec des ajaxSetup
remplacements.
/**
* 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);
});
Faites un pool de toutes les demandes ajax et annulez-les .....
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++]);
}
};
Mieux vaut utiliser du code indépendant .....
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++]);
}
};
Tout aussi important: dites que vous voulez vous déconnecter et que vous générez de nouvelles requêtes avec des minuteries: parce que les données de session sont renouvelées à chaque nouveau bootstrap (peut-être pouvez-vous dire que je parle de Drupal, mais cela pourrait être n'importe quel site qui utilise des sessions). J'ai dû parcourir tous mes scripts avec une recherche et un remplacement, car j'avais une tonne de choses en cours d'exécution dans différents cas: variables globales en haut:
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');
}
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));
chaque fois que vous voulez abandonner toute la demande ajax, il vous suffit d'appeler cette ligne
Request.AbortAll()
Il existe une solution factice, je l'utilise pour abandonner toutes les demandes ajax. Cette solution consiste à recharger toute la page. Cette solution est bonne si vous n'aimez pas attribuer un ID à chaque demande ajax et si vous faites des demandes ajax à l'intérieur de for-loop. Cela garantira que toutes les demandes ajax sont supprimées.
location.reload();
Voici comment connecter cela à n'importe quel clic (utile si votre page passe de nombreux appels AJAX et que vous essayez de vous éloigner).
$ ->
$.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()