begin process at 2012 05 30 05:06:29
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Javascript / DHTML / Ajax

 > 

JavaScript et le navigateur

 > 

Autre

 > 

synchroniser une requete ajax asynchrone


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

synchroniser une requete ajax asynchrone

mercredi 26 septembre 2007 à 15:37:49 | synchroniser une requete ajax asynchrone

AlexN

Bonjour,

Je cherche à synchroniser une requete ajax asynchrone. Et je prend une grosse suée.
Je fais appel de manière cyclique à une requete ajax en mode asynchrone.
mode cyclique parce que je relance la requete tant que la reponse ne contient pas ce qu'il faut.
mode asynchrone parce que c'est le seul mode ou abort est utilisable (et ou ça ne bloque pas le navigateur pendant les requetes)
Mais ! il faut aussi que je puisse stopper (abort) la requete si la réponse ne vient pas au bout d'un certain temps (timeout du cycle des requetes).

Je cherche à avoir une fonction du genre

while(!ready) {
   getDom(url);
}

où getDom(url) lance un cycle de requete ajax jusqu'à obtention de la reponse voulue ou que le timeout soit ecoulé.
De sorte que l'execution boucle (d'ou l'idee de synchroniser) sur ce getDom sans bloquer le reste. Suis-je clair ?

pour avoir une petite idée du contexte :

<html>
    <head>
        <title>is my datas ready ?</title>
    </head>
    <body>
        <input type="text" id="x1" size="40">
        <input type="text" id="y1" size="40">
        <input type="text" id="z1" size="40">
        <button type="button" onclick="abort()">stop</button>
        <script type="text/javascript">
       
            /* XMLHttpRequest */
            var xhr = false;
            var url = "test.xml";
            var ie = false;
           
            // branch for native XMLHttpRequest object
            if(window.XMLHttpRequest && !(window.ActiveXObject)) {
                try {
                    xhr = new XMLHttpRequest();
                } catch(e) {
                    xhr = false;
                }
            // branch for IE/Windows ActiveX version
            } else if (window.ActiveXObject) {
                try {
                    xhr = new ActiveXObject("Msxml2.XMLHTTP");
                    ie = true;
                } catch(e) {
                    try {
                        xhr = new ActiveXObject("Microsoft.XMLHTTP");
                        ie = true;
                    } catch(e) {
                        xhr = false;
                    }
                }
            }
                   
            received = false;
                               
            function getContents () {
                if(xhr.readyState == 4 && xhr.status == 200) {
                    response = xhr.responseXML;
                    if (response) {       
                        value = ie ?
                            response.getElementsByTagName("status")[0].text :
                            response.getElementsByTagName("status")[0].textContent;
                        document.getElementById("z1").value = value;
                        setTimeout("get()", 1000);
                    }
                }
            }
           
            function get () {
                if (xhr) {
                    xhr.open("GET", url, true);
                    xhr.send("");       
                }     
            }
           
            function abort() {
                xhr.abort();
                document.getElementById("z1").value='aborted';
            }
           
            xhr.onreadystatechange = getContents;
            var debut = new Date();                       
            get();
            fini = false;
           
            function f() {
                var now = new Date();
                document.getElementById("x1").value = now;
                var elapsed = now.getTime() - debut.getTime();
                document.getElementById("y1").value = elapsed;
                fini = elapsed > 5000;
                if (fini) abort();
                else setTimeout("f()", 100);
            }
            f();
           
        </script>
    </body>
</html>

