Heritiana Antonio Frond end Designer | Developer

Hello, I am

Heritiana Antonio

Frond end Designer | Developer

Chapitre 7 : Fetch et JSON

1 min de lecture

Chapitre 7 : Fetch et JSON

Objectif

À la fin de ce chapitre, la page demande fiche.json à une adresse http://, attend la réponse, puis affiche le titre et le texte de ce fichier. Si l’adresse ne répond pas, le paragraphe de la fiche affiche « L’adresse ne répond pas. ». Le dossier premiere-page reste en place. phraseEssai, prenoms, phrases, essai et les deux getElementById du message et du bouton ne changent pas. L’écouteur reste function (), sans parenthèses d’appel et sans console.log.

Servir le dossier

Ouvrir index.html depuis le disque donne une adresse file://. fetch demande un document, et cette adresse refuse la demande. Il faut une adresse http://.

Dans un terminal, placez-vous dans premiere-page et lancez :

python3 -m http.server 8000

Laissez ce terminal ouvert. Dans le navigateur, ouvrez http://127.0.0.1:8000/. Vous voyez « En attente d’un clic. » et le bouton « Nouvel essai ». Un clic affiche « Aina, essai 1 sur 3. ».

Si le terminal dit que le port est déjà pris, relancez avec 8001 et ouvrez http://127.0.0.1:8001/. Ctrl+C arrête le serveur. La page ne peut alors plus se recharger : le HTML lui-même n’arrive pas. Relancez la commande avant la suite.

La fiche

Ajoutez deux paragraphes dans index.html, au-dessus de message. Le clic ne les lit pas. La balise script reste en bas, après le bouton.

<p id="titre">Chargement…</p>
<p id="fiche">La fiche n’est pas encore arrivée.</p>
<p id="message">En attente d’un clic.</p>
<button type="button" id="action">Nouvel essai</button>

Créez fiche.json dans le même dossier. Les noms et les textes sont entre guillemets droits ", comme dans le script. Une virgule sépare les deux lignes. Il n’y a pas de virgule après la dernière, ni de commentaire.

{
  "titre": "Les essais",
  "texte": "Trois essais sont permis."
}

Rechargez http://127.0.0.1:8000/. « Chargement… » et « La fiche n’est pas encore arrivée. » restent en place : le script ne lit pas encore le fichier.

Demander sans bloquer le clic

Dans script.js, après les getElementById du message et du bouton, lisez les deux nouveaux paragraphes. Placez fetch avant l’écouteur. Cet écouteur reste la dernière instruction, avec function ().

const titre = document.getElementById("titre");
const fiche = document.getElementById("fiche");

fetch("fiche.json").then(function (reponse) {
  if (reponse.ok === false) {
    titre.textContent = "Fiche indisponible";
    fiche.textContent = "L’adresse n’a pas renvoyé la fiche.";
    return;
  }
  return reponse.json();
}).then(function (donnees) {
  if (!donnees) {
    return;
  }
  titre.textContent = donnees.titre;
  fiche.textContent = donnees.texte;
}).catch(function () {
  titre.textContent = "Fiche indisponible";
  fiche.textContent = "L’adresse ne répond pas.";
});

"fiche.json" est relatif. Le navigateur le complète avec l’adresse de la page, donc http://127.0.0.1:8000/fiche.json. fetch lance la demande et rend la main. La fonction passée à then attend qu’une réponse arrive. L’écouteur est posé avant cette réponse.

Ajoutez ce journal sur la première ligne du premier then, avant le if.

console.log("La réponse est là.");

Ajoutez l’autre juste après le point-virgule qui clôt catch, avant l’écouteur.

console.log("Le script continue.");

Rechargez. La console affiche d’abord « Le script continue. », puis « La réponse est là. ». Retirez les deux console.log.

Rechargez encore. Le titre affiche « Les essais ». La fiche affiche « Trois essais sont permis. ». Le premier clic affiche « Aina, essai 1 sur 3. ». La réponse écrit dans titre et fiche. Le clic écrit dans message.

La propriété, pas l’objet entier

reponse.ok vaut true pour un statut 200. reponse.json() transforme le texte du fichier en objet. Cette lecture attend aussi : le then suivant reçoit donnees. donnees.titre vaut "Les essais" et donnees.texte vaut "Trois essais sont permis.".

Remplacez donnees.titre par donnees. Rechargez. Le titre affiche [object Object]. textContent a reçu l’objet, pas la chaîne "Les essais". Remettez donnees.titre.

