| Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente |
| web:js:ajax [2023/04/01 12:26] – [async/await] jcheron | web:js:ajax [2023/10/12 11:11] (Version actuelle) – [API Fetch] jcheron |
|---|
| ==== async/await ==== | ==== async/await ==== |
| |
| L'utilisation de **async** et **await** permet d'utiliser les fonctions asynchrones sans obligations de chaîner les promesses (pas besoin de mettre le code dans le retour **then**). | L'utilisation de **async** et **await** permet d'utiliser les fonctions asynchrones sans obligation de chaîner les promesses (pas besoin de mettre le code dans le retour **then**). |
| |
| <sxh javascript;highlight:[9,11]> | <sxh javascript;highlight:[9,11]> |
| |
| ===== API Fetch ===== | ===== API Fetch ===== |
| | |
| | L'api fetch permet en javascript d'effectuer des requêtes partielles vers le serveur, sans changer de page, selon le mode AJAX (Asynchronous Javascript And XML). |
| | |
| | **fetch** fonctionne selon la syntaxe suivante : |
| | <sxh javascript;gutter:false> |
| | let promise = fetch(url, [options]) |
| | </sxh> |
| | |
| | * Requête vers une **url** cible |
| | * en passant un tableau d'**option**s (méthode, headers...) |
| | |
| | Sans options, **fetch** effectue un simple **GET** téléchargeant le contenu. |
| | |
| | Lors de l'utilisation de **fetch**, la requête est envoyée vers le serveur et renvoie une promise qui pourra être utilisée via un objet **Response**. |
| | |
| | La réponse peut être analysée (via ses membres **status** ou **ok**, et on obtient son corps fourni sous la forme d'une seconde promesse : |
| | |
| | <sxh javascript> |
| | let response = await fetch(url); |
| | |
| | if (response.ok) { // Statut dans les 200 |
| | // obtenir le corps de réponse au format JSON |
| | let json = await response.json(); |
| | } else { |
| | alert("HTTP-Error: " + response.status); |
| | } |
| | </sxh> |
| | |
| | ==== Response ==== |
| | ^Méthode ^Action ^ |
| | ^response.headers() | Retourne les en-têtes de la réponse | |
| | ^response.text() | Retourne la réponse sous forme de texte | |
| | ^response.json() | Retourne la réponse au format JSON | |
| | ^response.formData() | Retourne un objet FormData | |
| | ^response.blob() | Retourne la réponse sous forme de blob (données binaires typées) | |
| | |
| | ==== Exemples ==== |
| | |
| | Requête vers l'api Github pour obtenir la liste des messages de commits d'un repo : |
| | |
| | Version **await** : |
| | <sxh javascript> |
| | let url = 'https://api.github.com/repos/cnam-dist/nfa085-2023/commits'; |
| | let response = await fetch(url); |
| | |
| | let commits = await response.json(); |
| | |
| | alert(commits[0].message); |
| | </sxh> |
| | |
| | Version **then** |
| | |
| | <sxh javascript> |
| | fetch('https://api.github.com/repos/cnam-dist/nfa085-2023/commits') |
| | .then(response => response.json()) |
| | .then(commits => alert(commits[0].message)); |
| | </sxh> |
| | |
| | |
| | Chargement d'image : |
| | |
| | <sxh javascript> |
| | let response = await fetch('/lib/tpl/bootstrap3/images/logo.png'); |
| | |
| | let blob = await response.blob(); // téléchargement en tant qu'objet Blob |
| | |
| | // Création d img |
| | let img = document.createElement('img'); |
| | img.style = 'position:fixed;top:10px;left:10px;width:100px'; |
| | document.body.append(img); |
| | |
| | // Affichage |
| | img.src = URL.createObjectURL(blob); |
| | |
| | setTimeout(() => { // Effacement après 3 secondes |
| | img.remove(); |
| | URL.revokeObjectURL(img.src); |
| | }, 3000); |
| | </sxh> |
| | |
| | <html> |
| | <div class="imageB"> |
| | <button id="ajax-load-image">Test image loading</button> |
| | </div> |
| | <script> |
| | document.getElementById("ajax-load-image").addEventListener("click", async function () { |
| | let response = await fetch('/lib/tpl/bootstrap3/images/logo.png'); |
| | |
| | let blob = await response.blob(); |
| | |
| | let img = document.createElement('img'); |
| | img.style = 'position:fixed;top:100px;left:100px;width:100px'; |
| | document.body.append(img); |
| | |
| | img.src = URL.createObjectURL(blob); |
| | |
| | setTimeout(() => { // le cacher après 3 secondes |
| | img.remove(); |
| | URL.revokeObjectURL(img.src); |
| | }, 3000); |
| | }); |
| | </script> |
| | </html> |
| | |
| | ==== Headers ==== |
| | === Response === |
| | L'objet **response** renvoyé contient un membre **headers** grace auquel il est possible dé récupérer les en-têtes : |
| | |
| | <sxh javascript> |
| | let response = await fetch('https://api.github.com/repos/cnam-dist/nfa085-2023/commits'); |
| | |
| | // récupération d'un header |
| | alert(response.headers.get('Content-Type')); // application/json; charset=utf-8 |
| | |
| | // itération sur tous les headers |
| | for (let [key, value] of response.headers) { |
| | alert(`${key} = ${value}`); |
| | } |
| | </sxh> |
| | === Request === |
| | Les headers de la requête sont envoyées au travers des options du fetch : |
| | <sxh javascript> |
| | let response = fetch(protectedUrl, { |
| | headers: { |
| | Authentication: 'secret' |
| | } |
| | }); |
| | </sxh> |
| | |
| | ==== POST ==== |
| | La méthode HTTP utilisée peut également être spécifiée au travers des options, comme les données envoyées dans le body : |
| | <sxh javascript> |
| | let user = { |
| | name: 'John', |
| | surname: 'DOE' |
| | }; |
| | |
| | let response = await fetch('/post/user', { |
| | method: 'POST', |
| | headers: { |
| | 'Content-Type': 'application/json;charset=utf-8' |
| | }, |
| | body: JSON.stringify(user) |
| | }); |
| | </sxh> |
| | |
| |
| |