redémarrage Ajax demande en fonction de l'objet XHR jquery après l'événement: navigator.onLine
Question
Nous lier des gestionnaires mondiaux ajax pour vérifier si le navigateur est allé en ligne:
$(document).ajaxSend(function(event, xhr, settings, response){
if(!navigator.onLine){
xhr.abort();
}
}
alors nous montrons une boîte de dialogue à l'utilisateur que le navigateur est allé en ligne et se lient pour l'événement « en ligne » pour cacher la boîte de dialogue lorsque les tours de navigateur en ligne à nouveau.
Y at-il de toute façon (même un hacky) pour redémarrer la demande Ajax basée sur l'ancien qui se inscrit dans l'ancien contexte?
La solution
Voici la plus propre approche que je peux penser à:
- Une file d'attente pour la mise en cache des paramètres de requête AJAX de sorte que chaque appel ultérieur ne remplace pas le précédent
-
A conditionnel dans le gestionnaire d'
ajaxSend()
que soit repousse les appels sur la file d'attente pour plus tard ou exécute la totalité de la file d'attente.!(function($, window, undefined){ var ajaxRequestQueue = [], // queue for requests that were made while offline isProcessingQueue = false; function processRequestQueue() { if (isProcessingQueue === true) { return; } isProcessingQueue = true; while (settings = ajaxRequestQueue.shift()) { $.ajax(settings); } isProcessingQueue = false; } $(document).ajaxSend(function(event, xhr, settings, response){ if (!navigator.onLine) { // abort the original request xhr.abort(); // push a copy of the request's settings on the queue ajaxRequestQueue.push($.extend(true, {}, settings)); } else if (ajaxRequestQueue.length > 0 && isProcessingQueue === false) // there are calls on queue and we haven't triggered 'ajaxSend' ourselves { processRequestQueue(); } }); // Bind to start processing the queue when the browser comes back online window.addEventListener("online", processRequestQueue); })(jQuery, window)
Autres conseils
Eh bien, vous pourrait cloner l'objet en utilisant jQuery et puis redémarrez votre appel lorsque le navigateur retourne en ligne
// Deep copy
var savedXhr= jQuery.extend(true, {}, xhr);
ne sais pas si cela fonctionne vraiment, vous pouvez essayer
EDIT - Ok je l'ai essayé et aucun moyen, vous ne pouvez pas appeler send () sur cet objet. En effet, xhr
n'est pas la demande initiale, mais un objet « faux » créé par jQuery
Une autre approche pourrait être celle-ci: vous enregistrez les paramètres objet et vous lancer un autre appel .ajax $ avec
ces paramètres.
Fondamentalement, vous faites
var settingsSaved;
$(document).ajaxSend(function(event, xhr, settings, response) {
if (!navigator.onLine) {
settingsSaved = jQuery.extend(true, {}, settings);
xhr.abort();
} else {
//Send the request with the old settings
$.ajax(settingsSaved);
//abort the new request
xhr.abort();
}
}
Soyez très prudent que ce requre un contrôle précis du débit parce que chaque fois que vous appelez $ .ajax vous déclenchez un autre événement ajaxSend
... peut-être vous pourriez tout simplement commencer une nouvelle XMLHTTPRequest
en utilisant les valeurs de l'objet settingsSaved
.
Regardez ce violon, la première fois que vous cliquez sur un bouton, l'appel est interrompu. La deuxième fois l'appel commence par les anciens paramètres et à partir de là toutes les demandes sont normales