Partage
  • Partager sur Facebook
  • Partager sur Twitter

Envoyez des données avec une requête POST

Sujet résolu
Anonyme
    4 avril 2020 à 20:01:44

    Bonjour,

    Je suis actuellement en train de voir le cours "Écrivez du JavaScript pour le web" et je bloque sur la partie où l'on doit envoyer une requête.

    En effet, je n'arrive pas à récupérer les données de postData.text comme c'est demandé dans l'exercice. Soit je n'ai aucun affichage au clic sur le bouton, soit un message me disant que postData.text n'existe pas.

    Voici mon code :

    index.html

    <html lang="fr">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" type="text/css" href="index.css">
        <title>POST</title>
    </head>
    <body>
    <form id="form">
        <label>Saisissez une valeur <input type="text" id="value" /></label><br />
        <input type="submit" value="Envoyer" />
    </form>
    <div id="result"></div>
    
    <script type="text/javascript" src="index.js"></script>
    </body>
    </html>
    
    
    

    index.js

    let result = document.getElementById('result');
    let form = document.getElementById('form');
    
    function send() {
        var request = new XMLHttpRequest();
    
        request.open('POST', 'https://mockbin.com/request', false);
        request.setRequestHeader('Content-Type', 'application/json');
        let json = JSON.stringify({value: document.getElementById("value").value});
        request.send(json);
        request.responseText.postData.text = json;
        result.innerHTML =  request.responseText.postData.text;
    }
    
    form.addEventListener('click', (event) => {
        send();
        event.preventDefault();
    });
    

    Le problème doit venir de la valeur que j'assigne à result.innerHTML.
    Si vous pouviez m'aider à comprendre ce qui cloche, ce serait cool !

    P.S : Je débute dans l’utilisation de Ajax, alors soyez indulgents :)


    -
    Edité par Anonyme 4 avril 2020 à 21:35:26

    • Partager sur Facebook
    • Partager sur Twitter
      4 avril 2020 à 20:23:19

      Ça tient du fait qu'une requête ajax est par défaut asynchrone, c'est à dire que le résultat te revient à un temps t postérieur à l'exécution de result.innerHTML. Ça revient à écrire un setTimeout si tu veux, donc tu n'as pas accès à responseText au moment où tu l'utilises (note que comme son nom l'indique responseText est du texte, donc il n'a pas de propriété postData. C'est la réponse brut du serveur sous forme de texte)

      Donc soit tu rends la requête synchrone en passant false en 3e argument à request.open, ce qui est un peu oldschool (ça va bloquer le navigateur jusqu'à ce que le serveur ait répondu), soit tu attends l'événement "load" de l'objet request avec addEventListener et tu écris ton result.innerHTML dans la fonction en argument de addEventListener.

      Pense à traiter aussi l'événement "error" et, dans l'événement "load", pense à traiter les cas ou request.status n'est pas compris entre 200 et 400 (exclu), c'est à dire les cas où la requête a réussi mais où le serveur rapporte une erreur (par exemple 404 page non trouvée ou 500 erreur interne). Tu peux aussi décider de rejeter les status 3xx si tu ne veux pas autoriser les redirections.

      Quand je dis "pense à traiter" je veux dire soit avertir l'utilisateur qu'il y a une erreur, soit réessayer, soit émettre un log dans la console d'erreurs, mais ne pas candidement supposer que la requête va fonctionner.

      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        4 avril 2020 à 21:00:03

        Merci de m'avoir répondu si rapidement !


        Pour la question de l'asynchronisme, j'ai bien vu en effet le temps que ça prenait quand j'ai testé auparavant avec la méthode GET :waw:


        Je n'ai pas traité les événements que tu as cité car je l'avais déjà fait pour la méthode GET donc je voulais aller plus vite dans cette partie + Open Classroom m'empêche d'envoyer mon message quand je rajoute ces conditions ! (Erreur de sécurité).


        Mais voici mon code avec les modifications :

        index.js

        let result = document.getElementById('result');
        let form = document.getElementById('form');
        
        function send() {
            const request = new XMLHttpRequest();
            request.open('POST', 'https://mockbin.com/request');
            request.setRequestHeader('Content-Type', 'application/json');
            request.send(JSON.stringify({value: document.getElementById("value").value}));
            result.innerHTML = request.responseText.postData.text;
        }
        
        form.addEventListener('click', (event) => {
            send();
            event.preventDefault();
        });
        

        Je dois attendre combien de temps environ avant de recevoir une réponse ?

        Pour savoir à partir de quand je dois m'inquiéter :D

        -
        Edité par Anonyme 4 avril 2020 à 21:33:20

        • Partager sur Facebook
        • Partager sur Twitter
          4 avril 2020 à 21:13:17

          Je ne vois pas de différence avec le précédent code.

          Concernant mockbin.com, je ne sais pas. Si c'est vraiment long, crée une page PHP par exemple et utilise ton serveur local pour faire des tests.

          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            4 avril 2020 à 21:18:52

            J'ai juste réduit le code de quelques lignes.

            À la base, j'avais rajouté les conditions adéquates mais Open Classroom m'empêchait d'envoyer le code.

            -
            Edité par Anonyme 4 avril 2020 à 21:31:54

            • Partager sur Facebook
            • Partager sur Twitter
              4 avril 2020 à 22:24:01

              Bonsoir.

              Si tu ne peux pas mettre le code modifié directement dans ton message, tu peux par exemple le mettre sur JsFiddle, sauvegarder et ajouter les lien vers celui-ci dans ton message.

              Ce qui nous permettra de voir si tu as fait une erreur ou non.

              • Partager sur Facebook
              • Partager sur Twitter

              Face a quelqu'un pour qui l'on n'éprouve que de l'aversion et du mépris, les yeux d'un homme deviennent extrêmement froids et cruels.

              Anonyme
                5 avril 2020 à 11:53:53

                Bonjour,

                Voici le lien de JSFiddle : https://jsfiddle.net/72fwpek3/

                -
                Edité par Anonyme 5 avril 2020 à 11:55:57

                • Partager sur Facebook
                • Partager sur Twitter
                  5 avril 2020 à 13:21:35

                  Ton événement readystatechange ne sera jamais lancé. ton open, setRequestHeaders et send doivent être à l'extérieur de l'événement.

                  Je recommande d'utiliser load et error plutôte que readystatechange.

                  Ta ligne 13 ne veut rien dire.

                  J'ai envie de te conseiller de laisser tomber XMLHTTPRequest pour l'instant et de continuer à apprendre Javascript et surtout à écrire du code pour t'entraîner, parce que là on sent que tu tâtonnes trop pour utiliser une interface compliquée.

                  Je peux te conseiller de regarder fetch, mais je ne sais pas si c'est une bonne idée de te lancer dans les promesses alors que tu as déjà du mal avec les callbacks.

                  Gagne de l'XP, pex sur des mobs de niveau 2 et tu retenteras le boss plus tard ;)

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Anonyme
                    5 avril 2020 à 13:46:51

                    Pour le coup, j'ai du mal à comprendre comment récupérer la valeur que l'on a envoyé grâce à la méthode POST et la mettre dans le result.innerHTML. Parce qu'on assigne directement notre objet JS (qui est transformé en texte avec stringify) dans la méthode send().

                    Je vais repasser au niveau précèdent pour mieux comprendre ce que j'ai loupé :lol:

                    -
                    Edité par Anonyme 5 avril 2020 à 14:20:51

                    • Partager sur Facebook
                    • Partager sur Twitter
                      5 avril 2020 à 14:27:25

                      Dans request.send tu envoies des données au serveur. Rien à voir avec ce que le serveur répond. Quand on utilise POST en général c'est pour envoyer un truc au serveur et le serveur se contente de répondre que l'opération a réussi ou échoué en donnant des détails le cas échéant.

                      La réponse du serveur est accessible exactement de la même façon qu'avec une requête GET, dans request.responseText (par exemple).

                      Ce qui est particulier avec XMLHTTPRequest c'est que les propriétés request.status, request.readyState ou request.responseText changent au cours du temps mais sont accessibles à tout moment, donc il faut y accéder au bon moment pour avoir la valeur que tu attends.

                      C'est assez différent de ce qui se passe avec fetch par exemple, ou de ce qui se passe avec une bibliothèque qui fournit une fonction ajax, get ou post (construite par dessus XMLHTTPRequest). En général ces bibliothèques écrivent la réponse serveur dans le paramètre de la fonction callback, par exemple get("mon.url?mes=params", function (response) {console.log("la réponse serveur :", response);})

                      XMLHTTPRequest est une interface verbeuse et donc difficile à utiliser quand on débute et qu'on doit intégrer en même temps le fait que des choses sont asynchrones, tout en s'habituant aux fonctions callback. Et en plus il faut gérer le statu HTTP. Ça fait beaucoup de préoccupations d'un coup.

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Anonyme
                        5 avril 2020 à 14:50:47

                        Oui, j'avoue que j'ai eu du mal en découvrant XMLHttpRequest().

                        J'ai bien compris que normalement quand on envoie des données avec la méthode POST, on attend juste une réponse nous indiquant si l'action s'est bien déroulée ou non.


                        Le truc c'est que dans l'exercice, il fallait aller chercher dans postData.text (qui se trouve dans le fichier json du lien indiqué) les données qu'on a envoyé.
                        Et je ne voyais pas comment afficher ces données distantes ensuite.

                        Au départ, postData.text est vide. L'exercice cherchait à nous montrer que notre envoi a fonctionné en nous faisant afficher les nouvelles données de postData.text.

                        -
                        Edité par Anonyme 5 avril 2020 à 14:51:28

                        • Partager sur Facebook
                        • Partager sur Twitter
                          5 avril 2020 à 15:17:24

                          Je ne suis pas tout à fait sûr de comprendre ce qui te bloque mais il y a clairement une ambiguïté doncje vais récapituler brièvement ce qui se passe.

                          Déjà, ce que tu envoies au serveur ne contient pas de propriété postData ou text.

                          En admettant que document.getElementById("value").value vaut 'bidul', techniquement tu envoies la chaîne "{value: 'bidul'}" (générée par JSON.stringify) au serveur.

                          Peut-être que le serveur te renvoie "{text: 'bidul'}", j'ai pas lu l'exercice, mais cette chaîne elle va se retrouver automatiquement dans request.responseText quand l'événement load sera lancé (ou readystatechange, mais uniquement la 4e fois, quand readyState vaut XMLHttpRequest.DONE). Tout ce que tu as à faire pour récupérer la réponse serveur c'est accéder à cette propriété au bon moment et la parser avec JSON.parse (si tu reçois bien du JSON)

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Anonyme
                            5 avril 2020 à 15:49:29

                            D'accord, merci.

                            Je ne pensais pas que la chaîne se retrouvait automatiquement dans request.responseText, c'est pour ça que je tentais plusieurs choses sans l'utiliser.

                            J'ai bien compris le fonctionnement maintenant ^^
                            • Partager sur Facebook
                            • Partager sur Twitter
                              5 avril 2020 à 17:28:47

                              Bonjour Quentin

                              Si je comprends tu cherche à envoyer une requête de type POST à un serveur par exemple de type PHP via AJAX, soit une méthode asynchrone.

                              Lors de l'envoie de la requête tu as crées un objet new XMLHttpRequest() qui tu as nommé request

                              Dans ce cas le code de ta fonction send() devrait plutôt être

                              function send(requete) {
                                  var request = new XMLHttpRequest();
                                  var allResponseHeaders = false;
                              	var server = false;
                              	var contentType = false; //force à false, même avec requete = null renvoi html si exécution correcte, même en abscence de echo dans pagePHP
                              
                              	request.onreadystatechange = function() { //pour débboggage uniquement
                              		if (request.readyState == 4 && (request.status == 200 || request.status == 0)) { //XMLHttpRequest.DONE; valeur 4; Toutes les données ont été réceptionnées.
                              			allResponseHeaders = request.getAllResponseHeaders(); //retourne toutes les caractéristiques
                              			server = request.getResponseHeader('Server'); //type du serveur
                              			contentType = request.getResponseHeader('Content-Type'); // xml; plain; html ... - type de response par le serveur
                              			/*Détermine si response est de type xml ou pas */
                              			if ( contentType.indexOf("xml") == -1)	callback(request.responseText); //pour mémoire si (indexOf == -1) => ne contient pas
                              			else	callback(request.responseXML); // request.responseXML ou request.responseText
                              		};
                              	};
                                  
                                  request.open('POST', 'https://mockbin.com/request', false);
                                  request.setRequestHeader('Content-Type', 'application/json');
                                  request.send(requete);
                              };

                              Tu noteras que ce code introduit une fonction appelée callback, peu importe son nom en vérité; cette fonction javascript que tu devras écrire attends la réponse du serveur interrogé.

                              Le serveur doit donc traiter la réception de cette requête,

                              • c'est à dire transformer en variable PHP si serveur PHP, les données de la requête.
                              • Ensuite il traite les dites variables
                              • et enfin retourne le résultat, en PHP le retour du résultat s'obtient en écrivant sur la page PHP via la méthode echo

                              C'est au moment au le serveur retourne le résultat (méthode echo en PHP) que ta page javascript reçoit readyState=4 et status= 200 pour ton objet request et peu alors appelé la fonction callback qui reçoit en paramètre ce que le serveur PHP a écrit.

                              Cordialement

                              • Partager sur Facebook
                              • Partager sur Twitter
                              Anonyme
                                5 avril 2020 à 18:21:05

                                Merci pour ta réponse plus que complète claudebriard ! :)
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  10 août 2020 à 15:13:37

                                  Bonjour à tous,

                                  Moi aussi j'ai pas mal galéré pour finir cet exercice, mais en m'inspirant de ce post je pense y avoir réussi.

                                  Je vous laisse le lien avec l'énoncé de l'exercice et un CodePen avec la solution que j'ai trouvé.

                                  N'hésitez pas à me faire des commentaires si vous pensez que c'est pas ça du tout où s'il y a une meilleure façon de faire.

                                  Merci d'avance! 

                                  -
                                  Edité par JavierBarrón 12 décembre 2020 à 23:03:00

                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  Javier Barrón

                                  www.mediadatos.com

                                    12 décembre 2020 à 20:48:36 - Message modéré pour le motif suivant : Merci d'utiliser le bouton code du forum pour insérer votre code


                                    Envoyez des données avec une requête POST

                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                    • Editeur
                                    • Markdown