Écrivez donnees.titres, avec un s de trop, et ajoutez au-dessus console.log(donnees.titres). Rechargez. La console affiche undefined : ce nom est absent du fichier. Le titre se vide, « Chargement… » disparaît, et la fiche affiche encore « Trois essais sont permis. ». Retirez le journal, rétablissez donnees.titre. « Les essais » revient.

404 : le serveur a répondu

Ajoutez console.log(reponse.status) sur la première ligne du premier then. Dans fetch, demandez "fiche-absente.json". Rechargez. La console affiche 404. Le serveur a répondu que le fichier n’existe pas. reponse.ok vaut false, donc catch ne part pas. La page affiche « Fiche indisponible » et « L’adresse n’a pas renvoyé la fiche. ».

Ce return ne transmet pas d’objet. Le then suivant reçoit undefined, et if (!donnees) sort avant donnees.titre. Retirez ce if et son return, gardez le fichier absent, rechargez. donnees vaut undefined, donc donnees.titre échoue, et catch écrit « L’adresse ne répond pas. » à la place de la phrase du 404. Remettez le if, remettez "fiche.json", retirez le console.log. « Les essais » revient.

Aucune réponse, ou un JSON illisible

Le serveur du dossier doit rester lancé, sinon index.html ne s’ouvre plus. Changez seulement l’adresse demandée.

fetch("http://127.0.0.1:5999/fiche.json")

La page vient encore de http://127.0.0.1:8000/. Rien n’écoute sur le port 5999. Remplacez le catch par celui-ci.

}).catch(function (erreur) {
  console.log(erreur.name);
  titre.textContent = "Fiche indisponible";
  fiche.textContent = "L’adresse ne répond pas.";
});

Rechargez. La console affiche TypeError. Le titre devient « Fiche indisponible », la fiche « L’adresse ne répond pas. ». Le clic affiche toujours « Aina, essai 1 sur 3. » : l’écouteur a été posé avant l’échec de la demande.

Remettez fetch("fiche.json") et gardez le journal. Rechargez http://127.0.0.1:8000/ : la fiche correcte revient, sans TypeError. Un double-clic sur index.html ouvre une adresse file://. La demande est refusée, la console affiche TypeError, et la fiche montre « L’adresse ne répond pas. ». Revenez à l’adresse http://.

Effacez le guillemet fermant de "Les essais dans fiche.json, enregistrez, rechargez la page servie en http://. Le serveur répond 200. reponse.json() ne peut pas lire ce texte : la console affiche SyntaxError, et la fiche montre encore « L’adresse ne répond pas. ». Le nom de l’erreur sépare ce cas du port fermé. Rétablissez le guillemet, retirez console.log(erreur.name) et le paramètre. catch redevient function (). Au rechargement, « Les essais » et « Trois essais sont permis. » sont de retour.

Exercice

  1. Avec le serveur lancé, ouvrez http://127.0.0.1:8000/. Le titre est « Les essais », la fiche « Trois essais sont permis. », le premier clic « Aina, essai 1 sur 3. ».
  2. Demandez fiche-absente.json, puis rechargez. La fiche affiche « L’adresse n’a pas renvoyé la fiche. ». Remettez fiche.json.
  3. Demandez http://127.0.0.1:5999/fiche.json, puis rechargez. La fiche affiche « L’adresse ne répond pas. ». Remettez fetch("fiche.json").
  4. Retirez un guillemet dans fiche.json, rechargez, puis réparez le fichier. Le titre redevient « Les essais ». Le script final n’a aucun console.log.

À retenir

  • fetch demande fiche.json en http://. Le serveur lancé dans premiere-page livre la page et la fiche.
  • La fonction de then attend la réponse. L’écouteur du clic est posé avant elle.
  • Un statut 404 est une réponse. reponse.ok vaut false, et return évite de lire un objet qui n’est pas arrivé.
  • Sans réponse, avec une adresse file://, ou avec un JSON illisible, catch écrit « L’adresse ne répond pas. » dans la page.
  • donnees.titre et donnees.texte sont les deux chaînes du fichier. L’objet entier s’affiche comme [object Object].

La suite

La page sait demander une fiche, attendre, et montrer un message quand l’adresse ne répond pas. Tout tient encore dans script.js : les variables, phraseEssai, quatre getElementById, le fetch, puis l’écouteur. Le chapitre 8, « Modules et organisation du code », répartira ce script dans plusieurs fichiers. Chaque fichier n’exposera que ce que les autres ont le droit d’appeler, et la page chargera le point d’entrée. Gardez premiere-page, fiche.json et ce fetch. phraseEssai, prenoms, phrases et essai restent tels quels. L’écouteur reste function (), sans parenthèses d’appel et sans console.log.