[LOGO]

Requêtes AJAX


Comme pour les TP précédents, on vous demande de créer un répertoire tp8 qui contiendra les exercices de cette feuille de TP et de faire un compte rendu de TP en HTML.
Comme le TP 4, ce TP sera noté, mais vous pouvez bien sûr demander de l'aide à vos enseignants : le but de la note est de vous pousser à travailler sérieusement et de vous donner une idée de votre niveau de compréhension du cours.
Vous devez uploader ce TP (compte-rendu, feuille CSS et un fichier HTML par exercice) sur e-learning avant le mardi 2 avril à 22h. Les retards ne seront pas autorisés.
Les éléments suivants seront pris en compte dans la note.
  • Si vous travaillez en binôme, vous devez l'indiquer et écrire votre code et votre compte-rendu séparément : en cas de ressemblance trop grande entre les travaux de deux élèves, et surtout si ceux-ci ne nous ont pas prévenus, il auront chacun 0/20.
  • Vous devez être l'auteur du code et compte-rendu que vous rendez. Si vous copiez du code venu d'ailleurs, c'est du plagiat qui sera sanctionné.
  • Le code html produit pour le compte-rendu et les exercices doivent passer les tests du validateur W3.org sans erreurs.
  • Une feuille de style externe doit permettre une mise en forme élégante du compte-rendu.
  • Lorsque cela est demandé, le code JavaScript produit doit répondre aux attentes en respectant les éventuelles contraintes imposées.
  • Le code JS doit être commenté à bon escient.
  • Le code JS produit doit respecter les règles de forme et de syntaxe usuelles et vues en cours, notamment l'usage des indentations, des accolades `{}`, du point-virgule `;` et des mots-clés `let / const`.
  • ATTENTION ! Si jamais, lorsque vous répondez à une question, vous souhaitez modifier le code que vous aviez déjà écrit, il faut impérativement commenter votre ancien code pour en laisser une trace. De manière générale, si vous réussissez une question dure, on se doutera bien que vous avez aussi réussi la question facile, mais si vous effacez un code correct à une question pour écrire un code incorrect à la question d'après on comptera les deux questions comme fausses, ce qui serait très dommage.

Exercice 1 : Un panier de fruits