le xml (en fait la il n'y a pas ok mais not ok mais un jour il y aura ok a la place):

<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
    <status>not ok</status>
</root>

si quelqu'un a une piste de reflexion, merci.
jeudi 27 septembre 2007 à 11:58:59 | Re : synchroniser une requete ajax asynchrone

bultez

Membre Club


Bonjour,

    je n'ai probablement pas compris ton problème...

    setTimeout("get();", 1000); est fait sytématiquement,
    ne le faire que si la réponse n'est pas ="ok" et si le délai
       imparti pour cette réponse n'est pas atteint,
    sinon, déclencher une "fonction de fin".



                Cordialement            Bul         [mon Site]     [M'écrire]

jeudi 27 septembre 2007 à 13:18:15 | Re : synchroniser une requete ajax asynchrone

AlexN

Merci pour ta suggestion bultez mais ce n'est pas ça.
En fait oui pour l'instant le setTimeout("get()", 1000); est fait systématiquement parce que c'est juste un code de test. Ce qui me précocupait ce n'était pas le contenu de la réponse. Le titre de ma question n'est pas clair non plus.
Un titre plus explicite serait plutôt : "Comment resynchroniser une requete ajax asynchrone"
et la fonction f() devrait s'appeler quelquechose comme check().

Pour l'instant ce que fait ce code :
- il lance à  intervalle régulier une requete ajax, et ce seulement quand la précédente est terminée (et il devrait aussi y avoir la condition sur "calcul fini" comme tu le fais remarquer)
- il lance "en parallèle" un compteur qui vérifie que le temps imparti n'est pas dépassé, et si celui est dépassé il stoppe la requete en cours.

Mais il ne permet pas de faire boucler temporairement l'execution sur cette portion de code

Je vais essayer d'expliquer mon problème. Je dois mettre en place un mécanisme qui :

- lance une requete ajax à intervalle régulier pour connaitre l'état d'avancement d'un calcul
- stoppe cette série de requête
  - soit lorsque la réponse contient un code disant "calcul fini"
  - soit lorsqu'un temps donné pour le cycle de requête est dépassé
- provoque un "blocage" (pas un arrêt complet mais plutôt une boucle d'attente) sur ce mécanisme (le reste du javascript ne peut pas être exécuté tant que la réponse "calcul fini" n'est pas arrivée ou que le delai d'attente de ce calcul n'est pas dépassé.

Le seul moyen pour l'instant de stopper une requete ajax est de la mettre en asynchrone.
Mais d'un autre coté, comme elle est asynchrone, le xhr.send devient non bloquant. Et la boucle d'attente n'est pas bloquante non plus.

En fouillant à droite à gauche je n'ai pas trouvé grand chose d'autre que "ca n'a pas l'air possible" à part avec des composants php (sajax) ou java (htmlunit), ce que je ne peux pas utiliser parce tout doit être réalisé du coté client.
En fait, après réflexion il semble que ce ne soit pas possible du tout. Je suis parti dans une autre direction qui serait de simuler le while par un système de timeline. Mais c'est pas gagné non plus.

Voici l'état du code quand j'ai dit stop, faut arreter :

<html>
  <head>
    <title>resync the async</title>
    <style type="text/css">
    <!--
    .label {
      vertical-align:top;
    }
    -->
    </style>
  </head>
  <body>
    <input type="text" id="x1" size="40"/>
    <input type="text" id="y1" size="40"/>
    <input type="text" id="z1" size="40"/>
    <input type="text" id="message" size="40"/>
    <br/>
    <label class="label" for="readyState">Ready state : </label><textarea type="text" id="readyState" size="40" rows="30"></textarea>
    <label class="label" for="status">status : </label><textarea type="text" id="status" size="40" rows="30"></textarea>
    <button class="label" type="button" onclick="abort()">stop xhr</button>
    <script type="text/javascript">
       
      /* XMLHttpRequest */
      var xhr = false;
      var ie = false;
                       
      // branch for native XMLHttpRequest object
      if (window.XMLHttpRequest && !(window.ActiveXObject)) {
        try {
          xhr = new XMLHttpRequest();
        } catch(e) {
          xhr = false;
        }
      // branch for IE/Windows ActiveX version
      } else if (window.ActiveXObject) {
        try {
          xhr = new ActiveXObject("Msxml2.XMLHTTP");
          ie = true;
        } catch(e) {
          try {
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
            ie = true;
          } catch(e) {
            xhr = false;
          }
        }
      }
     
      function getContents () {
        try {
          // Infos
          document.getElementById("readyState").value += "\n" + xhr.readyState;
          if (xhr.readyState == 4 && typeof xhr.status != 'undefined')                                 
            document.getElementById("status").value += "\n" + xhr.status;
          else                                  
            document.getElementById("status").value += "\n" + 'undefined';
          if (xhr.readyState == 4 && typeof xhr.status == 'undefined') return;
          // Contents
          if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
            response = xhr.responseXML;
            if (response) {                             
              document.getElementById("z1").value = (ie ?                        
                response.getElementsByTagName("status")[0].text :                         
                response.getElementsByTagName("status")[0].textContent) + " " + times++;
              getTimer = setTimeout("get(url)", 1000);
            }
          }
              } catch (e) {
                  if (typeof console != 'undefined') console.log(e);             
              }
      }
                       
      function get(url) {
              //try {
          if (xhr) {
            xhr.open("GET", url, true);
            xhr.send("");
          }            
              //} catch (e) {}
      }
     
      function abort() {
        if (xhr) {
          xhr.abort();
          document.getElementById("message").value = 'aborted';
        }
              if (checkTimer) clearTimeout(checkTimer);
              if (getTimer) clearTimeout(getTimer);
      }
                       
      function check() {
        var now = new Date();
        document.getElementById("x1").value = now;
        var elapsed = now.getTime() - start.getTime();
        document.getElementById("y1").value = elapsed;
        timeover = elapsed > 5000;
        if (timeover) abort();
        else checkTimer = setTimeout("check()", 100);
      }
     
      if (xhr) xhr.onreadystatechange = getContents;
      document.getElementById('readyState').value = "";
      document.getElementById('status').value = "";
           
      var start = new Date();
      var checkTimer, getTimer;
      var timeover = false;
      url = "test.xml";
      var send = false;
      var times = 1;
     
      function getStatus(url, send) {
           
        if (!send) {
          send = false;
          get(url);                               
          check();
        }
              /*
        if (!timeover) {
          if (xhr.readyState == 4) {
            send = true;
            getTimer = setTimeout("get(url)", 1000);   
                    return true;
          } else
                     checkTimer = setTimeout("getStatus(url, send)", 1000);
            return false;
        }
              */
      }
             
      //get(url);                               
      //check();
      getStatus(url, send);
      //while (!getStatus(url, send));
                       
    </script>
  </body>
</html>

Je jette l'éponge pour cette voie...
Enfin merci.
jeudi 27 novembre 2008 à 16:26:02 | Re : synchroniser une requete ajax asynchrone

mlwacosmos

Bonjour,
La question est ancienne mais je peux fournir une réponse et ça peut toujours aider.

Pour les puristes une requête ajax est forcément asynchrone et il est interdit de lancer des requêtes synchrones si bien qu'un navigateur comme firefox ne l'accepte pas facilement.
Néanmoins c'est possible en changer le paramètre true en false.
Sous ie pas de soucis, mais sous firefox il faudra recopier apres le request.send les différentes bifurcations que l'on fait habituellement quand on reçoit la réponse du serveur.

Un petit exemple pour firefox? ok

request.onreadystatechange = function () {
   if(request.readyState == 4) {
      if(request.status == 200) {
         //ce que je fais
      }
   }
}
request.send(null);
if(not ie et requete est synchrone(à savoir false pour le paramètre) {
   //ce que je fais
}
 Le problème avec firefox c'est que l'on ne vérifie pas le code de retour du serveur.



Cette discussion est classée dans : requete, var, false, xhr, if


Répondre à ce message

Sujets en rapport avec ce message

Problème onkeyup [ par Le grand Jisay ] Bonjour à tous !Voici quelques jours que je suis bloqué sur un problème concernant l'événement onkeyup. Tout se passe bien sous FireFox mais sous Inte probleme incompatibilité IE-FF svp HELP !! [ par ju0123456789 ] Bonjour, depuis plusieurs jours, je mesuis pris la tête pour mon script de mon site web de commande en ligne, mais malheureusement il ne marche pas so intérompre une fonction... [ par davidcian ] Bonjour,Je cherche a stopper le déroulement d'une fonction lors d'une condition, j'ai testé avec return mais ça marche pas...Fonction principal:functi Problème de DIV [ par igregbzh ] Bonjour à tous voila j'effectue une petite application en javascript et la j'ai un gros problème. En fait j'arrive a déplacer et redimensionner les di jquery et ajax formulaires [ par Annadrill ] bonsoir, j'aimerais savoir comment je dois m'y prendre pour recréer un script du type de celui ci-dessous pour jquery, le systeme étant que les cha Gestion de touches F5, BACKSPACE et ENTER (javascript et jQuery) [ par elara1970 ] Bonjour, Je souhaiterais gérer certaines touches du clavier en javascript (et jQuery). Le code fonctionne bien sous IE mais pas trop avec FF. Cepend parser un xml [ par zeitoun69 ] Bonjour je dois parser un fichier xml et former un tableau a partir des données extraite j'ai réussi a former le tableau mais les données sont celles Formulaire Newsletter facebook FBML/FBJS [ par quinton75 ] Bonjour,[^^clinoeil1][^^clinoeil1] Je souhaite intégrer un formulaire d'inscription à ma Newsletter sur ma page facebook Mon code source HTML d'inté Intégrer du javascirpit sur facebook (FBML/FBJS) [ par quinton75 ] Hello,[^^clinoeil1][^^clinoeil1][^^clinoeil1] Petite question à pose. Je souhaite intégrer un formulaire d'inscription à ma Newsletter sur ma page FBJS : ou mettre le javascript étant dans <head> en html sans le head en fbjs ? [ par quinton75 ] [code=js] Webform var dtCh='/'; var minYear=1900; var maxYear=2100; function isValidInteger(s){ var i; for(i=


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 3,604 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales