Nous allons voir dans ce cours comment envoyer et recevoir des données avec le protocole HTTP à l’aide de JavaScript.

1 - Synchrone ou Asynchrone ?

Voilà le dilemme ? Mais essayons tout d’abord de comprendre ces termes.

1.1 - Synchrone

Une requête synchrone va bloquer le déroulement de l’exécution du code jusqu’à l’obtention d’un code de réponse de la part du serveur et ce quelque soit le résultat de la requête; succès ou échec.

1.2 - Asynchrone

Lors d’une requête asynchrone, l’application continuera de d’exécuter votre code. Des écouteurs seront mis en place afin de détecter un changement d’état de la requête et d’agir en conséquence, comme par exemple exécuter une fonction particulière si la requête est terminée ou si cette dernière a échoué.

2 - L’objet XMLHttpRequest()

2.1 - Instancier XMLHttpRequest

Pour réaliser une requête HTTP, nous devons tout d’abord instancier l’objet XMLHttpRequest
const req = new XMLHttpRequest();
Jusqu’à là, ça va ? Alors continuons...

2.2 - Ouvrir la requête

Nous allons utiliser la méthode open() de XMLHttpRequest afin de définir la méthode et l’url de notre requête.
 req.open('GET', 'http://www.neore.fr/mon_fichier.txt', false);
La méthode accepte 5 arguments dont les 2 premiers sont impératifs :
  1. Le type de méthode : GET, POST, PUT, DELETE, etc
  2. L’url : l’adresse absolue du fichier concerné.
  3. async : (true ou false) afin de préciser si la requête est asynchrone ou non, elle l’est pas défaut.
  4. user : Lors d’une connexion nécessitant une authentification, nous pouvons préciser le nom de l’utilisateur
  5. password : Lors d’une connexion nécessitant une authentification, nous pouvons préciser le mot de passe

2.3 - Executer la requête

Tout est prêt, nous pouvons maintenant envoyer notre requête grâce à la méthode send()
req.send(null);
Mais Laurent, pourquoi on met null en argument de cette méthode ?
En voilà une bonne question ! Et bien XMLHttpRequest peut tout autant recevoir que envoyer des données. Lors de l’envoi de données, avec la méthode POST par exemple, nous passerons les données envoyées en argument de la méthode send().
Dans le cas présent, nous n’envoyons aucune donnée, donc nous indiquons simplement null.

3 - Traitement du résultat d’une requête

3.1 - Les propriétés importantes de XMLHttpRequest

3.3.1 - XMLHttpRequest.status

La propriété status contient le code de réponse du serveur Http correspondant à la requête que nous avons formulé. Nous pouvons noter quelques codes importants :
  • 200 : Tout va bien, requête OK
  • 404 : Le fichier demandé n’existe pas... un classique.
  • 500 : Erreur d’execution du serveur.. un classique lors d’un problème d’execution de script Php par exemple
C’est cette propriété que nous interrogerons afin de connaitre l'état de notre requête.

3.3.2 - XMLHttpRequest.statusText

La propriété statusText contient une chaîne de caractères retournée par le serveur pour nous expliquer un peu mieux le code de résultat. Cette chaîne peut contenir des informations pertinentes pour débugger.

3.3.3 - XMLHttpRequest.responseText

La propriété responseText contient le contenu de la réponse du serveur sous la forme d'une chaîne de caractères.

3.2 - Testons le résultat de notre requête

Notre requête est envoyée et nous attendons donc le résultat...(rappelez vous, nous avons initialisé une requête synchrone).
Une fois le résultat de la requête reçu nous pouvons tester le status de celle-ci et, si tout va bien, récupérer le contenu de la requête.

if (req.status === 200) {
    // Yeah ! Super, nous avons un code de réponse OK
    // Voyons le contenu de la réponse dans la console :
    console.log(req.responseText);

} else {
    // Crénom d’un vieux mérou, y’a une .ouille dans le potage !
    // Nous n’avons pas eu un code de réponse OK, mais un autre...
    // Voyons ça dans la console
    console.log("Code de réponse :", req.status);

    // Avec un peu plus d’info :
    console.log("Code de réponse :", req.statusText);
}
Nous vérifions donc que req.status est bien égal à 200. Dans le cas contraire, nous affichons le code de résultat et un peu plus d'info dans la console.

4 - Création d'une requête asynchrone

4.1 - Instancier XMLHttpRequest

const req = new XMLHttpRequest();
Vous voilà en terrain connu maintenant. Bravo !

