web-dev-qa-db-fra.com

Demandes ajax bloquées et en attente par JQuery dans Chrome

De temps en temps, mes appels Ajax (via JQuery 1.8) dans mon application sont bloqués avec le statut "en attente" pendant une longue période (parfois jusqu'à 17 minutes). Je l'ai googlé et toutes les solutions possibles n'ont pas fonctionné:

  1. Je n'ai aucun bloqueur de publicité installé.
  2. J'ai désactivé l'indicateur "Prédire les actions du réseau pour améliorer les performances de chargement des pages" dans Chrome.
  3. J'ai également ajouté une chaîne de requête à l'appel Ajax pour le rendre unique (pour désactiver le verrouillage du cache Chrome)).

Avez-vous une idée de comment résoudre ce problème? Merci.

Dans l'exemple ci-dessous, la demande a été en attente pendant 17 minutes (vérifié auprès de Fiddler qu'elle n'a été envoyée qu'après 17 minutes).

   GET http://www.mywebsite.com/foo/rest/publishers/1/packages?_=1421584749323    HTTP/1.1
   Host: www.mywebsite.com
   Connection: keep-alive
   Accept: application/json, text/javascript, */*; q=0.01
   X-Requested-With: XMLHttpRequest
   User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36    (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36
   Content-Type: application/json
   Referer: http://www.mywebsite.com/foo/client/home
   Accept-Encoding: gzip, deflate, sdch
   Accept-Language: en-US,en;q=0.8,he;q=0.6,ru;q=0.4
   Cookie: JSESSIONID=C668509B5AFCDEBE9C9774C4721AFB9D;
   aaassz="ddss"

Voir l'image: https://drive.google.com/file/d/0B9uQiZLJG1csNzlPcHZEWHl1Z2c/view

22
Wasafa1

J'ai trébuché sur exactement le même problème. Dès que j'ai désactivé:

Utilisez un service de prédiction pour charger les pages plus rapidement

Allez Paramètres avancés -> Confidentialité -> 3e case à cocher, tout a commencé à fonctionner comme il se doit. Je n'ai pas pu reproduire l'erreur.

Le jquery/ajax poller fonctionne parfaitement dans Firefox. C'est seulement Chrome - testé sur Linux et Windows.

Ce n'est pas une solution parfaite, car elle n'affectera pas les utilisateurs au sens global - mais peut-être que vous êtes dans la même situation que moi - un public limité.

7
michael

Je sais que c'est un vieux fil de discussion, mais je le poste pour les personnes qui se démènent pour trouver une sorte de réponse à cela. Je devais aussi faire face à ce gratte-tête. Mon problème était dû au bloqueur de publicités bloquant un appel d'API contenant le mot "coupon". Il bloquait la demande tout en la gardant en vie. après quelques blocs, chaque demande passait automatiquement au statut en attente car il y avait trop (je pense environ 6 ou 7) demandes en direct.

Tapez chrome: // net-internals/# events dans votre barre d'adresse chrome pour inspecter les demandes. Cela vous donnera un aperçu plus clair du problème. J'ai joint deux images que j'ai capturées pendant que j'étais essayer de comprendre cela.

capture d'écran du débogueur

capture d'écran net-interne

3
Bahram Ghahari

Vous pouvez essayer ça.

MAINTENANT MIS À JOUR AVEC LE CODE DE TRAVAIL RÉEL

(utilisé mon propre code de fuseau horaire, alors excusez les références au fuseau horaire)

Initialisez d'abord les tableaux et exécutez votre logique de comptage des demandes

var request = ( typeof request != 'undefined' && request instanceof Array ) ? request : [];
var pendingAjax = ( typeof pendingAjax != 'undefined' && pendingAjax instanceof Array ) ? pendingAjax : [];

Utilisez . AjaxStart et . AjaxStop pour garder une trace des demandes actives.

var ajaxActive = 0;
$( document ).ajaxStart(function() {
  ajaxActive++;
  document.ajaxQueueFull = ajaxActive > 5;
});
$(document).ajaxStop(function() {
  ajaxActive--;
  document.ajaxQueueFull = ajaxActive > 5;
}

Créez une fonction pour construire de nouvelles requêtes

    function ajaxRequestNew(t, u, d, s) {

        var instance = request.length + 1;
        request[instance] = $.ajax({
            method: t,
            url: u,
            data: {ajaxPost: d },
            success: s
        });
        return instance;
    }

Maintenant, créez votre demande en récupérant le numéro d'instance

    var instance = ajaxRequestNew('POST', 
                                  'js/ajax_timezone.php', 
                                  { ajaxAction : "ajaxGetTimezone", 
                                    tzoffset : "0", 
                                    tztimezone: "America/New_York" },
                                    function(data) {  }
    );

La fonction $ .ajax () renvoie un objet XMLHttpRequest. Nous utilisons donc une boucle while pour vérifier quand notre ajax est réellement envoyé et abandonner les autres requêtes actives si la requête est bloquée.

    while(request[instance] === null || (request[instance].readyState < 1 || request[instance].readyState > 4)) {
        if (document.ajaxQueueFull) {
            //abort existing requests
            $.each(request, function(i,v) {
                if (i !== instance) {
                    request[i].abort();
                }
            });
        }
    }

Poussez votre demande sur la pile

    pendingAjax.Push(request[instance]);

Créez des rappels pour votre demande

  var timezoneFailCallback = function(data) {
        console.log('fail');
        console.dir(data);
    };

    var timezoneSuccessCallback = function(data) {
        console.log('success');
        console.dir(data);
    };

utilisez quand appliquer les rappels

    $.when.apply($, pendingAjax).done( timezoneSuccessCallback ).fail( timezoneFailCallback);

Le code peut nécessiter un petit ajustement pour votre application, mais j'espère que vous avez l'idée. Faites moi savoir si vous avez des questions.

3
Tech Savant