On cherche à afficher le contenu d'un panier de fruit en faisant une requête AJAX puis en modifiant le DOM pour ajouter des lignes à une table HTML. Dans tout cet exercice, on n'utilisera pas de promesses.

  1. Recopiez les fichiers exo1.html, basket.js, fruitQuantities.json et HTTPServer.py dans votre répertoire tp8.
    Dans la suite, vous devrez uniquement modifier le code Javascript de basket.js.
  2. On cherche à écrire une requête AJAX qui va lire le fichier fruitQuantities.json.
    Créez un objet XMLHttpRequest, utilisez la méthode open() pour créer une requête sur le fichier fruitQuantities.json stocké sur le serveur du cours (et non pas celui que vous avez copié localement), puis envoyez la requête au serveur avec la méthode send.
    Comment faire pour savoir si la requête a réussi ou échoué en utilisant les outils de développement de votre navigateur ?
    Testez si votre requête AJAX fonctionne avec Firefox et avec Chrome.
  3. Que se passe-t-il si vous essayez d'envoyer une requête pour récupérer une copie locale du fichier fruitQuantities.json ? Si vous avez un message d'erreur, comment pouvez-vous expliquer le contenu de ce message d'erreur ?
  4. En fonction de votre navigateur et de la version de celui-ci, il est probable que vous n'ayez pas pu accéder au fichier fruitQuantities.json. Pour éviter que ce genre de mésaventures ne se reproduise, vous allez lancer un serveur HTTP minimaliste sur votre propre machine. (Lisez bien toute la question, y compris le paragraphe qui commence par Attention, avant d'entamer les opérations qui suivent).
    Pour ce faire, ouvrez un terminal, placez-vous dans le répertoire tp8, puis lancez la commande python HTTPServer.py ou python3 HTTPServer.py. Vous venez de lancer votre serveur HTTP dans le répertoire tp8, et alors le fichier fruitQuantities.json est accessible depuis l'URL http://localhost:8080/fruitQuantities.json.

    Attention : Si jamais votre ordinateur hébergeait déjà un service qui utilisait le port 8080, vous avez dû voir s'afficher un message d'erreur Port 8080 already in use. Dans ce cas, vous pouvez remplacer le port 8080 par le port 3000 (ou bien par n'importe quel port : il vous suffit de remplacer 3000 par votre numéro de port préféré) en lançant la commande suivante : python HTTPServer.py 3000. Le fichier fruitQuantities.json sera accessible depuis l'URL http://localhost:3000/fruitQuantities.json.
    Note : Si jamais vous avez l'habitude d'utiliser une autre commande ou méthode pour exécuter des scripts python, faites comme d'habitude. L'essentiel étant d'exécuter le script HTTPServer.py.
  5. Ajoutez une fonction pour écouter les événements readystatechange et si la requête a réussi, affichez le résultat de la propriété responseText dans la console.
  6. Transformez la chaine de caractère stockée dans responseText au format JSON en objet JavaScript.
    Quel est le type de variable JavaScript obtenue ?
  7. Affichez, dans la console, un tableau contenant les noms des champs stockés dans votre objet JSON.
    Note : Quelle fonction permet de créer un tel tableau ?
  8. Actuellement, le document exo1.html contient une table HTML. À l'aide de JavaScript, récupérez l'élément HTML correspondant à cette table, puis modifiez la table pour faire en sorte qu'elle contienne une ligne par fruit et deux colonnes : la première colonne contiendra le nom du fruit, et l'autre la quantité du fruit.
    Note : Vous devez modifier votre élément HTML uniquement à l'aide de votre code Javascript, et certainement pas en réécrivant à la main des portions du document exo1.html.
  9. Faire en sorte que le span quantity de la page HTML soit mis à jour avec la somme des quantités de tous les fruits.

Exercice 2 : Combien ça coûte ?

On cherche à améliorer le code précédent pour calculer le prix du panier (en plus de la quantité de tous les fruits).
Pour cela, on va créer un nouveau fichier JSON (prices.json), contenant le prix d'une orange, d'une banane et d'une poire (et aucune autre information), et qui sera chargé pour calculer le prix d'un panier. Dans tout cet exercice, on n'utilisera pas de promesses non plus.

  1. Recopiez la page Web exo2.html dans votre répertoire tp8 puis recopiez votre fichier basket.js dans le fichier basket2.js.
  2. Le prix d'une orange est 10 euros, le prix d'une banane est 35 euros et le prix d'une poire est 5 euros. On veut écrire ces prix dans le fichier prices.json, quelle structure de données utiliser ?
  3. Écrivez le fichier prices.json contenant ces informations de prix.
    Vérifiez que votre fichier respecte bien le format JSON en utilisant le validateur de JSON http://jsonlint.com/.
  4. Faites en sorte que le fichier prices.json soit chargé par une requête AJAX.
    Note 1 : sachant que l'on charge déjà le fichier fruitQuantities.json avec une requête AJAX, c'est mieux s'il n'y a qu'un seul code de chargement de requête AJAX. Pour ce faire, écrivez une fonction effectuant ces requêtes, dont les deux arguments seront un tableau d'URLs des ressources que l'on veut charger et la fonction que l'on souhaitera appeler au moment où ces ressources auront été chargées.
    Note 2 : Comme l'on exécute plusieurs requêtes, il faut bien être sûr qu'elles soient toutes terminées avant d'exécuter la fonction finale.
    Note 3 : Mais ce n'est pas une raison pour attendre qu'une requête soit finie pour lancer l'autre, ce qui serait inefficace.
  5. Faites en sorte de calculer le prix du panier et de mettre à jour la page Web avec le prix.

Exercice 3 : Les promesses n'engagent que ceux qui y croient

  1. Recopiez la page Web exo3.html dans votre répertoire tp8 puis recopiez votre fichier basket2.js dans le fichier basket3.js.
  2. Récupérer l'objet contenu dans le fichier prices.json sans créer de requête AJAX à la main, mais en s'aidant de la fonction fetch et de promesses.
  3. Faites en sorte de calculer le prix du panier et de mettre à jour la page Web avec le prix, mais en utilisant la fonction fetch et des promesses.