4.2 - Préparons le terrain avec quelques fonctions sympathiques

4.2.1 - Traiter la progression de la requête : XMLHttpRequest.onprogress()

Nous allons créer une fonction qui affichera la progression de téléchargement de notre requête.

function maProgression(event) {

    // L'argument event va contenir deux propriétés intéressantes :
    // event.loaded : nous indique la quantité de d'octets téléchargés.
    // event.total : la quantité d'octets totale attendue.
    // Nous affichons ça dans la console.
    // MAIS, MAIS, MAIS !!! Au préalable nous allons vérifier que des données
    // existent sinon nous aurons une belle erreur d'execution.

    if (event.lengthComputable) {
        console.log("Données totales : ", event.total);
        console.log("Données reçues : ", event.loaded);
    } else {
        console.log("Pas de données calculables");
    }
}

req.onprogress = maProgression;// Ceci n'est pas un appel direct de la fonction mais bien une référence à la fonction à appeler quand l'événement se produira

4.2.2 - Traiter une erreur de la requête : XMLHttpRequest.onerror()

Nous allons créer une fonction qui affichera le pourquoi d'une erreur en cas d'erreur.

function monErreur(event) {
    // Cette fonction sera appellée uniquement en cas d'erreur de la requête.
    // Il nous suffit d'indiquer l'erreur dans la console pour en savoir plus.
    console.error("Erreur", event.target.status);
}

req.onerror = monErreur; // Ceci n'est pas un appel direct de la fonction mais bien une référence à la fonction à appeler quand l'événement se produira

4.2.3 - Traiter le changement de statut de la requête : XMLHttpRequest.onload()

Nous allons créer une fonction qui sera executée à chaque changement de statut de la requête. Si nous recevons le code 200, nous pourrons afficher le contenu de la réponse.

function enCours(event) {
    // On teste directement le status de notre instance de XMLHttpRequest
    if (this.status === 200) {
        // Tout baigne, voici le contenu de la réponse
        console.log("Contenu", this.responseText);
    } else {
        // On y est pas encore, voici le statut actuel
        console.log("Statut actuel", this.status, this.statusText);
    }
}

req.onload = enCours;// Ceci n'est pas un appel direct de la fonction mais bien une référence à la fonction à appeler quand l'événement se produira

4.3 - Ouvrir la requête asynchrone

 req.open('GET', 'http://www.neore.fr/mon_fichier.txt', true);
Nous avons donc défini le dernier argument à true afin de préciser que nous sommes bien en mode asynchrone.

4.4 - Lancement de la requête

 req.send(null);

- Laurent, pourquoi y'a null comme argument ?
- Ben mon p'tit Loulou fallait pas roupiller au début du cours, allez, tu relis le début, hop, hop, hop.

4.5 - Tester si la réponse est bien au format json avec l'objet JSON et la méthode parse

try {
  JSON.parse('{}');              // {}
  JSON.parse('true');            // true
  JSON.parse('"toto"');          // "toto"
  JSON.parse('[1, 5, "false"]'); // [1, 5, "false"]
  JSON.parse('null');            // null
} catch (e) {
  console.error("Parsing error:", e); 
}

cf méthode parse

Exercices pratiques

Exercice 1 : Afficher le contenu d'une réponse dans un conteneur html

Objectif : Vous devez traiter XMLHttpRequest.responseText afin de remplir un conteneur div ayant pour id "ma_div".
Pour cela, vous devrez :
  • Créer une div avec l'id demandé dans votre code HTML.
  • Instancier XMLHttpRequest
  • Créer une requête GET pour l'url : http://www.neore.fr/mon_fichier.txt
  • Tester le code de retour de la requête
  • Traiter le contenu de la réponse
  • Définir le contenu de votre div avec le contenu de la réponse

Exercice 2 : Envoyer des données et traiter la réponse

Objectif : Vous devrez envoyer des données avec la méthode POST et traiter XMLHttpRequest.responseText afin de remplir un conteneur div ayant pour id "ma_div2".
Pour cela, vous devrez :
  • Créer une div avec l'id demandé dans votre code HTML.
  • Instancier XMLHttpRequest
  • Créer une requête POST pour l'url : http://www.neore.fr/coucou.php
  • Envoyer les données nom=votre_prenom (remplacer votre_prenom par votre vrai prénom
  • Tester le code de retour de la requête
  • Traiter le contenu de la réponse
  • Définir le contenu de votre div avec le contenu de la réponse