IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

AJAX Discussion :

XHR - Recuperer au fur et a mesure les donnees.


Sujet :

AJAX

  1. #1
    Membre à l'essai
    Homme Profil pro
    Katowice
    Inscrit en
    Octobre 2015
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : Pologne

    Informations professionnelles :
    Activité : Katowice

    Informations forums :
    Inscription : Octobre 2015
    Messages : 17
    Points : 13
    Points
    13
    Par défaut XHR - Recuperer au fur et a mesure les donnees.
    Bonjour,

    j'aimerai lancer a partir d'une page via un bouton un script PHP qui renvoi au fur et a mesure des données.
    L'idee est qu'au moment du lancement du script, un loader s'affiche sur la page, et que en dessous les details de l'avancement du script s'affiche.

    Pour illustrer, le script PHP serait sous ce format :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    <?php
     
    // TEST QUI RENVOI "OK" OU "KO"
    if($test == "OK"){
        echo 'Le test est ok';
    }else{
        echo "Le test est KO, merci d'attendre un moment le temps des actions";
     
        //Action cote serveur qui peuvent prendre un certain temps
        //NOUVEAU TEST
        if($test == "OK"){
               echo 'Le test est ok apres les actions blablabla';
        }else{
               echo 'Le test est toujours KO apres les actions blablabla';
        }
    }
    echo "Ici le resultat final";
     
    ?>
    L'idee est de recuperer le retour et l'afficher au fur et a mesure, donc si le test est KO, le premier message 'Le test est KO, merci d'attendre un moment le temps des actions' va s'afficher, et le script va continuer, et eventuellement afficher en fonction de son déroulement d'autres infos (en gros donner un visuel a l'user en direct de l'avancement).
    Pour afficher un loader et recuperer les infos finales c'est OK, mais je coince sur comment récupérer au fur et a mesure les infos et les afficher.

    Desole si cela vous parait simple, j'ai naturellement chercher avec de poster ce message - mais ca reste assez complexe pour moi..
    Merci d'avance !

    Cordialement

  2. #2
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Tu as quoi comme code côté client actuellement ?

    Je ne sais pas si j’ai bien compris ton besoin, mais je pense que progress peut t’intéresser.

    Hors sujet : j’ai jamais compris pourquoi les gens utilisent « KO » pour le contraire de « OK ». C’est tellement facile de faire une faute de frappe, ou de confondre à la relecture…
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  3. #3
    Expert éminent sénior
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 234
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 234
    Points : 15 531
    Points
    15 531
    Par défaut
    pour faire cela, il y aura 2 scripts PHP
    - le 1er s'occupera du traitement qui prend du temps et enregistrera régulièrement la donnée qui indique l'avancement.
    - le 2e script est appelé par AJAX, il lit la donnée et la retourne au code JavaScript qui l'affiche.

  4. #4
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 739
    Points
    4 739
    Par défaut
    J'ai codé un truc comme ça, il y a bien longtemps

    L'idée était de lister un répertoire de photos-vignettes distant (sur le serveur), mais ces derniers pouvaient approcher le demi millier d'éléments.
    Donc hors de question d'afficher tout ça en une seule requête Ajax.
    Ca affichait aussi les éventuels sous-dossiers contenant eux aussi des vignettes de photo.

    Et il suffisait alors de double-cliquer sur l'un de ces sous dossiers pour le lister en lieu et place de l'affichage en cours.

    Bref, d'un coté on a du code PHP qui renvoie une portion d'information - disons sur une douzaine de fichiers - dont les arguments sont = nom du répertoire + référence sur la "tranche d'éléments" t de la série à fournir + Code de transaction.

    et sa renvoie le même code de transaction, plus une référence de la tranche suivante, si le répertoire n'est pas entièrement couvert.


    Coté Javascript on a bien sur une boucle d'appel AJAX vers les info du PHP, ,
    Le code de transaction est une référence fournie coté Javascript pour identifier les infos d'un même répertoire.

    Si l'utilisateur "clique" sur un dossier alors que l'affichage de toutes les vignettes n'est pas achevée, alors coté javascript on génère une nouvelle référence de transaction, ce qui fait que les retours avec une ancienne référence ne sont pas affichées...


    La grosse difficulté dans ce beans c'est qu'on doit gérer de envois et retours ajax en pagaille, et qu'il faut tout afficher proprement dans le bon ordre.

    L'utilisation du callBack sur le success ajax est aussi à proscrire, j'ai essayé, et bien sur ça plante parce qu'avec une centaine d'appels récursifs à la suite on déborde la stack du navigateur (à l'époque) et de toutes fçons je trouve cela horrible de coder ainsi.
    Ma première idée à été d'utiliser la fonction setTimeout pour réaliser une fausse récursivité, sans remplir la stack, Globalement ça marche, mais dans un cas sur 100 on se retrouve avec un truc aberrant en retour et qui reste un mystère.
    Donc la seule solution propre est d'n passer par les promesses JavaScript, et ça été coton à coder parce que c'était un première pour moi à l'époque
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  5. #5
    Membre à l'essai
    Homme Profil pro
    Katowice
    Inscrit en
    Octobre 2015
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : Pologne

    Informations professionnelles :
    Activité : Katowice

    Informations forums :
    Inscription : Octobre 2015
    Messages : 17
    Points : 13
    Points
    13
    Par défaut
    Hello,
    énorme merci pour vos réponses !
    @Watilin, merci pour la piste, je commence a etudier le truc pour voir si ca correspond a ce que je veux faire. Et ah, tu as totalement raison pour le "OK/KO", je vais le proscrire ^
    @mathieu, justement, c'est sur ce deuxieme script que je coince - car comment faire pour l'appeler plusieurs fois sans recharger la page affichee et mettre a jour sur cette meme page les infos MAJ dans le script de traitement ?

    @psychadelic, woa .. ca semble bien trop complique pour moi !!! En tout cas avec mon niveau actuel ca me parrait impossible a faire de mon cote =/

    Merci encore pour vos réponses - je mettrai a jour avec mon avancée sur le sujet.

  6. #6
    Membre à l'essai
    Homme Profil pro
    Katowice
    Inscrit en
    Octobre 2015
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : Pologne

    Informations professionnelles :
    Activité : Katowice

    Informations forums :
    Inscription : Octobre 2015
    Messages : 17
    Points : 13
    Points
    13
    Par défaut
    Pour progress, je pense pas que cela corresponde a ce que j'essaye de faire.

    Script php cote serveur (en vulgarisant les actions) :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    <?php
            $ch = curl_init('<url_a_controler>');
            curl_setopt($ch, CURLOPT_HEADER, 0); // 
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 
            curl_exec($ch);
            $info = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            if($info == 200){
                $retour = "L'application est bien accessible";
            }else{
                $retour = "Acces a l'application KO lors du premier test - relance du service";
                shell_exec('<relance_de_lappli>');
                sleep(20);
                    $ch = curl_init('<url_a_controler>');
                    curl_setopt($ch, CURLOPT_HEADER, 0); 
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
                    curl_exec($ch);
                    $info = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                    if($info == 200){
                        $retour .= "<br>Acces a l'application OK apres le relance du service";
                    }else{
                        $retour .= "<br>Acces a l'application KO apres la relance du service et une attente de 20 secondes <br> Arret de l'application.<br>";
                        shell_exec('<arret_du_service>"');
                        shell_exec('<demarrage_du_service>');
                        sleep(20);
                        $ch = curl_init('<url_a_controler>');
                        curl_setopt($ch, CURLOPT_HEADER, 0); 
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
                        curl_exec($ch);
                        $info = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                        if($info == 200){
                            $retour .= "<br>Acces a l'application OK apres l'arret puis la relance du service";
                        }else{
                            $retour .= "<br>Acces a l'application KO apres l'arret puis la relance du service et une attente de 20 secondes";
                        }
                    }
            }
    ?>

    C'est vrai que c'est plus concret avec l'exemple, du coup ce que je voudrais c'est afficher au moment du lancement du controle, un loader avec une MAJ des infos au fur et a mesure que le controle se poursuit.


    Cordialement

  7. #7
    Expert éminent sénior
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 234
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 234
    Points : 15 531
    Points
    15 531
    Par défaut
    Citation Envoyé par Akihisa. Voir le message
    @mathieu, justement, c'est sur ce deuxieme script que je coince - car comment faire pour l'appeler plusieurs fois sans recharger la page affichee et mettre a jour sur cette meme page les infos MAJ dans le script de traitement ?
    c'est pour faire cela que vous allez utiliser un appel AJAX :
    https://ajax.developpez.com/cours/

  8. #8
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Re après quelques jours,
    j’avais dans l’idée que les server-sent events pouvaient répondre à ton problème, mais je n’avais encore jamais utilisé cette techno, alors j’ai pris le temps de me documenter. Au final, me voici avec un exemple complet.
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    <!DOCTYPE html>
    <html lang="fr">
    <head>
      <meta charset="utf-8" />
      <title>Test avec les server-sent events</title>
      <style>
     
      body {
        margin: 1rem;
        font: 16px sans-serif;
      }
     
      #support.yes { color: green; }
      #support.yes::before { content: '\2713\00a0'; }
     
      #support.no { color: red; }
      #support.no::before { content: '\2715\00a0'; }
     
      button {
        font: inherit;
        color:  #44a;
        border: #44a solid 2px;
        background: #eef;
        padding: 0.5ex 1em;
        box-shadow: 0 1px 3px #999;
        cursor: pointer;
      }
     
      button:active, button:focus {
        color:        #28f;
        border-color: #28f;
        background: white;
      }
     
      button:disabled {
        color:        #88b;
        border-color: #88b;
        cursor: default;
      }
     
      kbd {
        color:  #444;
        border: #444 solid thin;
        background: #eee;
        padding: 0 0.5ex;
        border-radius: 4px;
      }
     
      </style>
    </head>
    <body>
     
    <p>
      Support de <code>EventSource</code> dans ce navigateur&#x202F;:
      <strong id="support"></strong>
    </p>
     
    <button type="button" disabled> Ouvrir une connexion </button>
     
    <p>Note&#x202f;: pensez à ouvrir la console avec <kbd>F12</kbd>.</p>
     
    <script> "use strict";
     
    const EVENT_SOURCE_URL = "./event-source.php";
     
    const $button = document.querySelector("button");
    const $support = document.querySelector("#support");
     
    if ("EventSource" in window) {
      let evSource = null;
     
      $support.textContent = "oui";
      $support.classList.add("yes");
      $button.disabled = false;
     
      let closeEventSource = () => {
        if (evSource) {
          evSource.close();
          evSource = null;
          $button.textContent = "Ouvrir une connexion";
        }
      };
     
      $button.addEventListener("click", () => {
        if (!evSource) {
          evSource = new EventSource(EVENT_SOURCE_URL);
          console.log("*** connexion ouverte");
     
          evSource.addEventListener("message", (event) => {
            console.log('[message]', event.data);
          });
     
          evSource.addEventListener("end-of-stream", () => {
            console.log("*** fin du flux");
            closeEventSource();
          });
     
          evSource.addEventListener("error", () => {
            console.warn("*** erreur");
            closeEventSource();
          });
     
          $button.textContent = "Fermer la connexion";
        }
        else {
          console.log("*** connexion interrompue sur demande");
          closeEventSource();
        }
      });
    }
    else {
      $support.textContent = "non";
      $support.classList.add("no");
    }
     
    </script>
    </body>
    </html>

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    <?php
    // envoie les en-têtes HTTP
    header('Cache-Control: no-cache');
    header('Content-Type: text/event-stream');
     
    // force les messages à être envoyés immédiatement
    ob_end_clean();
    ob_implicit_flush();
     
    $ch = curl_init('<url_a_controler>');
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_exec($ch);
     
    $info = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    if (200 === $info) {
        // attention les guillemets doubles (") sont obligatoires pour traiter correctement les "\n"
        echo "data:L’application est bien accessible\n\n";
    }
    else {
        echo "data:Accès à l’application ÉCHEC lors du premier test\n";
        echo "data:- relance du service\n\n";
     
        shell_exec('<relance_de_lappli>');
        sleep(20);
     
        $ch = curl_init('<url_a_controler>');
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_exec($ch);
        $info = curl_getinfo($ch, CURLINFO_HTTP_CODE);
     
        if (200 === $info) {
            echo "data:Accès à l'application OK après le relance du service";
        }
        else {
            echo "data:Accès à l’application ÉCHEC après la relance du service et une attente de 20 secondes.\n";
            echo "data:Arrêt de l’application.\n\n";
     
            shell_exec('<Arrêt_du_service>');
            shell_exec('<demarrage_du_service>');
            sleep(20);
     
            $ch = curl_init('<url_a_controler>');
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_exec($ch);
            $info = curl_getinfo($ch, CURLINFO_HTTP_CODE);
     
            if (200 === $info) {
                echo "data:Accès à l’application OK après l’arrêt puis la relance du service\n\n";
            }
            else {
                echo "data:Accès à l’application ÉCHEC après l’arrêt puis la relance du service et une attente de 20 secondes.\n\n";
            }
        }
    }
     
    echo "event:end-of-stream\n";
    echo "data:\n\n";

    Le point crucial à souligner ici, je pense, c’est que la connexion est relancée automatiquement en cas de rupture, ce qui inclut le cas où le code PHP arrive à la fin de son traitement. J’imagine que tu n’as pas envie qu’un script qui redémarre des applis et des services à toutes les sauces soit rappelé automatiquement sans te demander ton avis.

    Donc il ne faut pas oublier de gérer l’évènement error et de fermer explicitement la connexion. C’est ce que je fais dans mon script. Et pour que ça ait l’air un peu plus propre, j’ai ajouté un évènement end-of-stream que j’envoie moi-même à la main à la fin du script PHP.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  9. #9
    Membre à l'essai
    Homme Profil pro
    Katowice
    Inscrit en
    Octobre 2015
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : Pologne

    Informations professionnelles :
    Activité : Katowice

    Informations forums :
    Inscription : Octobre 2015
    Messages : 17
    Points : 13
    Points
    13
    Par défaut
    @Watilin, wow ...
    Je sais meme pas comment te remercier, ca a l'air de correspondre exactement a ce que je souhaite faire !
    Desole de pas avoir vu la possibilite a ton premier message, je manque encore de competences ..

    Je vais tester ca dans le weekend et faire un retour !
    Encore merci !!

Discussions similaires

  1. [JTable] recuperer les donnees
    Par clemouf dans le forum Composants
    Réponses: 3
    Dernier message: 08/02/2019, 15h44
  2. Effacer les sessions au fur et a mesure
    Par Sylvain245 dans le forum Langage
    Réponses: 2
    Dernier message: 10/09/2010, 14h45
  3. Réponses: 15
    Dernier message: 07/06/2009, 15h11
  4. Réponses: 6
    Dernier message: 09/07/2008, 17h20
  5. Macro pour ajouter les bordures au fur et a mesure
    Par Raiga dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 15/06/2007, 08h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo