Fetch et API du navigateur : récupérer des données

Apprends à charger et à envoyer des données avec fetch, à afficher les résultats sur une page web et à conserver de petites quantités de données dans le navigateur. Tu lis des requêtes et des réponses HTTP ainsi que du JSON, tu gères les états de chargement et d’erreur et tu mets en forme les dates et les prix d’une API pour chaque lecteur. Tu découvres pourquoi les erreurs CORS se produisent et pourquoi les clés d’API secrètes n’ont pas leur place dans le code côté client, puis tu utilises localStorage, sessionStorage et des fonctionnalités du navigateur comme la géolocalisation et le presse-papiers.

DébutantUnité 8 sur 9 de la formation Formation : JavaScript : DOM, événements et code asynchrone

Ce que tu vas apprendre

  1. Explique comment fonctionnent une requête et une réponse HTTP, charge des données JSON avec fetch et envoie des données à une API avec la méthode, les en-têtes et le corps appropriés.
    • Lis les requêtes et les réponses HTTP
      Décris les parties d’une requête et d’une réponse HTTP, associe chaque méthode HTTP à son action et lis les codes d’état et les en-têtes dans les outils de développement du navigateur.
    • Charge des données JSON avec fetch
      Appelle fetch, vérifie l’état de la réponse, lis et analyse son corps JSON et construis des URL de requête avec des paramètres de requête correctement encodés.
    • Envoie des données avec POST, PUT, PATCH et DELETE
      Passe un objet d’options à fetch pour envoyer du JSON ou des données de formulaire, et traite la réponse du serveur après avoir créé, mis à jour ou supprimé un enregistrement.
  2. Transforme les résultats d’une API en contenu de page, mets en forme les dates et les montants pour le lecteur et garde la page claire pendant le chargement, en cas d’échec ou lorsque les données arrivent dans le désordre.
    • Affiche les résultats d’une API dans la page
      Construis des éléments de page à partir des tableaux et des objets d’une réponse JSON, insère le texte de l’API en toute sécurité et gère les champs manquants, les résultats vides et les résultats paginés.
    • Mets en forme les dates, les nombres et les montants monétaires issus des données d’une API
      Convertis les chaînes de date, les horodatages et les montants envoyés par les API en texte lisible adapté à la langue, à la région et au fuseau horaire du lecteur avec les outils de mise en forme Intl.
    • Affiche les états de chargement, d’erreur et d’absence de données
      Suis les étapes d’une requête, affiche un message clair à l’utilisateur pour chaque étape et réagis aux échecs par de nouvelles tentatives.
    • Annule des requêtes, limite leur durée et combine-les
      Annule les requêtes devenues inutiles, définis des limites de durée, empêche les réponses obsolètes de remplacer les plus récentes et exécute plusieurs requêtes en parallèle ou en séquence.
  3. Explique la politique de même origine et les erreurs CORS, et protège les clés d’API et les données des utilisateurs lorsqu’une page communique avec d’autres serveurs.
    • Comprends la politique de même origine et le partage de ressources entre origines
      Identifie l’origine d’une URL, explique pourquoi le navigateur bloque certaines réponses provenant d’autres origines et reconnais comment les en-têtes CORS et les requêtes préliminaires permettent à un serveur de les autoriser.
    • Protège les clés d’API et les données des utilisateurs
      Explique le rôle des clés d’API et des jetons, pourquoi un secret dans le code côté client est public et comment envoyer les identifiants et traiter les données des utilisateurs de manière responsable.
  4. Enregistre, lis et mets à jour de petites quantités de données avec localStorage et sessionStorage, et détermine ce qu’il est judicieux et sûr de conserver dans le navigateur.
    • Enregistre et lis des données avec localStorage et sessionStorage
      Utilise les méthodes de Web Storage, explique la durée de conservation de chaque type de stockage et qui peut le lire, et convertis des nombres, des booléens et des objets en chaînes de caractères stockées et inversement.
    • Utilise le stockage du navigateur dans une application
      Restaure l’état enregistré au chargement d’une page, mets en cache les réponses d’une API avec une durée d’expiration, synchronise les onglets et décide de ce qui ne doit pas être stocké.
  5. Détecte et utilise les API du navigateur qui nécessitent une page sécurisée ou l’autorisation de l’utilisateur, comme la géolocalisation et le presse-papiers, et propose une solution de repli lorsqu’une fonctionnalité est indisponible.
    • Obtiens la position de l’utilisateur avec l’API de géolocalisation
      Vérifie qu’une API du navigateur est disponible, explique les contextes sécurisés et les demandes d’autorisation, et utilise l’API de géolocalisation avec ses options, ses erreurs et une solution de repli.
    • Copie du texte et utilise d’autres API du navigateur
      Copie du texte avec l’API du presse-papiers, réagis aux changements de connectivité, lis les paramètres de l’adresse de la page et suis une méthode pour découvrir toute nouvelle API du navigateur.

Fetch et API du navigateur : cours

5 chapitres

1

Effectue des requêtes et lis les réponses

Une page peut demander des données à un serveur sans charger une nouvelle page. La requête indique quelle ressource tu veux et ce que tu veux en faire ; la réponse indique ce qui s’est passé. Tu suivras cet échange dans l’onglet Réseau, convertiras une réponse JSON en données JavaScript et enverras des modifications au serveur. Les points à vérifier sont la méthode, le code d’état et la structure du corps : l’arrivée d’une réponse ne signifie pas à elle seule que l’opération a réussi.

1.1 Les éléments d’un échange HTTP

Une API web permet à un programme de lire ou de modifier des données au moyen d’URL nommées, appelées points de terminaison. Le JavaScript de la page est le client. Il envoie une requête HTTP ; le serveur répond avec une réponse HTTP. De nombreuses API envoient du texte JSON, qui peut représenter des objets, des tableaux, des chaînes de caractères, des nombres, des booléens et null.

Lire une requête

Prenons GET https://api.example.com/books?author=Le%20Guin&limit=5. La méthode est GET, le chemin /books sélectionne la ressource et la chaîne de requête contient deux paramètres. La valeur de author est « Le Guin » ; %20 encode l’espace. Une esperluette sépare les paramètres. La documentation de l’API explique les noms de paramètres acceptés et le sens de chaque valeur.

Une requête peut aussi transporter des en-têtes, qui sont des paires nom-valeur, et un corps, qui contient les données soumises. Accept: application/json demande une réponse JSON. Content-Type: application/json décrit le corps envoyé. Authorization transporte des identifiants. Les noms d’en-tête ne tiennent pas compte de la casse : content-type et Content-Type désignent donc le même en-tête.

Choisir l’action
MéthodeAction prévueUtilisation habituelle
GETLireObtenir une liste de notes
POSTCréer ou soumettreAjouter une note
PUTRemplacerEnvoyer la note complète de remplacement
PATCHModifier une partieMarquer une note comme terminée
DELETESupprimerSupprimer une note

GET et HEAD sont des méthodes sûres : elles sont destinées à la lecture. N’utilise donc pas GET pour un bouton de suppression. GET, PUT et DELETE sont idempotentes. Répéter la même requête laisse le serveur dans le même état attendu qu’une seule exécution. Supprimer une note déjà supprimée peut renvoyer un code d’état différent, mais la note reste absente. Répéter un POST peut créer un second enregistrement.

Interpréter la réponse

La réponse contient un code d’état, des en-têtes et généralement un corps. Le premier chiffre classe le résultat :

  • 2xx : succès. 200 OK contient généralement des données, 201 Created indique une création et 204 No Content n’a pas de corps.
  • 3xx : redirection. Par défaut, fetch suit les redirections.
  • 4xx : problème lié à la requête ou à l’accès. 400 signifie que la requête est incorrecte ; 401, que les identifiants sont absents ou invalides ; 403, que le serveur comprend la requête mais la refuse ; 404, que la ressource est introuvable ; 429, qu’il y a trop de requêtes.
  • 5xx : problème de serveur, comme 500 Internal Server Error ou 503 Service Unavailable.

Un appel à /books/42 peut renvoyer 200, un type de contenu JSON et {"id":42,"title":"The Dispossessed","year":1974}. Un appel à /books/9999 peut renvoyer 404 et {"error":"Book not found"}. Les deux appels ont reçu une réponse. Une erreur de connexion ne produit aucun code d’état HTTP que JavaScript puisse examiner.

Examiner avant de supposer

Ouvre les outils de développement, sélectionne Réseau et déclenche l’action. Examine la méthode, l’URL complète, le code d’état, les en-têtes, le corps et les durées. Compare-les au point de terminaison, aux paramètres obligatoires, aux identifiants, aux limites de requêtes et à l’exemple de réponse de la documentation. Si le serveur a renvoyé les bonnes données, examine le code de la page ; si l’URL de la requête est incorrecte, corrige-la avant de modifier le code de rendu.

Points clés

  • Un point de terminaison est une URL qu’une API expose pour une opération.
  • La méthode sélectionne l’action ; l’URL sélectionne la ressource et les paramètres.
  • Les en-têtes de requête et de réponse décrivent l’échange.
  • Un 404 est une réponse, tandis qu’une erreur de connexion n’a pas de code d’état HTTP.
  • Examine l’onglet Réseau et compare l’échange à la documentation de l’API.

1.2 Charge du JSON en deux étapes asynchrones

fetch(url) envoie une requête GET et renvoie une promesse. Son résultat est un objet Response, disponible à l’arrivée des en-têtes. La lecture du corps est une opération asynchrone distincte. response.json() lit ce corps et l’analyse pour obtenir des données JavaScript.

Attendre, vérifier, lire
async function loadBook(id) {
  const response = await fetch(`https://api.example.com/books/${id}`);
  if (!response.ok) {
    throw new Error(`HTTP error ${response.status}`);
  }
  return await response.json();
}

Pour loadBook(42), le premier await obtient la réponse. La condition rejette un résultat HTTP indiquant un échec. Le second await obtient le livre analysé, par exemple { id: 42, title: "The Dispossessed", year: 1974 }. La fonction elle-même renvoie une promesse : son appelant attend donc aussi le résultat.

response.ok est vrai pour les codes d’état de 200 à 299 inclus. Une erreur HTTP comme 404 ou 500 ne provoque pas le rejet de la promesse de fetch : un serveur a répondu. Une panne réseau, un échange bloqué par CORS, une URL de requête invalide ou une annulation peuvent provoquer son rejet. Lever une exception pour !response.ok permet à un bloc try/catch englobant de gérer aussi les échecs HTTP.

Comprendre le corps

Sans await, const data = response.json() stocke une promesse, pas le livre. L’accès à data.title donne alors undefined. Omettre await devant fetch laisse de même une promesse là où le code attend un objet Response.

Choisis la méthode de lecture adaptée au corps de la réponse : json() pour le JSON, text() pour le texte ou blob() pour les données binaires. Un corps ne peut être consommé qu’une fois. Stocke le résultat analysé et réutilise-le. Pour examiner aussi le texte JSON brut, lis text() une fois, puis appelle JSON.parse(text) sur la chaîne stockée.

Du JSON invalide entraîne un rejet avec une SyntaxError. Une page d’erreur HTML provoque souvent un message « Unexpected token '<' ». Un corps vide, notamment dans une réponse 204, ne peut pas non plus être analysé comme du JSON. Vérifie d’abord le code d’état et examine response.headers.get("Content-Type") en cas de doute sur le format. Un code d’état de succès ne garantit pas à lui seul que le corps contient du JSON.

Construire une requête en toute sécurité
const url = new URL("https://api.example.com/search");
url.searchParams.set("q", "rock & roll");
url.searchParams.set("limit", 10);

L’adresse obtenue est https://api.example.com/search?q=rock+%26+roll&limit=10. L’esperluette incluse dans la valeur est encodée comme partie de celle-ci. Ajouter directement la saisie à "?q=" peut donner à &, # ou + leur signification dans une URL et modifier la recherche. Une URL relative suit les règles habituelles de résolution des adresses : depuis https://notes.example.org/app/index.html, fetch("data/books.json") charge /app/data/books.json sur cette origine.

Suivre la structure renvoyée

Pour {"results":[{"title":"Dune"}],"total":1}, le premier titre est data.results[0].title. L’objet englobant n’est pas le tableau de résultats. Utilise l’aperçu de la réponse pour trouver le tableau avant de le parcourir.

Une fonction utilitaire partagée getJSON(url, options) peut effectuer la même vérification du code d’état et la même lecture du corps pour de nombreux appels. Dans une chaîne .then(), renvoie response.json() depuis la fonction de rappel de la réponse afin que la suivante reçoive les données analysées. Ajoute .catch() à la fin pour gérer les étapes rejetées.

Points clés

  • fetch et response.json() renvoient des promesses distinctes.
  • Vérifie response.ok ; une erreur HTTP ne provoque pas le rejet de fetch.
  • Lis le corps d’une réponse une seule fois et réutilise la valeur stockée.
  • Utilise URL.searchParams pour encoder les valeurs de requête.
  • Lis le JSON imbriqué selon sa structure réelle d’objets et de tableaux.
  • Une réponse réussie peut tout de même contenir un corps JSON vide ou invalide.

1.3 Envoie une modification et utilise le résultat du serveur

Le second argument de fetch configure une requête. Ses options comprennent method, headers, body, signal et credentials. Sans ces options, la requête est un GET sans corps. Pour soumettre du JSON, tu dois préparer son texte et son type de contenu.

Envoyer du JSON
const response = await fetch("https://api.example.com/notes", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ title: "Shopping", text: "Rice, lentils" }),
});

JSON.stringify produit {"title":"Shopping","text":"Rice, lentils"}. L’en-tête indique au serveur comment lire ce texte. Passer directement l’objet comme corps envoie "[object Object]". Envoyer la chaîne JSON sans l’en-tête lui attribue le type text/plain;charset=UTF-8, que de nombreux points de terminaison JSON rejettent avec 400 ou 415 Unsupported Media Type.

Une création réussie renvoie souvent 201 avec l’enregistrement stocké, par exemple {"id":17,"title":"Shopping","text":"Rice, lentils"}. Utilise l’objet renvoyé pour mettre la page à jour : le nouvel id attribué par le serveur est nécessaire pour les modifications et la suppression ultérieures.

Remplacer ou mettre à jour
RequêteCorpsSignification
PATCH /notes/17{"done":true}Modifier le champ fourni
PUT /notes/17La note complète de remplacementRemplacer la ressource
DELETE /notes/17Souvent aucunSupprimer la ressource

Un corps PUT qui omet un champ peut entraîner sa suppression ou sa réinitialisation, selon l’API. Utilise la méthode documentée pour la modification souhaitée. PUT et PATCH peuvent renvoyer un enregistrement mis à jour avec 200, ou renvoyer 204 sans corps.

Gère le succès sans supposer qu’il est toujours suivi de JSON :

if (!response.ok) {
  throw new Error(`HTTP error ${response.status}`);
}
const saved = response.status === 204
  ? null
  : await response.json();

Ce schéma convient aux points de terminaison documentés comme renvoyant soit du JSON, soit 204. Une suppression peut réussir et produire tout de même une erreur d’analyse syntaxique si le code appelle systématiquement json() sur son corps vide.

Choisir le format du corps

new FormData(formElement) recueille les champs nommés du formulaire et les fichiers sélectionnés. Passe-le directement comme body. Laisse le navigateur définir Content-Type: multipart/form-data et son délimiteur ; un en-tête fourni manuellement peut omettre le délimiteur nécessaire pour séparer les champs. Un corps URLSearchParams utilise application/x-www-form-urlencoded.

GET et HEAD ne peuvent pas transporter de corps avec fetch. Place les termes de recherche et les filtres dans la chaîne de requête de l’URL. Une tentative de GET avec un corps est rejetée avec une TypeError avant de pouvoir servir de requête de recherche.

Terminer correctement après un succès ou un échec

Désactive le bouton de soumission avant d’attendre une requête de création, puis réactive-le dans finally. Sinon, un double clic peut envoyer deux requêtes POST et créer deux enregistrements. Ne répète pas automatiquement une opération de création dont le résultat est incertain : une réponse perdue ne permet pas de savoir si le serveur a effectué la modification.

Pour un code d’état d’erreur, le corps peut contenir un message utile comme {"error":"title is required"}. Lis-le une fois s’il s’agit de JSON ; intercepte une erreur d’analyse et conserve un message HTTP général pour les réponses vides ou HTML. Garde le texte saisi par l’utilisateur afin qu’il puisse corriger la requête.

Points clés

  • Les requêtes JSON nécessitent JSON.stringify et un type de contenu correspondant.
  • Utilise PATCH pour une modification partielle et PUT pour un remplacement complet.
  • Ne lance pas l’analyse JSON pour 204 No Content.
  • Laisse le navigateur définir l’en-tête multipart lors de l’envoi de FormData.
  • Utilise la réponse du serveur, y compris l’identifiant attribué, pour mettre la page à jour.
  • Empêche les soumissions en double et rétablis les commandes dans finally.
2

Transforme les réponses en une page utile

La récupération des données n’est que la première partie d’une interface. Les lecteurs ont besoin de résultats utiles, de dates et de prix lisibles et d’un message clair pendant l’attente. Tu construiras l’affichage à partir de la structure de la réponse, empêcheras les valeurs manquantes de le bloquer et rendras visibles les succès, les résultats vides et les échecs. Tu contrôleras aussi les requêtes qui se chevauchent pour qu’une réponse lente ne puisse pas remplacer des résultats plus récents, et choisiras quand des requêtes indépendantes peuvent s’exécuter ensemble.

2.1 Construis l’affichage à partir des données

Le rendu transforme un tableau ou un objet en éléments sur la page. Conserve les données récupérées dans une variable et donne-les à une fonction de rendu. Cette séparation permet de trier ou de filtrer les mêmes données sans les redemander au serveur.

Créer un élément par résultat
function renderBooks(books, list) {
  list.replaceChildren();
  for (const book of books) {
    const item = document.createElement("li");
    item.textContent = `${book.title} (${book.year})`;
    list.append(item);
  }
}

Pour [{"title":"Kindred","year":1979},{"title":"Beloved","year":1987}], ce code crée deux éléments de liste : « Kindred (1979) » et « Beloved (1987) ». Vider d’abord le conteneur permet à une nouvelle recherche de remplacer la précédente. Sans cette étape, les anciennes et les nouvelles listes s’accumulent.

Conserver le texte externe sous forme de texte

Utilise textContent pour les titres, descriptions et autres textes d’une API. innerHTML analyse une chaîne comme du balisage. Un titre contenant <img src="x" onerror="alert(1)"> peut alors exécuter du code. C’est une injection de script intersite, ou XSS. Le texte provenant des formulaires et du stockage nécessite le même traitement, car il peut lui aussi provenir d’une source non fiable.

Les propriétés des éléments définissent des valeurs individuelles, comme img.alt = book.title. Elles ne rendent pas automatiquement sûrs tous les types de valeurs. Un lien fourni par une API nécessite toujours une vérification du protocole :

try {
  const target = new URL(book.url, location.href);
  if (target.protocol === "https:" || target.protocol === "http:") {
    link.href = target.href;
  }
} catch {
  link.removeAttribute("href");
}

Ce code s’exécute sur un lien nouvellement créé, sans href existant. Une URL invalide ou non autorisée le laisse sans destination. Une URL javascript: n’est pas une navigation web ordinaire. Pour les images, fournis si possible un texte alt pertinent construit à partir des données.

Fournir des valeurs par défaut sans perdre les valeurs réelles

Les champs facultatifs peuvent être absents ou valoir null. book.author?.name ?? "Unknown author" essaie d’abord d’obtenir le nom imbriqué, puis fournit une valeur par défaut. Le chaînage optionnel évite d’accéder à une propriété d’un auteur absent.

L’opérateur compte : 0 || "n/a" donne "n/a", tandis que 0 ?? "n/a" conserve 0. L’opérateur || remplace toutes les valeurs fausses dans un contexte booléen, notamment zéro et une chaîne vide ; ?? ne remplace que null et undefined. Pour un livre dont aucun exemplaire n’est disponible, il faut afficher zéro.

Un tableau de résultats vide correspond à une recherche réussie sans résultat. Affiche « Aucun livre ne correspond à ta recherche. » pour que les lecteurs puissent le distinguer d’une page qui n’a pas été chargée.

Remplacer une recherche, ajouter une autre page

De nombreuses API renvoient des pages à l’aide de page, limit, d’un nombre total ou d’une URL next. Avec 47 résultats et 10 par page, quatre pages complètes contiennent 40 enregistrements et la cinquième en contient 7. Une nouvelle recherche efface la liste précédente ; « Charger plus » ajoute la page suivante à la liste actuelle. Distingue bien ces deux actions d’affichage.

Pour trier une copie locale de la plus récente à la plus ancienne, utilise [...books].sort((a, b) => b.year - a.year) et affiche cette copie. La décomposition crée un nouveau tableau : l’ordre de la réponse enregistrée reste donc disponible. Examine la structure de la réponse avant de sélectionner le tableau : une API paginée le place souvent dans data.results.

Points clés

  • Effectue le rendu à partir des données enregistrées pour trier localement sans nouvelle requête.
  • Insère le texte non fiable avec textContent.
  • Valide le protocole d’un lien fourni par une API avant d’affecter sa destination.
  • Utilise ?. pour les données imbriquées manquantes et ?? lorsque zéro doit rester zéro.
  • Remplace les résultats pour une nouvelle recherche ; ajoute les résultats d’une autre page.

2.2 Mets en forme les dates et les montants pour les lecteurs

Les API renvoient des valeurs faciles à échanger pour les programmes. Les lecteurs ont besoin de dates, d’heures et de montants mis en forme selon leur langue et leur région. Sépare la valeur stockée du texte utilisé pour l’afficher.

Lire d’abord le format de date

"2026-03-05T14:30:00Z" désigne un instant : le 5 mars 2026 à 14 h 30 UTC. Le Z signifie UTC. new Date(...) le convertit en objet JavaScript Date. Une chaîne contenant uniquement une date, comme "2026-03-05", est interprétée comme minuit UTC ; une date et une heure sans décalage, comme "2026-03-05T14:30", sont interprétées comme une heure locale.

Un horodatage Unix compte le temps écoulé depuis le 1er janvier 1970, UTC. Les API comptent souvent en secondes, mais Date utilise les millisecondes. new Date(1772721000 * 1000) donne le même instant du 5 mars. Omettre la multiplication donne une date en janvier 1970. Lis la documentation de l’API pour identifier l’unité.

Choisir des paramètres régionaux et un fuseau horaire
const date = new Date("2026-03-05T14:30:00Z");
const dateFormat = new Intl.DateTimeFormat("en-US", {
  dateStyle: "medium",
  timeStyle: "short",
  timeZone: "UTC",
});
dateFormat.format(date);

La sortie est « Mar 5, 2026, 2:30 PM ». Avec en-GB, elle est « 5 Mar 2026, 14:30 ». Les dates courtes donnent « 3/5/26 » en en-US, « 05/03/2026 » en en-GB et « 05.03.26 » en de-DE.

Les paramètres régionaux contrôlent la présentation ; le fuseau horaire détermine l’heure locale. Sans timeZone, l’outil de mise en forme utilise le fuseau de l’appareil. Cet instant correspond à 9 h 30 à New York, 15 h 30 à Amsterdam et 23 h 30 à Tokyo. Conserve et envoie les instants en UTC, puis convertis-les pour l’affichage. Une date du calendrier comme un anniversaire demande de l’attention : afficher minuit UTC dans un fuseau situé à l’ouest d’UTC peut donner le jour précédent.

Séparer la devise des paramètres régionaux
const priceFormat = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "EUR",
});
priceFormat.format(1234.5);

Cela donne €1,234.50. Pour le même montant, de-DE avec EUR donne 1.234,50 € ; en-US avec USD donne $1,234.50 ; en-US avec JPY donne ¥1,235. JPY n’a pas d’unité monétaire divisionnaire : son affichage habituel ne comporte donc aucune décimale. Le choix des paramètres régionaux ne convertit pas les devises. Utilise le code de devise fourni avec le montant.

Certaines API de paiement envoient des unités divisionnaires sous forme d’entiers. Avec USD, 1999 cents représentent 19.99 dollars américains : divise par 100 avant la mise en forme. N’applique pas ce diviseur à JPY. Additionner des cents entiers donne 1999 + 2550 = 4549, ce qui est mis en forme comme $45.49. Cela évite le résultat bien connu du calcul décimal 0.1 + 0.2, qui vaut 0.30000000000000004.

Réutiliser l’outil de mise en forme

Crée une seule fois un outil de mise en forme pour une liste. Utilise undefined comme paramètres régionaux pour sélectionner ceux du navigateur par défaut ; navigator.language indique le code de langue préféré du navigateur. D’autres options mettent en forme 0.256 comme « 26% », ou 12.5 avec l’unité "kilometer-per-hour" comme « 12.5 km/h ». new Intl.RelativeTimeFormat("en", { numeric: "auto" }).format(-1, "day") donne « yesterday ». Les dates construites à la main comme « 03/05/2026 » restent ambiguës selon les régions.

Points clés

  • Vérifie si les horodatages utilisent des secondes ou des millisecondes.
  • Un fuseau horaire explicite rend prévisible l’affichage de la date et de l’heure.
  • Les paramètres régionaux contrôlent la mise en forme ; la devise provient des données.
  • Convertis les unités divisionnaires indiquées dans la documentation avant de mettre en forme un montant monétaire.
  • Réutilise les objets de mise en forme Intl pour toute une liste.
  • Les chaînes contenant uniquement une date sont interprétées en UTC et peuvent changer de jour lorsqu’elles sont affichées dans un autre fuseau.

2.3 Montre ce que fait la requête

Une requête a un cycle de vie visible : inactive, en chargement, puis réussie ou en erreur. Le succès peut contenir des données ou un résultat vide. La page doit expliquer chaque état pour que les lecteurs sachent s’ils doivent attendre, modifier une recherche ou réessayer.

Regrouper la préparation et la remise en état

Dans ce gestionnaire, getJSON vérifie le code d’état HTTP et analyse le corps, searchUrl construit l’URL de la requête et renderResults met la liste à jour. Le bouton et l’élément d’état existent déjà dans la page.

async function search(query) {
  button.disabled = true;
  status.textContent = "Loading…";
  try {
    const data = await getJSON(searchUrl(query));
    renderResults(data.results);
    status.textContent = data.results.length === 0 ? "No results." : "";
  } catch (error) {
    status.textContent = "Could not load results. Check your connection and try again.";
    console.error(error);
  } finally {
    button.disabled = false;
  }
}

La préparation a lieu avant l’attente. En cas de succès, le code affiche les résultats et gère un tableau vide. Le bloc catch remplace le message de chargement si une étape attendue échoue. finally rétablit le bouton dans les deux cas. Si la remise en état n’avait lieu qu’après un await réussi, un échec laisserait la commande désactivée.

Expliquer la cause utile

Une erreur HTTP possède un code d’état qui aide à formuler le message. Pour 404, indique que l’élément est introuvable. Pour 401, demande à l’utilisateur de se connecter ; pour 403, explique que l’accès n’est pas autorisé. Pour 429, demande-lui de patienter. Pour 5xx, explique que le service rencontre un problème et propose de réessayer plus tard.

Une TypeError provenant de fetch peut indiquer une panne réseau, une requête bloquée par CORS ou une URL incorrecte. JavaScript ne reçoit pas de diagnostic CORS détaillé et fiable ; examine la console du navigateur et l’onglet Réseau. Une SyntaxError provenant de json() indique du JSON invalide. L’annulation et les limites de durée produisent des erreurs comme AbortError et TimeoutError. Garde les détails techniques dans la console et indique aux lecteurs une action qu’ils peuvent comprendre.

Rendre les changements perceptibles

Utilise un élément d’état existant comme <p role="status"></p>. Ses changements sont annoncés aux lecteurs d’écran sans déplacer le focus. aria-live="polite" remplit un rôle similaire ; role="alert" convient aux erreurs urgentes. Un indicateur de chargement seul ne signale pas un résultat vide ou une requête échouée.

Un bouton Réessayer appelle à nouveau la fonction de chargement. Répéter sans modification des requêtes ayant reçu 400 ou 404 reproduit généralement le problème. Des pannes temporaires du réseau ou du service peuvent justifier une courte série limitée de nouvelles tentatives. L’attente exponentielle augmente la pause, par exemple 1 seconde, 2 secondes, puis 4 secondes. Respecte l’en-tête de réponse Retry-After ; il peut indiquer un délai en secondes ou une date HTTP. Évite de répéter automatiquement une requête de création qui a peut-être déjà réussi.

Si une actualisation échoue mais que les données précédentes sont encore utiles, laisse-les visibles avec une note comme « Résultats de 10 h 42 affichés. Actualisation impossible. » Ne laisse pas croire silencieusement que les anciens résultats sont à jour.

Tester les cas difficiles

Utilise les outils de développement pour ralentir la connexion, passer hors ligne et demander un chemin inexistant. Vérifie que le chargement apparaît rapidement, qu’une requête échouée le remplace, qu’un succès sans résultat a son propre message et que les commandes redeviennent utilisables.

Points clés

  • Rends visibles le chargement, le succès sans résultat, le succès avec des données et les erreurs.
  • Place la remise en état commune dans finally.
  • Propose aux lecteurs une action utile et garde les détails techniques dans la console.
  • Annonce les mises à jour d’état au moyen d’une région dynamique adaptée.
  • Limite les nouvelles tentatives et respecte le délai demandé par le serveur.

2.4 Contrôle les requêtes simultanées et parallèles

Les requêtes peuvent durer plus longtemps que l’action qui les a lancées. Une réponse de recherche peut arriver après que le lecteur a saisi autre chose, et un service lent peut laisser une page attendre trop longtemps. Contrôle si les résultats sont encore pertinents, ainsi que la réussite de chaque requête.

Annuler le travail devenu inutile

Crée un AbortController, passe son signal à fetch, puis appelle abort() pour annuler la requête. L’annulation peut interrompre l’attente des en-têtes ou une lecture du corps en cours. L’erreur de rejet est normalement nommée "AbortError".

const controller = new AbortController();
const response = await fetch(url, { signal: controller.signal });
// A cancel button can call controller.abort().
const data = await response.json();

Gère les erreurs autour des deux attentes. Si ton code annule volontairement une recherche obsolète, termine silencieusement pour cette annulation attendue au lieu d’indiquer à l’utilisateur que le service a échoué.

fetch ne possède pas d’option timeout intégrée. Utilise un signal comme AbortSignal.timeout(5000) pour limiter la requête à 5 000 ms, soit 5 secondes de temps actif. Avant l’arrivée des en-têtes, la promesse est rejetée avec TimeoutError ; après leur arrivée, le délai peut interrompre la lecture du corps.

Empêcher les anciennes recherches de prendre le dessus

Une condition de concurrence se produit lorsque l’ordre d’achèvement modifie le résultat. Un lecteur saisit « ch », puis « chat ». Si la réponse pour « ch » arrive en dernier et est affichée, l’écran ne correspond plus à la saisie.

Une approche annule la requête précédente avant chaque nouvelle requête. Une autre attribue un numéro à chaque appel et ne laisse que le plus récent mettre la page à jour :

let latest = 0;
async function search(query) {
  const request = ++latest;
  try {
    const data = await getJSON(searchUrl(query));
    if (request !== latest) return;
    renderResults(data.results);
  } catch (error) {
    if (request !== latest) return;
    showError(error);
  }
}

Cette vérification empêche aussi un ancien échec de remplacer un succès plus récent. Applique la même vérification de pertinence aux messages de chargement et à la remise en état des commandes lorsque les appels se chevauchent.

L’anti-rebond réduit le nombre d’appels lancés. Efface la minuterie précédente à chaque frappe et démarre-en une nouvelle, par exemple de 300 ms. Saisir rapidement « paris » lance alors une seule requête après la pause. L’anti-rebond économise des requêtes ; il n’empêche pas à lui seul une réponse à un appel précédent encore en cours d’arriver tardivement.

Décider ce qui peut s’exécuter ensemble

Des requêtes indépendantes peuvent être lancées ensemble :

const [user, posts] = await Promise.all([
  getJSON(userUrl),
  getJSON(postsUrl),
]);

Pour des durées de 300 ms et 500 ms, les deux prennent environ 500 ms au lieu d’environ 800 ms en séquence. Promise.all est rejetée dès que l’une des promesses fournies est rejetée, mais elle n’annule pas les autres opérations.

Utilise Promise.allSettled lorsque des résultats partiels sont utiles. Elle attend toutes les promesses fournies et indique chaque résultat sous la forme { status: "fulfilled", value } ou { status: "rejected", reason }. Un tableau de bord peut ainsi afficher les panneaux ayant réussi à côté de celui qui a échoué.

Les requêtes dépendantes doivent rester en séquence. Si une seconde URL nécessite un identifiant renvoyé par la première requête, attends cet identifiant avant de construire la seconde requête.

Points clés

  • Passe un signal d’annulation avant d’appeler abort().
  • Intercepte les erreurs de récupération et de lecture du corps.
  • Ignore les résultats et les erreurs obsolètes.
  • L’anti-rebond réduit les appels ; une vérification de pertinence empêche les mises à jour obsolètes.
  • Utilise Promise.all pour des opérations indépendantes qui doivent toutes réussir.
  • Utilise Promise.allSettled lorsque des résultats partiels sont utiles.
  • Attends les données nécessaires avant de lancer une requête dépendante.
3

Lis des données entre origines et protège les identifiants

Une requête peut sembler correcte et pourtant échouer dans un navigateur parce que la page et l’API appartiennent à des origines différentes. Cette frontière est contrôlée conjointement par les règles du navigateur et les en-têtes de réponse du serveur. Tu identifieras l’origine, interpréteras les échecs des requêtes préliminaires et de CORS, et distingueras l’autorisation de lire une réponse de celle d’effectuer une action. Les identifiants nécessitent une décision distincte : tout ce qui est envoyé à un navigateur peut être examiné par son utilisateur.

3.1 Comprends la frontière des origines dans le navigateur

Une origine combine le schéma, l’hôte et le port d’une URL. Le chemin n’en fait pas partie. https://shop.example.com/cart et /help sur le même site partagent une origine. Passer à http://shop.example.com, https://api.example.com ou https://shop.example.com:8443 change l’origine. HTTPS utilise normalement le port 443.

Qui autorise la lecture de la réponse ?

La politique de même origine limite les ressources qu’un script de page peut lire. Pour une récupération depuis une autre origine, CORS permet au serveur de l’API d’accorder l’accès au moyen d’en-têtes de réponse. Une page sur https://notes.example.org qui appelle https://api.example.com/weather a besoin de l’autorisation de l’API pour lire la réponse.

Access-Control-Allow-Origin: https://notes.example.org accorde l’accès à cette origine. La valeur * autorise toutes les origines pour une requête sans identifiants. Si la réponse ne contient pas d’autorisation correspondante, le navigateur la cache à la page et fetch est rejeté avec une TypeError. La console fournit le diagnostic CORS ; JavaScript ne reçoit pas la raison détaillée.

Ajouter Access-Control-Allow-Origin à la requête JavaScript n’accorde pas d’autorisation. C’est un en-tête de réponse contrôlé par le serveur. Ajouter un en-tête de requête personnalisé peut au contraire provoquer une vérification préliminaire supplémentaire.

Pourquoi OPTIONS apparaît avant POST

Certaines requêtes vers une autre origine nécessitent une requête préliminaire. Le navigateur envoie d’abord OPTIONS, en indiquant la méthode prévue dans Access-Control-Request-Method et les noms des en-têtes non autorisés par défaut dans Access-Control-Request-Headers. Le serveur les autorise avec Access-Control-Allow-Methods et Access-Control-Allow-Headers, en plus de l’autorisation de l’origine.

Un GET, HEAD ou POST simple, avec seulement des en-têtes autorisés, peut éviter la requête préliminaire. Les types de contenu autorisés comprennent text/plain, application/x-www-form-urlencoded et multipart/form-data. Un POST JSON, un en-tête Authorization, PUT ou DELETE nécessite une requête préliminaire, sauf si une autorisation antérieure valide est en cache. Si la requête préliminaire est refusée, la requête réelle n’est pas envoyée.

Pour une requête simple, la requête réelle peut atteindre le serveur même si le navigateur bloque ensuite la lecture de sa réponse. CORS ne remplace donc pas l’autorisation côté serveur ni la vérification des entrées.

Les cookies ajoutent une exigence

La valeur par défaut credentials: "same-origin" n’envoie les cookies que pour les requêtes de même origine. credentials: "include" autorise également les cookies admissibles dans les requêtes vers d’autres origines. Les règles SameSite des cookies et les politiques relatives aux cookies tiers continuent de s’appliquer.

Pour permettre à JavaScript de lire une réponse associée à des identifiants, le serveur doit envoyer Access-Control-Allow-Credentials: true et nommer explicitement l’origine de la page. Access-Control-Allow-Origin: * ne fonctionne pas avec des identifiants. Ces en-têtes ne forcent pas un navigateur à envoyer un cookie qui serait autrement bloqué.

Diagnostiquer sans masquer le problème

mode: "no-cors" donne une réponse opaque avec l’état 0, sans corps ni en-têtes lisibles. Elle ne peut pas fournir de JSON à une page. Une requête qui fonctionne dans curl ne prouve pas non plus que CORS l’autorise dans le navigateur : les clients de terminal n’appliquent pas cette politique du navigateur.

Examine la console et l’onglet Réseau. Vérifie si la requête préliminaire a échoué ou si la réponse finale ne contenait pas l’autorisation nécessaire. Corrige la configuration des réponses de l’API ou fais passer l’appel par ton propre serveur. Pendant le développement, sers les pages depuis un serveur local : les pages file:// ont souvent des origines opaques. Un serveur local a toujours besoin d’une autorisation CORS lorsqu’il appelle une origine différente.

Points clés

  • Une origine est constituée d’un schéma, d’un hôte et d’un port.
  • Les en-têtes de réponse du serveur accordent l’autorisation de lecture entre origines.
  • La requête préliminaire vérifie la méthode et les en-têtes prévus avant la requête réelle.
  • CORS peut cacher une réponse après qu’une requête simple a déjà été traitée.
  • Les réponses associées à des identifiants nécessitent une origine explicite et un en-tête d’autorisation des identifiants.
  • no-cors produit une réponse opaque, et non du JSON lisible.

3.2 Garde les clés secrètes hors de la page

Une clé d’API identifie une application qui appelle une API, pour l’utilisation, les limites et la facturation. Un jeton d’accès accorde un accès pour un utilisateur ou une session. Toute personne possédant un identifiant utilisable peut être en mesure d’agir avec les droits associés : décide donc où le placer avant de l’ajouter à une requête.

Les en-têtes protègent l’emplacement, pas le secret vis-à-vis de l’utilisateur

Les fournisseurs peuvent exiger Authorization: Bearer <token>, X-API-Key: <key> ou un paramètre de requête comme api_key. Suis la documentation de l’API. Un en-tête évite de placer l’identifiant dans une URL complète qui peut se retrouver dans des journaux et des outils d’analyse. Un en-tête Authorization ou personnalisé dans un appel vers une autre origine déclenche normalement une requête préliminaire.

Un en-tête reste visible dans les outils de développement. Les visiteurs peuvent examiner le JavaScript qu’ils téléchargent et les requêtes qu’il envoie. Minifier le code ou cacher une valeur derrière une variable ne la rend pas secrète.

Suivre la clé dans une requête météo

Supposons que le code du navigateur appelle https://api.weather.example/v1/current?city=Lima&key=sk_live_4f9a2c. Toute personne qui ouvre l’onglet Réseau peut copier la clé et utiliser le quota du compte. Déplacer cette valeur dans une variable d’environnement utilisée lors de la compilation ne sert à rien si la compilation l’insère dans le JavaScript envoyé à la page.

Un secret conservé sur un serveur change le parcours :

  1. La page appelle son propre site à /api/weather?city=Lima.
  2. Le serveur de ce site ajoute le secret et contacte le fournisseur météo.
  3. Le serveur renvoie les données météo à la page sans inclure le secret dans la réponse.

Le serveur doit toujours contrôler l’accès à son point de terminaison et son utilisation. Conserver le secret du fournisseur sur un serveur ne rend pas inoffensive une utilisation publique illimitée.

Certains fournisseurs délivrent des clés pour navigateur destinées à être publiques. Applique les restrictions de domaine du fournisseur, limite les API autorisées et définis des quotas d’utilisation. N’utilise une clé de cette façon que si sa conception documentée le permet ; une clé serveur secrète ne devient pas une clé pour navigateur par l’ajout d’une restriction de domaine.

Réagir à une exposition

Ne place pas les fichiers d’identifiants sous contrôle de version, par exemple en indiquant .env dans .gitignore. Cela empêche que le fichier soit inclus dans un commit ; cela n’empêche pas une compilation côté client de publier une valeur intégrée au code. Si une clé est exposée, révoque-la et crée une clé de remplacement. La retirer du commit le plus récent laisse intacts l’historique antérieur et les éventuelles copies.

Protéger l’échange et réduire le gaspillage

Utilise HTTPS pour les appels d’API afin que les données et les identifiants soient chiffrés pendant leur transit. Un appel fetch d’une page HTTPS vers une API HTTP est bloqué comme contenu mixte. Le chiffrement n’empêche pas la personne qui utilise le navigateur de voir sa propre requête.

Une limite de requêtes plafonne l’utilisation, par exemple à 60 requêtes par minute. Les appels dépassant la limite peuvent renvoyer 429 Too Many Requests. Mets en cache les résultats appropriés, applique l’anti-rebond aux saisies de recherche et évite les appels en double. Si le serveur fournit Retry-After, respecte le délai indiqué au lieu de réessayer immédiatement à répétition.

La validation côté client facilite l’utilisation des formulaires, mais tout le monde peut appeler un point de terminaison sans passer par ton formulaire. Le serveur doit lui-même valider les requêtes et autoriser les actions. Lorsque tu affiches sa réponse, continue de traiter les chaînes comme du texte non fiable et insère-les avec textContent.

Points clés

  • Le code et les requêtes envoyés au navigateur exposent tous les identifiants qu’ils contiennent.
  • Une clé secrète doit rester sur le serveur qui appelle le fournisseur.
  • Restreins les clés publiques pour navigateur par domaine, par API et par quota.
  • Révoque une clé exposée ; la supprimer du code actuel ne suffit pas.
  • HTTPS chiffre les données en transit, tandis que le serveur doit toujours valider et autoriser les requêtes.
4

Conserve de petites quantités de données d’état dans le navigateur

Un paramètre ou un brouillon peut survivre à un rechargement sans nouvelle requête au serveur. Le stockage du navigateur rend cela pratique, mais ses valeurs sont des chaînes de caractères et leur durée de vie dépend du stockage choisi. Tu enregistreras et restaureras de petites quantités de données d’état, valideras les anciennes données avant de les utiliser et donneras une durée d’expiration aux résultats d’API mis en cache. Tu décideras aussi quelles données doivent être conservées ailleurs, car le stockage local n’est ni un coffre-fort à secrets ni l’unique copie sûre d’un travail important.

4.1 Enregistre des chaînes et restaure leurs types

Web Storage propose deux espaces de stockage clé-valeur : localStorage et sessionStorage. Ils utilisent les mêmes méthodes : le choix principal porte donc sur la durée de conservation des données et les onglets qui doivent les partager.

Choisir la durée de vie
StockageDurée de viePartage
localStorageSurvit à la fermeture de l’onglet et du navigateur jusqu’à suppression ou effacementPartagé par les pages de la même origine
sessionStorageSurvit aux rechargements pendant la session de page de l’ongletDistinct pour chaque onglet et chaque origine

Fermer l’onglet met fin à son stockage de session. Une page nouvellement ouverte avec un élément déclencheur peut commencer avec une copie du stockage de session de cet élément, mais les modifications ultérieures restent distinctes. N’utilise pas le stockage de session pour garder des informations secrètes vis-à-vis des scripts.

Le stockage dépend des origines. https://app.example.com ne peut pas partager son stockage avec http://app.example.com. Les chemins d’une même origine le partagent : un préfixe comme "notes-app:settings" aide donc à distinguer les clés de plusieurs applications.

Utiliser les méthodes de stockage
localStorage.setItem("notes-app:theme", "dark");
const theme = localStorage.getItem("notes-app:theme");
localStorage.removeItem("notes-app:theme");

setItem crée ou écrase une entrée. getItem renvoie sa valeur sous forme de chaîne ou null si elle est absente. removeItem supprime une entrée. clear() supprime toutes les entrées de cet espace de stockage pour l’origine, ce qui peut affecter d’autres fonctionnalités du même site. length et key(index) permettent d’examiner les clés.

Utilise ces méthodes plutôt que des affectations de propriétés comme localStorage.theme = "dark". Des clés comme "length" ou "key" peuvent entrer en conflit avec des membres intégrés lorsqu’on y accède comme à des propriétés.

Convertir les valeurs explicitement

Après localStorage.setItem("count", 5), la lecture donne "5". Ajouter directement 1 produit "51". Number(localStorage.getItem("count")) + 1 produit 6.

Un booléen stocké présente un piège similaire. setItem("darkMode", false) stocke "false", et une chaîne non vide est une valeur vraie dans un contexte booléen. Lis avec localStorage.getItem("darkMode") === "true" lorsque ce sont les deux chaînes stockées attendues.

Les objets et les tableaux nécessitent JSON :

localStorage.setItem("settings", JSON.stringify({
  theme: "dark",
  fontSize: 18,
}));
const settings = JSON.parse(localStorage.getItem("settings"))
  ?? { theme: "light", fontSize: 16 };

Sans sérialisation, un objet ordinaire devient "[object Object]". JSON.parse(null) donne null, donc la valeur par défaut couvre le cas d’une entrée manquante. Une chaîne stockée mal formée nécessite toujours try/catch, et les données analysées doivent être vérifiées avant utilisation pour s’assurer qu’elles ont la bonne structure.

Limiter le travail

Les appels à Web Storage sont synchrones : JavaScript attend chacun d’eux sur le thread principal. Utilise-le pour des paramètres, un brouillon ou une courte liste, pas pour de grandes collections ou des fichiers. IndexedDB fournit un stockage asynchrone pour des données structurées plus volumineuses.

Les navigateurs actuels autorisent généralement environ 5 Mio dans chaque espace Web Storage par origine. Un stockage plein peut amener setItem à lever QuotaExceededError ; l’accès peut aussi échouer en raison des paramètres de confidentialité du navigateur. Gère l’échec sans empêcher le reste de l’application de fonctionner. Les outils de développement affichent les espaces de stockage dans l’onglet Application de Chrome et Edge ou dans l’onglet Stockage de Firefox, où la suppression d’entrées aide à tester les premières visites.

Points clés

  • Choisis localStorage pour les paramètres partagés persistants et sessionStorage pour l’état propre à la session d’un onglet.
  • Les espaces de stockage sont séparés par origine.
  • getItem renvoie une chaîne de caractères ou null.
  • Sérialise les objets avec JSON et restaure leurs types à la lecture.
  • Gère les échecs de stockage et limite la taille des écritures synchrones.

4.2 Restaure l’état et fais expirer les données en cache

Une application charge généralement au démarrage et enregistre à chaque modification. Lis une liste enregistrée à l’ouverture de la page, affiche-la et enregistre la liste mise à jour après une modification. Le stockage du navigateur est une copie pratique : il peut être absent, endommagé, obsolète ou effacé.

Valider avant de restaurer

Cette fonction de chargement attend un tableau de chaînes enregistré :

function loadTodos() {
  try {
    const value = JSON.parse(localStorage.getItem("todos"));
    if (Array.isArray(value) && value.every(item => typeof item === "string")) {
      return value;
    }
  } catch {
    // Continue with an empty list if reading or parsing fails.
  }
  return [];
}

JSON.parse seul ne prouve pas que la valeur est un tableau ni que ses éléments conviennent à l’application. Une valeur JSON valide comme 42 n’a tout de même pas la bonne structure. Une valeur comportant une version comme { version: 2, todos: [...] } permet au code plus récent de reconnaître les anciens formats et de les convertir ou de restaurer une valeur par défaut.

Enregistre la liste en mémoire avec localStorage.setItem("todos", JSON.stringify(todos)) après chaque modification. Intercepte aussi les échecs d’écriture ; une page doit pouvoir continuer à fonctionner même si elle ne peut pas conserver l’état pour le prochain rechargement. Un brouillon de formulaire propre à une seule visite peut utiliser sessionStorage.

Horodater les réponses en cache
localStorage.setItem("weather", JSON.stringify({
  savedAt: Date.now(),
  data,
}));

Lors d’un chargement ultérieur, vérifie d’abord la structure et l’horodatage de l’objet en cache. Son âge est Date.now() - savedAt. Ne l’utilise que tant que cet âge est inférieur à 10 * 60 * 1000, soit 600 000 ms. Une valeur enregistrée à 10:00:00 a 450 000 ms à 10:07:30 et peut être utilisée. À 10:12:00, elle a 720 000 ms : récupère donc une nouvelle valeur. À exactement 600 000 ms, elle est expirée selon cette règle.

L’expiration relève de la logique de l’application : localStorage ne supprime pas une entrée lorsque ton intervalle de fraîcheur prend fin. Rejette un horodatage manquant ou invalide au lieu de considérer comme récente une donnée d’âge inconnu. Tu peux laisser des données périmées visibles lorsqu’une actualisation échoue si elles sont indiquées comme anciennes.

Synchroniser les autres onglets

Lorsqu’un onglet modifie localStorage, les autres onglets de la même origine reçoivent un événement storage. L’onglet qui écrit ne reçoit pas son propre événement. L’événement expose key, oldValue, newValue et url.

window.addEventListener("storage", (event) => {
  if (event.key === "theme") applyTheme(event.newValue);
});

Applique aussi immédiatement le thème dans l’onglet qui écrit. Gère null lorsqu’une clé est supprimée. Un événement de stockage ne remplace pas la mise à jour de l’état de ta propre page.

Décider de ce qui doit être conservé ailleurs

Ne place pas de mots de passe, de numéros de carte de paiement ou de clés d’API secrètes dans Web Storage. Les scripts de l’origine peuvent le lire, y compris le code tiers et les scripts injectés. Efface les données personnelles concernées à la déconnexion sur les appareils partagés. Conserve les travaux importants sur un serveur ou propose leur exportation, car les utilisateurs peuvent effacer les données du site et les sessions privées les suppriment.

Les cookies sont différents : les requêtes correspondantes les envoient au serveur, et les scripts de la page ne peuvent pas lire les cookies HttpOnly. Ils sont petits, environ 4 Ko chacun. Web Storage reste dans le navigateur et peut être lu par les scripts. IndexedDB convient aux données structurées plus volumineuses grâce à une API asynchrone.

Points clés

  • Valide les données analysées et utilise une solution de repli si elles sont absentes ou endommagées.
  • La fraîcheur du cache dépend d’un horodatage et d’une limite d’âge définie par l’application.
  • L’événement storage atteint les autres onglets de la même origine, pas celui qui écrit.
  • Ne conserve pas de secrets ni de données irremplaçables dans Web Storage.
5

Utilise les fonctionnalités de localisation et de presse-papiers

Les API du navigateur donnent à une page accès à des fonctionnalités comme la localisation et le presse-papiers. Leur disponibilité dépend du navigateur, du contexte de sécurité de la page et des choix de l’utilisateur. Tu détecteras une fonctionnalité avant de l’appeler, demanderas l’autorisation à un moment approprié et géreras le succès ou le refus. Une interaction complète comprend un retour visible et un autre moyen de terminer la tâche, comme saisir une ville ou copier au clavier un texte sélectionné.

5.1 Demande une position avec une solution de repli

La géolocalisation est une API du navigateur : une fonctionnalité fournie par le navigateur, distincte du langage JavaScript. Comme d’autres fonctionnalités de l’appareil, elle peut être indisponible ou refusée. Une page météo doit continuer à fonctionner lorsqu’un lecteur choisit de saisir une ville.

Vérifier la fonctionnalité et le contexte

Détecte la fonctionnalité elle-même avec "geolocation" in navigator. Vérifier le nom d’un navigateur est moins fiable : les versions et les paramètres modifient ce qui est disponible. La géolocalisation nécessite un contexte sécurisé, normalement HTTPS ; http://localhost convient aussi pour le développement. window.isSecureContext indique si la page actuelle remplit cette condition. Le simple HTTP sur l’adresse réseau d’un autre appareil n’est pas équivalent à localhost.

Explique pourquoi la position est utile et demande-la lorsque le lecteur clique sur « Utiliser ma position ». Le navigateur gère la demande d’autorisation. Une personne peut l’autoriser ou la bloquer, et un refus antérieur peut faire échouer un appel ultérieur sans nouvelle demande. L’utilisateur peut modifier cette décision dans les paramètres du site.

Lire le résultat de la fonction de rappel

navigator.geolocation.getCurrentPosition(success, error, options) utilise des fonctions de rappel. En cas de succès, position.coords contient la latitude et la longitude en degrés décimaux et accuracy en mètres. La précision correspond à un rayon d’incertitude estimé, pas à une précision décimale supplémentaire. En cas d’échec, le code 1 signifie que l’autorisation est refusée, 2 que la position est indisponible et 3 que le délai a expiré.

Les options contrôlent la tentative :

  • enableHighAccuracy : demande une meilleure précision ; valeur par défaut false.
  • timeout : limite d’attente en millisecondes ; valeur par défaut Infinity.
  • maximumAge : âge maximal d’une position en cache acceptable ; valeur par défaut 0.

Utilise un délai fini pour que la page puisse sortir de l’attente. watchPosition observe les mises à jour au fil du temps et renvoie un identifiant ; passe cet identifiant à clearWatch lorsque le suivi doit s’arrêter.

Encapsuler les fonctions de rappel pour utiliser await
function getPosition(options) {
  return new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(resolve, reject, options);
  });
}

async function useLocation() {
  if (!("geolocation" in navigator)) {
    showCityInput();
    return;
  }
  try {
    const { coords } = await getPosition({ timeout: 10000 });
    const url = new URL("https://api.example.com/weather");
    url.searchParams.set("lat", coords.latitude.toFixed(2));
    url.searchParams.set("lon", coords.longitude.toFixed(2));
    await loadWeather(url);
  } catch {
    showCityInput();
  }
}

Ici, showCityInput affiche la commande de saisie manuelle et loadWeather demande et affiche la météo. Relie useLocation au bouton de localisation. Le bloc catch couvre l’échec de localisation et la requête météo ; dans les deux cas, la saisie manuelle reste disponible.

Ne demander que la précision utile

Une position de latitude 52.3676, de longitude 4.9041 et de précision 35 a un rayon estimé d’environ 35 m. Arrondir à 52.37 et 4.90 réduit la précision envoyée au service météo. Un intervalle de latitude de 0,01° représente environ 1,1 km ; l’espacement des longitudes varie selon la latitude. Cette précision régionale convient à une prévision sans partager les coordonnées les plus détaillées.

Lorsque l’API Permissions est disponible, navigator.permissions.query({ name: "geolocation" }) indique "granted", "denied" ou "prompt". Détecte et gère aussi cette API. Son état aide à adapter l’interface, mais ne remplace pas la gestion des erreurs de l’appel de localisation.

Points clés

  • Détecte la géolocalisation et utilise un contexte sécurisé.
  • Demande la position après une action explicite de l’utilisateur et en indiquant pourquoi.
  • La latitude et la longitude sont exprimées en degrés ; la précision est exprimée en mètres.
  • Définis un délai fini et propose une saisie manuelle en cas d’échec.
  • N’envoie que la précision de localisation nécessaire à la fonctionnalité.
  • L’état de l’autorisation ne garantit pas une position exploitable.

5.2 Copie du texte et découvre une autre API du navigateur

L’API du presse-papiers permet à une page de copier du texte sans demander au lecteur de le sélectionner d’abord. Comme la géolocalisation, elle nécessite des vérifications de disponibilité, une action appropriée de l’utilisateur, une gestion des erreurs et une solution de repli.

Copier pendant le clic

navigator.clipboard.writeText(text) renvoie une promesse. Attends qu’elle soit tenue avant d’annoncer le succès. Un contexte sécurisé est obligatoire et une opération refusée peut entraîner un rejet avec NotAllowedError. Appelle cette méthode directement depuis un gestionnaire de clic : Firefox et Safari exigent une interaction récente de l’utilisateur, tandis que les exigences de Chromium peuvent aussi dépendre de l’autorisation d’écriture dans le presse-papiers.

copyButton.addEventListener("click", async () => {
  try {
    if (!navigator.clipboard?.writeText) {
      throw new Error("Copy unavailable");
    }
    await navigator.clipboard.writeText(codeField.value);
    copyButton.textContent = "Copied!";
  } catch {
    codeField.focus();
    codeField.select();
    copyButton.textContent = "Copy selected text: Ctrl+C / Cmd+C";
  }
  setTimeout(() => {
    copyButton.textContent = "Copy";
  }, 2000);
});

codeField est un champ de saisie ou une zone de texte et copyButton est le bouton de la page. Si la copie échoue, la sélection du texte permet de passer par le clavier : Ctrl+C sur de nombreux systèmes ou Cmd+C sur macOS. Le libellé redevient « Copy » après 2 000 ms. N’affiche jamais « Copied! » avant que la promesse soit tenue.

La lecture utilise navigator.clipboard.readText() et fait l’objet de contrôles plus stricts, car un presse-papiers peut contenir des données privées provenant d’autres applications. Un navigateur peut exiger une autorisation ou afficher une demande de collage. L’autorisation d’écrire ne garantit pas l’autorisation de lire.

Considérer la connectivité comme un indice

navigator.onLine et les événements online et offline de la fenêtre aident à afficher une bannière de connexion. Ils ne permettent pas de savoir si ton API est accessible. Un appareil peut avoir une connexion réseau alors que le serveur de l’API est en panne ou inaccessible.

window.addEventListener("offline", () => {
  status.textContent = "You are offline.";
});

Continue de gérer les erreurs autour de fetch même lorsque navigator.onLine est vrai. Utilise une région dynamique adaptée pour le message d’état.

Lire une recherche partageable

L’API URL lit la chaîne de requête de la page elle-même et construit aussi des URL d’API. Sur https://books.example.org/search?q=dune, new URL(location.href).searchParams.get("q") renvoie "dune". Lis cette valeur au chargement pour restaurer une recherche depuis un lien partagé. Un paramètre manquant renvoie null : décide donc de ce que l’écran initial doit afficher dans ce cas.

Utiliser une méthode d’apprentissage

Pour une autre API du navigateur, lis sa syntaxe, ses règles de contexte sécurisé et d’autorisation, son tableau de compatibilité et son statut Baseline sur MDN. Détecte ensuite la fonctionnalité, appelle-la depuis une action de l’utilisateur lorsque c’est nécessaire, traite sa promesse ou ses fonctions de rappel et propose une alternative si elle est absente ou refusée.

L’API Notifications affiche des notifications système après autorisation ; Web Share ouvre le menu de partage d’un appareil lorsqu’il est pris en charge ; Canvas dessine des graphismes ; les API multimédias contrôlent l’audio et la vidéo. Une API de cartographie tierce peut ajouter une bibliothèque et une clé de fournisseur. Ses identifiants suivent les mêmes règles concernant les clés secrètes que ceux de tout autre service. Tester un navigateur sur localhost ne prouve pas qu’un autre appareil ou navigateur dispose de la même prise en charge et du même contexte.

Points clés

  • Attends writeText avant d’annoncer que la copie a réussi.
  • Prévois une solution de copie au clavier si l’accès au presse-papiers échoue.
  • La lecture du presse-papiers obéit à des règles d’autorisation distinctes et plus strictes.
  • L’état en ligne ne garantit pas que l’API est accessible.
  • Utilise les paramètres d’URL pour restaurer une recherche partageable.
  • Vérifie la compatibilité, détecte les fonctionnalités et gère les refus pour chaque API du navigateur.

Fetch et API du navigateur : exemples

5 Leçons Interactives

1

Construis et mets à jour une liste de lecture

14 étapes
Suis une requête depuis son URL jusqu’à sa réponse JSON, puis soumets un nouvel enregistrement et traite le résultat du serveur.
  1. 1
    IntroductionSuis un échange

    Une page de liste de lecture doit charger des livres et ajouter une note sur l’un d’eux. La page est le client ; l’API est le serveur. Chaque échange comprend une requête qui décrit l’action et une réponse qui décrit son résultat.

    Nous allons d’abord lire l’échange, puis relier les deux étapes asynchrones du chargement JSON et enfin soumettre une modification. La réponse du serveur détermine ce que la page peut afficher ensuite en toute sécurité.

  2. 2
    ExempleLis la ressource et les filtres

    La page demande GET https://api.example.com/books?author=Le%20Guin&limit=5.

    GET demande une lecture. /books désigne la ressource. La requête filtre par auteur et limite le nombre de résultats. %20 représente l’espace dans « Le Guin ». La documentation de l’API détermine ces noms de paramètres ; la page ne peut pas choisir un autre nom et s’attendre à ce que le service le comprenne.

  3. 3
    Point cléDistingue le code d’état de la connexion

    Une réponse peut indiquer 200 OK avec un livre ou 404 Not Found avec une erreur. Les deux prouvent qu’un serveur a répondu. Une erreur de connexion ne fournit aucun code d’état HTTP à la page.

    Examine l’onglet Réseau pour voir l’URL complète, la méthode, le code d’état, les en-têtes et le corps. Si l’API a renvoyé le JSON attendu, examine ensuite le code qui le lit ou l’affiche.

  4. 4
    DéfiChoisis une méthode pour une modification

    Une note existe déjà. La page doit modifier uniquement son champ done tout en conservant son texte. Quelle méthode HTTP convient à cette opération et pourquoi GET serait-elle incorrecte ?

    ---reveal---

    Utilise PATCH pour la mise à jour partielle. GET est une méthode de lecture sûre et ne doit pas servir à demander une modification de données. PUT décrirait un remplacement complet et pourrait réinitialiser les champs omis du corps.

  5. 5
    ExplicationAttends la réponse

    Commence par const response = await fetch(url). Cela attend l’arrivée des en-têtes de réponse et fournit un objet Response, pas les livres analysés.

    La réponse peut tout de même être une erreur HTTP. La promesse de fetch est tenue pour un 404 parce qu’une réponse existe. Vérifie response.ok avant de considérer que l’opération a réussi ; cette propriété est vraie pour les codes d’état de 200 à 299 inclus.

  6. 6
    ExempleVérifie et lis le corps

    Continue dans la fonction asynchrone :

    if (!response.ok) {
      throw new Error(`HTTP error ${response.status}`);
    }
    const data = await response.json();
    

    La seconde attente lit et analyse le corps. data est maintenant une valeur JavaScript. Un bloc try/catch externe peut gérer à la fois l’erreur de code d’état levée ici et les échecs de récupération ou d’analyse du corps.

  7. 7
    ExempleTrouve le tableau imbriqué

    Supposons que le corps soit {"results":[{"title":"Dune"}],"total":1}.

    La première étape, data.results, donne accès au tableau. [0] donne accès à son premier objet. .title donne "Dune". Une fonction de rendu doit recevoir data.results, pas tout l’objet englobant. L’aperçu de la réponse dans l’onglet Réseau est utile lorsque la structure de l’API diffère de celle attendue par la page.

  8. 8
    DéfiDiagnostique la valeur manquante

    Le code utilise const data = response.json() puis essaie data.results[0]. Le corps est bien du JSON valide contenant un tableau results. Que manque-t-il ?

    ---reveal---

    Attends le corps : const data = await response.json(). Sans cette attente, data est une promesse et ne possède pas de propriété results. Le premier await fetch(...) n’a pas attendu aussi l’analyse JSON.

  9. 9
    ConseilPréserve la ponctuation dans une recherche

    Construis les paramètres de requête avec l’API URL :

    const url = new URL("https://api.example.com/search");
    url.searchParams.set("q", "rock & roll");
    

    La valeur devient rock+%26+roll. L’esperluette reste dans l’expression recherchée au lieu de séparer la requête. Réutilise la réponse analysée après le chargement : appeler une seconde méthode de lecture du corps sur la même réponse échoue, car le corps a été consommé.

  10. 10
    ExemplePrépare une soumission JSON

    Pour créer une note, sérialise les champs et indique leur format :

    const response = await fetch("https://api.example.com/notes", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ title: "Read", done: false }),
    });
    

    La méthode demande une création, l’en-tête déclare le format JSON et le corps contient du texte JSON plutôt qu’un objet ordinaire.

  11. 11
    LienUtilise l’enregistrement stocké

    Le serveur peut renvoyer 201 Created avec {"id":31,"title":"Read","done":false}. Ajoute cet enregistrement renvoyé à l’état de la page. Son identifiant permet à une action ultérieure d’appeler /notes/31.

    Pour un formulaire avec des fichiers, passe FormData au lieu de JSON et laisse le navigateur définir son délimiteur multipart. Une requête GET ne peut pas transporter de corps avec fetch ; les champs de recherche vont dans la chaîne de requête.

  12. 12
    DéfiGère un succès sans corps

    La suppression d’une note enregistrée renvoie 204. Le code vérifie response.ok, puis appelle response.json() et affiche une erreur. La suppression a-t-elle nécessairement échoué et que faut-il changer ?

    ---reveal---

    Non : 204 indique une opération réussie sans corps. Ignore l’analyse JSON pour ce code d’état et mets la page à jour après l’avoir vérifié. L’échec de l’analyse vient de la tentative de lecture d’un contenu vide, pas d’une preuve que la suppression a échoué.

  13. 13
    DéfiExamine un processus complet de soumission

    Un bouton d’enregistrement peut recevoir deux clics pendant l’exécution d’un POST. Une réponse réussie fournit un nouvel identifiant. Nomme les deux comportements de la page qui empêchent un doublon accidentel et conservent cet identifiant.

    ---reveal---

    Désactive le bouton pendant la requête et réactive-le dans finally. En cas de succès, mets la page à jour à partir de l’enregistrement renvoyé, y compris son identifiant. Le bouton empêche les clics répétés ; le résultat du serveur fournit des valeurs qui n’existaient pas dans les données soumises.

  14. 14
    RécapitulatifVérifie l’échange à chaque étape

    Lorsqu’une requête ne fonctionne pas comme prévu, examine l’opération dans l’ordre : l’URL et la méthode documentées, le code d’état réel, la méthode choisie pour lire le corps et la structure des données transmises à la page.

    Pour une écriture, vérifie aussi le type de contenu et le corps sérialisé. Un succès sans contenu ne nécessite pas de lecture JSON. Une réponse à une création doit fournir l’enregistrement sauvegardé utilisé pour la prochaine modification ou suppression.

2

Construis une page de recherche qui reste à jour

18 étapes
Affiche une liste, mets en forme un prix et une date et garde l’état des requêtes correct pendant les recherches lentes, échouées ou simultanées.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionGarde l’écran cohérent avec la recherche
  2. 2
    ExempleRemplace la liste précédente
  3. 3
    Point cléDistingue zéro des données manquantes
  4. 4
    DéfiTraite les textes et les liens externes
  5. 5
    ExempleLis l’unité de temps
  6. 6
    ExplicationChoisis le fuseau d’affichage
  7. 7
    ExempleMets en forme les unités divisionnaires documentées
  8. 8
    DéfiSépare les paramètres régionaux de la valeur
  9. 9
    ExplicationCommence par rendre l’attente visible
  10. 10
    ExempleTermine tous les parcours
  11. 11
    DéfiReconnais une recherche réussie sans résultat
  12. 12
    ConseilAttends avant de réessayer après un échec temporaire
  13. 13
    ExempleObserve l’ordre d’achèvement
  14. 14
    ExempleAnnule une requête obsolète
  15. 15
    LienRéduis les appels pendant la saisie
  16. 16
    DéfiChoisis un succès partiel
  17. 17
    DéfiProtège toute l’interaction en cours
  18. 18
    RécapitulatifTeste l’interface avec des réponses imparfaites
3

Diagnostique un appel d’API entre origines

10 étapes
Suis l’autorisation de lecture du navigateur séparément de l’autorisation du serveur et de la protection d’une clé de fournisseur.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionDistingue deux questions d’autorisation
  2. 2
    ExempleCompare les origines complètes
  3. 3
    ExplicationLis l’autorisation du serveur
  4. 4
    ExempleSuis d’abord la requête préliminaire
  5. 5
    DéfiExplique un succès limité au terminal
  6. 6
    ExempleTrouve la clé exposée
  7. 7
    LienDéplace la frontière du secret
  8. 8
    DéfiDistingue le transport du secret
  9. 9
    DéfiVérifie les cookies et les réponses lisibles
  10. 10
    RécapitulatifDiagnostique la frontière en échec
4

Restaure une liste enregistrée sans bloquer la page

12 étapes
Choisis la durée de vie du stockage, préserve les types de données, valide les données restaurées et applique une règle de fraîcheur du cache.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionConserve une copie locale pratique
  2. 2
    ExplicationChoisis ce qui doit persister
  3. 3
    ExempleConserve un tableau sous forme de texte
  4. 4
    DéfiRestaure le type attendu
  5. 5
    ConseilGère une écriture qui dépasse l’espace disponible
  6. 6
    ExempleNe te limite pas à vérifier la syntaxe JSON
  7. 7
    ExempleAssocie une heure au cache
  8. 8
    DéfiCalcule si le cache est encore frais
  9. 9
    LienSuis un thème entre les onglets
  10. 10
    Point cléProtège les données importantes
  11. 11
    DéfiGère un ancien format enregistré
  12. 12
    RécapitulatifTeste une première visite et une visite ultérieure
5

Ajoute des boutons de localisation et de copie utiles

13 étapes
Construis des interactions qui tiennent compte des autorisations, avec une détection de fonctionnalités, un retour clair et des alternatives manuelles.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionRends l’action compréhensible
  2. 2
    ExplicationVérifie le contexte et la fonctionnalité
  3. 3
    ConseilFais la demande lorsque la fonctionnalité est utile
  4. 4
    ExempleDéfinis une attente limitée
  5. 5
    ExempleNe lis que la précision utile
  6. 6
    DéfiGère un refus
  7. 7
    ExempleÉcris pendant le clic
  8. 8
    Point cléAttends avant d’annoncer la copie
  9. 9
    DéfiConsidère un signal de connexion comme un indice
  10. 10
    LienRestaure une recherche depuis son lien
  11. 11
    ConseilVérifie une autre fonctionnalité du navigateur
  12. 12
    DéfiExamine les deux boutons ensemble
  13. 13
    RécapitulatifTeste aussi les choix de la personne

Fetch et API du navigateur : QCM

40 Questions Pratiques en 4 séries

Série 1 : Requêtes, résultats et fonctionnalités du navigateur10 Questions Pratiques

Question 1 sur 10

Une réponse a le code d’état 403. Que dit ce code à la page ?
  1. Le serveur n’a pas pu recevoir la requête.
  2. Le serveur exige une redirection de l’URL de la ressource.
  3. Le serveur a compris la requête mais l’a refusée.
  4. Le serveur a accepté la requête avec un corps vide.
Afficher la réponseMasquer la réponse
Réponse : C
Une réponse 403 signifie que le serveur a compris la requête et refuse de la satisfaire. Elle ne prouve pas que l’utilisateur a fourni des identifiants valides ni qu’une connexion résoudra le refus. Une connexion réseau échouée ne fournirait pas de code d’état HTTP lisible par la page.

Question 2 sur 10

Une API renvoie 200 avec {"items":[{"name":"Cedar"}]}. Quelle affectation stocke le nom du premier élément après const response = await fetch(url) ?
  1. const name = (await response.json()).items[0].name;
  2. const name = response.json().items[0].name;
  3. const name = (await response.json())[0].items.name;
  4. const name = (await response.text()).items[0].name;
Afficher la réponseMasquer la réponse
Réponse : A
Attends que json() lise et analyse le corps, puis suis la propriété externe items jusqu’au premier objet du tableau. Appeler json() sans await laisse une promesse qui ne possède pas de tableau items. La lecture avec text() donne une chaîne, pas l’objet analysé nécessaire pour accéder aux propriétés.

Question 3 sur 10

Un point de terminaison accepte un corps JSON. Quelle valeur body doit-il recevoir lors de l’envoi de { label: "Read" } ?
  1. JSON.parse({ label: "Read" })
  2. String({ label: "Read" })
  3. { label: "Read" }.toString()
  4. JSON.stringify({ label: "Read" })
Afficher la réponseMasquer la réponse
Réponse : D
JSON.stringify convertit l’objet en texte JSON valide pour le corps de la requête. Convertir un objet ordinaire avec String ou toString() produit "[object Object]", que le point de terminaison JSON ne peut pas analyser. La requête nécessite aussi la méthode documentée et un en-tête de type de contenu JSON.

Question 4 sur 10

Une API renvoie { remaining: 0, owner: null }. Comment la page peut-elle afficher le nombre restant tout en utilisant "Unknown" pour le nom du propriétaire manquant ?
  1. data.remaining || "n/a"; data.owner?.name ?? "Unknown";
  2. data.remaining ?? "n/a"; data.owner?.name ?? "Unknown";
  3. data.remaining ?? "n/a"; data.owner.name ?? "Unknown";
  4. data.remaining || "n/a"; data.owner.name || "Unknown";
Afficher la réponseMasquer la réponse
Réponse : B
La coalescence des nuls conserve le nombre valide zéro et le chaînage optionnel évite de lire name depuis null. Utiliser || pour le nombre remplace zéro, car zéro est une valeur fausse dans un contexte booléen. Une valeur de repli après data.owner.name ne peut pas aider si l’accès à name a déjà levé une erreur.

Question 5 sur 10

Une API indique que amount: 3785, currency: "USD" représente des unités divisionnaires entières. Quel nombre faut-il passer à l’outil de mise en forme monétaire ?
  1. 3785
  2. 37.85
  3. 378.5
  4. 0.3785
Afficher la réponseMasquer la réponse
Réponse : B
Le dollar américain compte 100 unités divisionnaires par unité principale : l’entier documenté représente donc 37,85 dollars américains. Passer directement 3785 afficherait un montant 100 fois trop élevé. Intl.NumberFormat met en forme le nombre reçu ; il ne déduit pas qu’un montant d’API est exprimé en cents.

Question 6 sur 10

Une recherche désactive son bouton, puis attend une requête. Le bouton n’est réactivé qu’après l’affichage des résultats en cas de succès. Une requête échouée le laisse désactivé. Où placer l’instruction commune de réactivation ?
  1. Dans la branche de succès après avoir effacé l’état.
  2. Dans une minuterie lancée avant de vérifier la réponse.
  3. Dans un bloc catch qui remplace toute remise en état après succès.
  4. Dans un bloc finally autour de l’opération attendue.
Afficher la réponseMasquer la réponse
Réponse : D
finally s’exécute après l’opération protégée, qu’elle réussisse ou lève une exception : c’est donc le bon endroit pour la remise en état nécessaire dans les deux cas. Placer la réinitialisation uniquement dans catch oublie le succès ; la laisser après l’affichage oublie l’échec. Une minuterie réinitialiserait les commandes sans savoir si la requête est terminée.

Question 7 sur 10

Une page se trouve à https://studio.example.org/edit. Quelle est son origine ?
  1. https://studio.example.org
  2. https://studio.example.org/edit
  3. https://example.org
  4. http://studio.example.org
Afficher la réponseMasquer la réponse
Réponse : A
L’origine est constituée du schéma, de l’hôte et du port ; HTTPS utilise son port par défaut lorsqu’aucun port n’est indiqué. Le chemin /edit désigne une ressource dans l’origine et ne fait pas partie de l’origine elle-même. Passer le schéma à HTTP créerait une origine différente, même avec le même hôte.

Question 8 sur 10

Une compilation côté client lit une clé secrète de fournisseur dans un fichier d’environnement ignoré et l’envoie dans un en-tête de requête HTTPS. Un visiteur copie la clé depuis l’onglet Réseau. Quelle modification protège une clé de remplacement des visiteurs du navigateur ?
  1. Supprimer le fichier ignoré et garder la même compilation téléchargée.
  2. Recompiler avec un nom de variable plus court et garder le même en-tête.
  3. Révoquer la clé exposée et faire ajouter sa remplaçante par un serveur.
  4. Placer une clé de remplacement dans le corps et supprimer l’en-tête.
Afficher la réponseMasquer la réponse
Réponse : C
Révoque la clé copiée, puis conserve sa remplaçante sur un serveur qui appelle le fournisseur. Un fichier d’environnement ignoré protège le contrôle de version, mais une compilation côté client peut tout de même publier ses valeurs. HTTPS protège le transit, et déplacer la clé entre les champs d’une requête du navigateur ne la cache pas à son utilisateur.

Question 9 sur 10

Après localStorage.setItem("visits", 8), quelle est la valeur de localStorage.getItem("visits") + 1 ?
  1. "81"
  2. 9
  3. "9"
  4. 81
Afficher la réponseMasquer la réponse
Réponse : A
Web Storage renvoie la chaîne "8" : + 1 effectue donc une concaténation de chaînes et donne "81". Il ne restaure pas le type numérique passé à setItem. Convertis la chaîne stockée avec Number avant l’addition si le résultat attendu est le nombre 9.

Question 10 sur 10

Une demande de position échoue avec le code d’erreur de géolocalisation 1. Quelle réponse à l’utilisateur convient à cet échec ?
  1. Expliquer que le délai a expiré et recommencer immédiatement.
  2. Expliquer qu’aucune position n’existe et cacher le formulaire météo.
  3. Expliquer que la localisation a été refusée et proposer la saisie d’une ville.
  4. Expliquer qu’aucune position n’était disponible et proposer une autre tentative.
Afficher la réponseMasquer la réponse
Réponse : C
Le code d’erreur de géolocalisation 1 signifie que l’autorisation a été refusée : propose donc un autre moyen d’indiquer la position. L’expiration du délai correspond au code 3 et n’explique pas cet échec. Des demandes répétées ne peuvent pas imposer l’autorisation ; un refus mémorisé peut obliger l’utilisateur à modifier les paramètres du site dans le navigateur.
Série 2 : Suis les données dans l’interface10 Questions Pratiques

Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.

Question 1 sur 10

Un appel fetch renvoie un objet Response avec le code d’état 502. Le code possède un gestionnaire catch mais ne vérifie jamais response.ok. Pourquoi son message d’erreur HTTP pourrait-il ne jamais apparaître ?
  1. Une erreur HTTP ne provoque un rejet qu’après la fin du gestionnaire catch.
  2. Une erreur HTTP tient la promesse de fetch ; le code doit examiner son état.
  3. Une réponse 502 reste cachée jusqu’à la lecture de son corps JSON.
  4. Un gestionnaire catch ne reçoit les codes d’état du serveur qu’avec no-cors.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 2 sur 10

Un point de terminaison de suppression documenté renvoie 204 en cas de succès. Que doit faire la page avant de tenter d’analyser du JSON ?
  1. Reconnaître 204 comme un échec et répéter la même suppression.
  2. Reconnaître 204 comme un succès et analyser un objet vide.
  3. Reconnaître 204 comme une redirection et demander la même URL.
  4. Reconnaître 204 comme un succès et ne pas lire le corps.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 3 sur 10

Une nouvelle recherche ajoute ses éléments aux anciens résultats. Un bouton distinct « Charger plus » doit continuer à ajouter des pages. Comment le comportement de rendu doit-il différer ?
  1. Vider pour une nouvelle recherche ; ajouter pour une autre page.
  2. Ajouter pour une nouvelle recherche ; vider pour une autre page.
  3. Vider pour les deux actions avant d’ajouter leurs résultats.
  4. Ajouter pour les deux actions et ne retirer que les éléments vides.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 4 sur 10

Deux lectures indépendantes prennent environ 240 ms et 680 ms. Sans tenir compte du temps supplémentaire, combien de temps l’attente des deux avec Promise.all devrait-elle prendre ?
  1. Environ 920 ms.
  2. Environ 240 ms.
  3. Environ 680 ms.
  4. Environ 440 ms.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 5 sur 10

Une recherche de « lo » commence, puis une recherche de « lotus ». La fin d’un ancien appel peut cacher le nouveau message de chargement et un ancien échec peut remplacer des résultats plus récents. L’annulation n’est pas disponible dans la fonction enveloppante de requête. Quelle règle de mise à jour garde tout l’écran lié à la recherche actuelle ?
  1. Seuls les appels réussis comparent leur numéro avant l’affichage.
  2. Seuls les appels échoués comparent leur numéro avant l’erreur.
  3. Seul le dernier appel peut modifier résultats, erreurs ou chargement.
  4. Chaque appel vide la liste à la fin de sa propre requête.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 6 sur 10

Depuis une autre origine, une page envoie un POST JSON avec Content-Type: application/json. Aucune autorisation de requête préliminaire n’est en cache. Que doit vérifier le navigateur avant d’envoyer ce POST ?
  1. Une réponse GET contenant le même JSON que le POST prévu.
  2. Une réponse OPTIONS autorisant l’origine, la méthode et les en-têtes.
  3. Une requête OPTIONS contenant l’en-tête de réponse autorisant l’origine.
  4. Une réponse POST déclarant que la page a désactivé les règles de même origine.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 7 sur 10

Un formulaire à plusieurs étapes doit survivre aux rechargements dans son onglet, mais prendre fin avec la session de cet onglet. Quel stockage convient ?
  1. Utiliser localStorage et garder l’entrée jusqu’à sa suppression par le code.
  2. Garder la progression uniquement dans une variable JavaScript en mémoire.
  3. Utiliser localStorage et effacer l’entrée à chaque chargement de page.
  4. Utiliser sessionStorage pour conserver la progression actuelle de l’onglet.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 8 sur 10

Un cache expire après 6 minutes. Il a été enregistré à 09:12:00 et lu à 09:19:30. Comment l’application doit-elle le traiter ?
  1. Il a 450 000 ms et nécessite des données récentes.
  2. Il a 75 000 ms et peut être utilisé comme récent.
  3. Il a 450 000 ms et peut être utilisé comme récent.
  4. Il a 7 500 ms et nécessite des données récentes.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 9 sur 10

Une application météo fonctionne sur http://localhost, mais sa fonctionnalité de localisation est absente lorsqu’elle est ouverte sur un téléphone à une adresse réseau HTTP. Elle cesse aussi de fonctionner lorsque les utilisateurs sur ordinateur refusent la localisation. Quelle conception résout ces deux problèmes ?
  1. Redemander la position au chargement, puis cacher la saisie de ville après un refus.
  2. Servir en HTTPS, détecter la géolocalisation et laisser la saisie de ville disponible.
  3. Vérifier le nom du navigateur, puis demander la position sans limite d’attente.
  4. Garder HTTP, demander une haute précision et supprimer les vérifications d’autorisation.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 10 sur 10

Un gestionnaire de copie attend navigator.clipboard.writeText(text). À quel moment doit-il afficher « Copié ! » ?
  1. Après que cette promesse est tenue.
  2. Dès que writeText renvoie une valeur.
  3. Lorsque la détection réussit.
  4. Dès que l’utilisateur clique.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Série 3 : Débogue les requêtes, le stockage et les autorisations10 Questions Pratiques

Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.

Question 1 sur 10

Un service indique que PUT /profiles/29 remplace le profil. Qu’implique l’idempotence lorsque la même requête complète est envoyée deux fois ?
  1. Les deux réponses doivent avoir exactement le même état et les mêmes en-têtes.
  2. La seconde requête doit être rejetée avant d’atteindre le service.
  3. Le serveur doit créer un nouveau profil pour chaque requête identique.
  4. Le profil stocké attendu est le même qu’après une seule requête.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 2 sur 10

Une requête de création expire après que le serveur a peut-être reçu la requête. La page réessaie immédiatement, n’affiche que les champs soumis, puis envoie une modification à un identifiant indéfini. Quelle conception doit remplacer cette séquence ?
  1. Empêcher les répétitions, résoudre les créations incertaines et garder les identifiants renvoyés.
  2. Répéter après expiration, garder les champs soumis et déduire les identifiants de l’ordre de la liste.
  3. Empêcher les clics, répéter après chaque expiration et ne garder que les champs soumis.
  4. Autoriser les répétitions, ignorer les identifiants renvoyés et utiliser l’URL de création pour les modifications.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 3 sur 10

La documentation d’une API d’événements indique que son horodatage est en secondes. Une page le passe directement à new Date et affiche janvier 1970. Quelle conversion doit précéder la mise en forme de la date ?
  1. Diviser l’horodatage par 1 000.
  2. Ajouter le décalage UTC du lecteur.
  3. Multiplier l’horodatage par 1 000.
  4. Remplacer les paramètres régionaux de l’outil.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 4 sur 10

Un catalogue conserve les données de la veille après qu’une actualisation a renvoyé 503 avec Retry-After: 12. Quel comportement indique l’état et permet de réessayer ?
  1. Cacher l’échec et présenter les anciennes données comme venant d’être actualisées.
  2. Indiquer que les données sont anciennes et attendre au moins 12 secondes avant de réessayer un nombre limité de fois.
  3. Vider la liste et répéter immédiatement jusqu’à obtenir un code de succès.
  4. Traiter la réponse comme un succès sans résultat et désactiver les futures actualisations.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 5 sur 10

Une vue de compte nécessite un profil et le nom de son équipe. Le profil renvoie teamId. Les notifications sont indépendantes et peuvent échouer sans masquer les données du compte. Comment organiser les opérations ?
  1. Lancer toutes les requêtes ensemble, puis rejeter toute la vue au moindre échec.
  2. Enchaîner profil et équipe en parallèle des notifications ; traiter le résultat de chaque branche.
  3. Attendre les notifications, le profil puis l’équipe avec un gestionnaire d’erreurs commun.
  4. Lancer les notifications après le profil ; lancer l’équipe si les notifications réussissent aussi.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 6 sur 10

Une clé secrète de fournisseur a été incluse dans un commit d’un dépôt. Quelle action empêche l’utilisation de cet identifiant exposé ?
  1. La retirer uniquement du commit le plus récent.
  2. La renommer dans le code source JavaScript.
  3. La déplacer dans un en-tête de requête public.
  4. La révoquer et créer une clé de remplacement.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 7 sur 10

Un booléen enregistré est restauré avec if (localStorage.getItem("compact")). Le texte stocké est "false", mais le mode compact s’active. Pourquoi ?
  1. Web Storage restaure les booléens avec leur type d’origine.
  2. Une clé absente renvoie la chaîne "true" par défaut.
  3. Une chaîne non vide est une valeur vraie, même si son texte est "false".
  4. L’instruction if transforme le texte stocké en valeur vraie.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 8 sur 10

Deux onglets de même origine partagent le mode compact sous forme des chaînes « true » ou « false ». L’onglet A enregistre « false » mais attend son propre événement storage ; l’onglet B traite l’événement avec Boolean(event.newValue). La suppression de la clé doit désactiver le mode compact. Quelle règle de mise à jour gère ces trois cas ?
  1. Appliquer les changements dans l’onglet qui écrit et les écouteurs ; activer uniquement pour la chaîne « true ».
  2. Attendre les événements dans les deux onglets ; activer pour toute chaîne stockée non vide.
  3. Appliquer les changements uniquement dans l’onglet qui écrit ; garder le mode précédent dans les autres.
  4. Recharger l’onglet qui écrit ; utiliser Boolean sur les valeurs d’événement et garder le mode après suppression.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 9 sur 10

Un résultat de localisation indique la latitude -12.0464, la longitude -77.0428 et la précision 80. Que décrit 80 ?
  1. Une position estimée à 80 mètres au-dessus du niveau de la mer.
  2. Une probabilité de 80 % que la position soit exacte.
  3. Une garantie que l’appareil se trouve à moins de 80 mètres.
  4. Un rayon d’incertitude horizontal estimé à 80 mètres.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 10 sur 10

Une page à https://recipes.example.org/search?q=green+tea lit new URL(location.href).searchParams.get("q"). Quelle valeur obtient-elle ?
  1. "green+tea"
  2. "q=green+tea"
  3. "green tea"
  4. null
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Série 4 : Conçois des fonctionnalités d’API fiables10 Questions Pratiques

Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.

Question 1 sur 10

Une API limite une application à 80 appels par minute. Les requêtes dépassant cette limite reçoivent 429. Que signifie ce code d’état ?
  1. L’enregistrement demandé a disparu.
  2. Trop de requêtes ont été effectuées.
  3. Un remplacement complet est exigé.
  4. Le point de terminaison a déménagé.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 2 sur 10

Une recherche doit envoyer la valeur exacte « A+B & C ». Quel code définit cette valeur sans traiter sa ponctuation comme une structure d’URL ?
  1. url.search = "q=" + "A+B & C";
  2. url.hash = "q=" + "A+B & C";
  3. url.searchParams.set("q", "A+B & C");
  4. url.pathname += "?q=" + "A+B & C";
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 3 sur 10

Un enregistrement d’API possède un titre contenant le texte littéral <b>, un lien javascript: et remaining: 0. La page doit afficher le titre littéralement, n’autoriser que les liens web ordinaires et conserver le nombre. Quel plan de rendu répond aux trois besoins ?
  1. Utiliser textContent, vérifier les URL HTTP(S) et définir la valeur par défaut avec ??.
  2. Utiliser innerHTML, vérifier les URL HTTP(S) et définir la valeur par défaut avec ??.
  3. Utiliser textContent, affecter tous les href et définir la valeur par défaut avec ??.
  4. Utiliser textContent, vérifier les URL HTTP(S) et définir la valeur par défaut avec ||.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 4 sur 10

Deux lecteurs consultent le même instant UTC avec Intl.DateTimeFormat, des paramètres régionaux en-US fixes mais sans option timeZone. Les heures affichées diffèrent. Qu’est-ce qui explique cette différence ?
  1. Les paramètres régionaux choisissent le décalage UTC de chaque lecteur.
  2. L’objet Date change son instant stocké selon l’appareil.
  3. Le suffixe Z est ignoré sans option timeZone.
  4. L’outil de mise en forme utilise le fuseau de chaque appareil.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 5 sur 10

Une recherche renvoie du JSON valide avec un tableau de résultats vide. Son gestionnaire affiche le message d’erreur générique et garde le bouton désactivé. Quelle transition d’état convient à ce résultat ?
  1. Afficher un succès vide, garder le chargement et continuer à demander des pages.
  2. Afficher une panne du service, arrêter le chargement et réessayer sans limite.
  3. Afficher un succès vide, arrêter le chargement et rétablir la commande.
  4. Afficher un succès avec les anciens résultats et laisser la commande désactivée.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 6 sur 10

Un tableau de bord charge un compte en 400 ms, puis a besoin de l’identifiant renvoyé pour charger une équipe en 200 ms. Des alertes indépendantes prennent 700 ms et peuvent échouer sans masquer les données du compte. Quelle organisation permet ce comportement et combien de temps prend-elle environ si toutes les lectures réussissent ?
  1. Tout lancer ensemble et rejeter la vue au moindre échec ; environ 700 ms.
  2. Charger compte puis équipe en parallèle des alertes, avec des branches distinctes ; environ 700 ms.
  3. Charger compte, équipe puis alertes avec un catch commun ; environ 1 300 ms.
  4. Charger compte et alertes ensemble, puis l’équipe après leur succès ; environ 900 ms.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 7 sur 10

Un PATCH JSON vers une autre origine utilise credentials: "include". La requête préliminaire l’autorise. La réponse finale utilise un caractère générique pour l’origine et autorise les identifiants, si bien que JavaScript ne peut pas la lire. Le serveur suppose aussi que CORS rend les vérifications des utilisateurs inutiles. Quelles règles de réponse et d’accès corrigent cette conception ?
  1. Garder le caractère générique, retirer l’autorisation des identifiants et autoriser chaque action.
  2. Nommer l’origine de la page, garder l’autorisation des identifiants et confier l’autorisation à CORS.
  3. Garder le caractère générique et l’autorisation des identifiants, mais autoriser chaque action.
  4. Nommer l’origine de la page, garder l’autorisation des identifiants et autoriser chaque action.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 8 sur 10

Un fournisseur indique qu’une clé de carte convient à un usage public dans le navigateur. Quelle configuration limite les sites, les opérations d’API et l’utilisation totale autorisés pour cette clé ?
  1. Restreindre les domaines et les API, et définir des quotas d’utilisation.
  2. Restreindre les domaines et les API, mais laisser l’utilisation illimitée.
  3. Restreindre les API et les quotas, mais autoriser tous les domaines.
  4. Restreindre les domaines et les quotas, mais autoriser toutes les API.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 9 sur 10

Une fonction de chargement de brouillon analyse un texte enregistré et appelle immédiatement .map. Certains utilisateurs ont du JSON valide {"version":1,"items":[]} laissé par un ancien code, et d’autres ont du texte endommagé. Quel plan de restauration gère les deux cas ?
  1. Intercepter uniquement les échecs d’écriture et utiliser chaque valeur analysée comme tableau.
  2. Remplacer JSON.parse par JSON.stringify avant d’appeler .map.
  3. Intercepter les échecs de lecture ou d’analyse et valider ou convertir la structure enregistrée.
  4. Utiliser ?? [] après l’analyse et supposer que les valeurs non nulles sont des tableaux.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 10 sur 10

Un ordinateur portable indique navigator.onLine === true, mais un appel d’API est rejeté. Que doit en déduire la page sur la connectivité et que doit-elle gérer ensuite ?
  1. L’API est accessible ; interpréter le rejet uniquement comme du JSON invalide.
  2. Un réseau est détecté, mais l’API peut rester inaccessible ; gérer l’échec de la requête.
  3. L’API est inaccessible ; passer l’indicateur en ligne du navigateur à false.
  4. L’API est accessible ; réessayer immédiatement jusqu’à recevoir une réponse.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Tu bloques sur ton propre exercice ? Aide aux Devoirs

Mots-Clés

68 Mots-Clés, chacun avec sa définition

A

AbortController
Un AbortController fournit un signal pour une opération annulable et peut demander son annulation par un appel à sa méthode abort.
La recherche crée un AbortController et passe son signal à fetch avant qu’une action ultérieure l’annule.
AbortSignal
Un AbortSignal relie une annulation ou une limite de durée à une opération asynchrone comme fetch et à la lecture en cours de son corps.
Un AbortSignal issu de AbortSignal.timeout(4000) limite une requête à quatre secondes de temps actif.
Activation utilisateur
L’activation utilisateur est une interaction reconnue par le navigateur, comme un clic récent, qui peut être exigée avant d’autoriser une fonctionnalité soumise à restriction.
Appeler l’écriture dans le presse-papiers directement dans un gestionnaire de clic fournit l’activation utilisateur lorsque le navigateur l’exige.
Anti-rebond
L’anti-rebond retarde une opération jusqu’à une pause dans des événements répétés, en réinitialisant l’attente après chaque événement pour qu’une série produise moins d’appels.
L’anti-rebond sur un champ de recherche évite d’envoyer une requête distincte pour chaque frappe d’un mot saisi rapidement.
API du presse-papiers
L’API du presse-papiers permet à une page de lire ou d’écrire de manière asynchrone le contenu du presse-papiers système, sous réserve des règles de contexte sécurisé et d’accès du navigateur.
Un bouton de copie utilise l’API du presse-papiers après un clic et attend avant d’afficher son message de succès.
API web
Une API web expose des opérations qu’un programme appelle au moyen d’URL pour lire ou modifier des données détenues par un autre système.
Une API web météo permet à une page de demander une prévision pour une ville sans charger une nouvelle page.
Attente exponentielle
L’attente exponentielle augmente le délai entre les nouvelles tentatives selon un facteur multiplicatif, ce qui réduit la charge répétée pendant une panne temporaire.
Une attente exponentielle peut laisser passer une, deux puis quatre secondes entre une série limitée de tentatives.
Autorisation
Une autorisation est une décision gérée par le navigateur qui accorde ou refuse à une page l’accès à une fonctionnalité protégée, comme la position de l’appareil.
Un refus d’autorisation mémorisé peut faire échouer une demande de position sans afficher une seconde invite.

B

Baseline
Baseline est le résumé de MDN sur la disponibilité d’une fonctionnalité dans les principaux navigateurs, utilisé avec les informations détaillées sur la compatibilité et les exigences.
Consulter Baseline aide à planifier les tests des navigateurs avant que la page dépende d’une API du navigateur nouvellement découverte.

C

Cache
Un cache est une copie enregistrée de données utilisée pour éviter de répéter des opérations ou des requêtes, avec une règle définie par l’application pour déterminer sa fraîcheur.
Un cache météo peut afficher immédiatement une prévision récente, tandis qu’une entrée expirée déclenche une nouvelle requête.
Chaînage optionnel
Le chaînage optionnel interrompt sans erreur un accès à une propriété lorsque la valeur avant ?. est null ou undefined, et renvoie undefined.
Le chaînage optionnel permet à book.author?.name de gérer un livre dont l’objet auteur est absent de la réponse.
Clé d’API
Une clé d’API est un identifiant qui désigne l’application effectuant un appel afin que le fournisseur puisse contrôler l’accès, mesurer l’utilisation et appliquer des limites ou une facturation.
Une clé d’API visible dans le navigateur peut être copiée : une clé secrète de fournisseur doit donc rester sur le serveur qui effectue l’appel.
Coalescence des nuls
La coalescence des nuls fournit une valeur de repli avec ?? uniquement lorsque la valeur à gauche est null ou undefined, en préservant les zéros valides.
La coalescence des nuls conserve un nombre égal à zéro provenant d’une API au lieu de le remplacer par le texte « indisponible ».
Code d’état
Un code d’état est une valeur HTTP à trois chiffres qui indique le résultat d’une requête, comme un succès, un refus ou un problème de serveur.
Un code d’état 201 indique à la page que le serveur a créé une ressource en réponse à la requête.
Condition de concurrence
Une condition de concurrence est un résultat qui dépend de l’ordre d’achèvement d’opérations asynchrones, par exemple lorsqu’une ancienne recherche remplace des résultats plus récents.
Une vérification du numéro de requête empêche une condition de concurrence lorsqu’une recherche précédente plus lente se termine après la recherche actuelle.
Contenu mixte
Un contenu mixte apparaît lorsqu’une page sécurisée demande une ressource non sécurisée ; les navigateurs bloquent les appels fetch HTTP effectués par des pages HTTPS.
Une URL de prévision HTTP provoque un échec dû au contenu mixte lorsque la page météo elle-même est chargée en HTTPS.
Contexte sécurisé
Un contexte sécurisé est un contexte de navigateur considéré comme fiable pour les API soumises à restriction, généralement fourni par HTTPS ou une origine locale admissible.
Un contexte sécurisé sur localhost permet le développement, tandis qu’une simple adresse réseau HTTP peut ne pas remplir cette condition.
Corps de réponse
Un corps de réponse est le contenu envoyé après les en-têtes de réponse ; il peut contenir du JSON, du texte, des données binaires ou aucun contenu.
La page lit une fois le corps de réponse et conserve l’objet obtenu pour l’affichage comme pour le filtrage.
Corps de requête
Un corps de requête transporte le contenu soumis à un serveur, comme un enregistrement JSON sérialisé ou des champs de formulaire dans une requête de création.
Le corps de requête contient le titre et le texte d’une note, tandis que la méthode précise que la note doit être créée.

D

Délimiteur multipart
Un délimiteur multipart sépare les champs et les fichiers dans un corps multipart et est indiqué dans son en-tête de type de contenu.
Le navigateur fournit le délimiteur multipart lorsque la page envoie FormData sans définir elle-même Content-Type.
Détection de fonctionnalités
La détection de fonctionnalités vérifie qu’une capacité est disponible avant que le code l’utilise, ce qui permet à la page de choisir une solution prise en charge ou une solution de repli.
La détection de fonctionnalités avec "geolocation" in navigator détermine si la page peut proposer la localisation de l’appareil.

E

En-tête
Un en-tête est une valeur nommée associée à une requête ou à une réponse, qui décrit l’échange, son contenu ou ses exigences d’accès.
Un en-tête Content-Type indique au programme destinataire que le corps associé contient du JSON.
Encodage d’URL
L’encodage d’URL représente les caractères de manière sûre dans les composants d’une URL afin que la ponctuation des données ne soit pas confondue avec la structure de l’adresse.
L’encodage d’URL garde l’esperluette du nom d’un groupe dans la valeur de requête au lieu de commencer un nouveau paramètre.
Erreur d’analyse syntaxique
Une erreur d’analyse syntaxique se produit lorsqu’un texte ne peut pas être interprété dans le format attendu, par exemple une page HTML passée à un lecteur JSON.
Un corps 204 vide provoque une erreur d’analyse JSON même si le serveur a terminé l’opération avec succès.
Expiration
L’expiration est l’âge ou le moment au-delà duquel une application ne considère plus une valeur enregistrée comme récente, même si cette valeur reste stockée.
Une expiration de dix minutes amène une application à comparer l’heure actuelle à celle enregistrée avec sa réponse en cache.

É

État de chargement
Un état de chargement indique au lecteur qu’une opération asynchrone est en cours pendant que la page attend son résultat.
L’état de chargement affiche « Recherche en cours… » avant le début de la requête et disparaît lorsqu’elle se termine.
État vide
Un état vide est l’interface affichée après qu’une opération réussie n’a renvoyé aucune donnée correspondante, ce qui distingue ce résultat d’un échec.
L’état vide indique « Aucun enregistrement ne correspond à ton filtre » après que l’API a renvoyé un tableau vide valide.
Événement storage
Un événement storage informe les autres contextes admissibles de même origine d’une modification du stockage ; celui qui écrit dans localStorage ne reçoit pas son propre événement.
Un événement storage met le thème à jour dans un autre onglet, tandis que l’onglet qui écrit applique directement le thème.

F

FormData
FormData est un objet du navigateur qui recueille des champs de formulaire et des fichiers pour les soumettre, permettant à fetch de construire un corps de requête multipart.
Passer FormData comme corps permet au navigateur d’envoyer l’image sélectionnée avec les champs texte du formulaire.
Fuseau horaire
Un fuseau horaire détermine la date du calendrier et l’heure locales utilisées pour afficher un instant, y compris les règles de décalage applicables.
Un fuseau horaire UTC explicite permet à tous les lecteurs de voir l’heure d’un événement en UTC au lieu du fuseau de leur appareil.

G

Géolocalisation
La géolocalisation est une API du navigateur qui obtient une estimation de la position de l’appareil avec l’autorisation de l’utilisateur et indique si l’opération a réussi ou échoué.
La géolocalisation peut fournir des coordonnées pour une prévision à proximité, avec la saisie d’une ville disponible en cas de refus.

H

Horodatage Unix
Un horodatage Unix mesure le temps écoulé depuis le 1er janvier 1970, UTC ; l’unité documentée peut être la seconde ou la milliseconde.
Un horodatage Unix en secondes doit être multiplié par 1 000 avant de devenir une valeur JavaScript Date.
HttpOnly
HttpOnly est un attribut de cookie qui empêche le JavaScript de la page de lire ce cookie tout en lui permettant d’accompagner les requêtes correspondantes.
Un cookie portant l’attribut HttpOnly diffère des données localStorage, que les scripts de l’origine peuvent lire.

I

Idempotence
L’idempotence signifie que répéter une opération identique a le même effet attendu sur l’état du serveur que l’effectuer une fois.
Supprimer deux fois une note illustre l’idempotence : la note reste absente même si le second code d’état diffère.
IndexedDB
IndexedDB est la base de données asynchrone du navigateur pour les données structurées et les fichiers trop volumineux pour les petites tâches adaptées à Web Storage.
Une page contenant une grande collection structurée peut utiliser IndexedDB au lieu de l’écrire à répétition comme une seule chaîne de stockage.
Injection de script intersite
L’injection de script intersite est l’exécution d’un script non fiable dans une page, qui peut se produire lorsque des chaînes externes sont interprétées comme du HTML.
Utiliser textContent pour les titres d’une API supprime l’interprétation HTML qui peut permettre une injection de script intersite.
Intl.NumberFormat
Intl.NumberFormat est un outil JavaScript qui produit des chaînes lisibles pour les nombres, les devises, les pourcentages ou les unités selon les paramètres régionaux choisis.
La page réutilise Intl.NumberFormat pour chaque prix au lieu de reconstruire une chaîne monétaire pour chaque élément.

J

Jeton d’accès
Un jeton d’accès est un identifiant qui accorde un accès défini à un utilisateur ou à une session, permettant à son détenteur d’effectuer les requêtes autorisées.
L’en-tête Authorization de la requête transporte un jeton d’accès pour l’opération autorisée de l’utilisateur connecté.
JSON
JSON est un format texte pour les données structurées, notamment les objets et les tableaux, qui doit être analysé avant que le code utilise ses valeurs imbriquées.
La page analyse le JSON et lit le tableau contenu dans sa propriété results avant de construire les éléments de liste.

L

Limite de requêtes
Une limite de requêtes plafonne le nombre d’opérations qu’un client ou un identifiant peut effectuer pendant un intervalle de temps, ce qui aide un service à contrôler son utilisation.
Une requête à chaque frappe peut dépasser la limite de requêtes d’une recherche : l’anti-rebond réduit donc les appels inutiles.
localStorage
localStorage est l’espace Web Storage persistant d’une origine, partagé par ses onglets et conservé après la fermeture du navigateur jusqu’à sa suppression ou son effacement.
Un thème enregistré dans localStorage peut être restauré à la visite suivante et lu par un autre onglet de même origine.

O

Objet Response
Un objet Response représente les en-têtes et le code d’état renvoyés par fetch et fournit des méthodes pour lire le corps de la réponse.
L’objet Response a le code d’état 200, mais la page attend encore json() pour obtenir les données du livre.
Opération synchrone
Une opération synchrone se termine avant que l’instruction suivante puisse se poursuivre : un long appel de stockage peut donc bloquer le thread principal de la page.
Une écriture volumineuse dans Web Storage est une opération synchrone qui peut retarder le traitement de l’interaction suivante de l’utilisateur.
Origine
Une origine est la combinaison du schéma, de l’hôte et du port d’une URL, que le navigateur utilise pour définir plusieurs frontières d’accès.
Deux chemins sur un même hôte HTTPS partagent une origine, mais changer cet hôte ou son port crée une autre origine.

P

Pagination
La pagination divise une collection de résultats en groupes plus petits qu’une API renvoie séparément, généralement à l’aide de paramètres de page ou de curseur.
La pagination permet à un bouton « Charger plus » de demander le groupe suivant tout en conservant les éléments déjà affichés.
Paramètre de requête
Un paramètre de requête est une valeur nommée dans la partie d’une URL située après ?, utilisée par un point de terminaison pour des entrées comme les recherches ou les limites de page.
Le paramètre de requête limit=12 demande au point de terminaison de recherche de renvoyer au plus douze résultats.
Paramètres régionaux
Les paramètres régionaux identifient les conventions de langue et de présentation régionale utilisées pour afficher des valeurs comme les dates, les nombres et les montants monétaires.
Les paramètres régionaux en-US écrivent une date différemment de en-GB même lorsqu’ils mettent en forme le même instant.
Partage de ressources entre origines (CORS)
Le partage de ressources entre origines (CORS) est le mécanisme d’en-têtes HTTP qui permet à un serveur d’autoriser les scripts de navigateurs situés sur d’autres origines à lire ses réponses.
L’API utilise CORS pour permettre à une page d’un site nommé de lire ses données météo depuis un hôte différent.
Point de terminaison
Un point de terminaison est une adresse d’API qui accepte une requête documentée pour une ressource ou une opération, souvent avec une méthode HTTP particulière.
Le point de terminaison des notes accepte un POST pour créer une note et renvoie l’identifiant du nouvel enregistrement.
Politique de même origine
La politique de même origine est une frontière de sécurité du navigateur qui limite la façon dont un script peut lire des ressources appartenant à une autre origine.
La politique de même origine fait dépendre un appel fetch vers une autre origine de l’autorisation de lecture CORS du serveur de l’API.
Précision de la localisation
La précision de la localisation décrit l’incertitude horizontale estimée autour d’une position indiquée, mesurée en mètres plutôt qu’en degrés.
Une précision de localisation de 60 mètres décrit le rayon d’incertitude estimé autour de la position indiquée.
Promise.all
Promise.all combine les promesses fournies en un tableau de résultats lorsqu’elles sont toutes tenues et est rejetée dès qu’une promesse fournie est rejetée.
La page utilise Promise.all pour deux lectures indépendantes dont les résultats doivent tous deux être disponibles pour l’affichage.
Promise.allSettled
Promise.allSettled attend toutes les promesses fournies et renvoie pour chacune un objet décrivant son résultat, en cas de succès ou d’échec.
Promise.allSettled permet à un tableau de bord d’afficher deux panneaux réussis tout en expliquant l’échec d’un troisième.

Q

Quota de stockage
Un quota de stockage est une limite imposée par le navigateur aux données stockées ; dépasser l’espace Web Storage disponible peut provoquer une erreur d’écriture.
Une application qui conserve une liste en mémoire intercepte une erreur de quota de stockage et continue à utiliser cette liste même lorsqu’elle ne peut pas l’enregistrer.

R

Région dynamique
Une région dynamique est une zone de page dont les changements de contenu peuvent être annoncés par une technologie d’assistance sans déplacer le focus du clavier.
Une région dynamique avec role="status" annonce « Chargement… » puis le message de résultat de la recherche.
Rendu
Le rendu transforme les données en contenu visible sur une page, par exemple en créant un élément de liste pour chaque objet du tableau de résultats d’une API.
Le rendu d’une nouvelle recherche commence par vider la liste précédente, puis ajoute les éléments des résultats actuels.
Réponse HTTP
Une réponse HTTP est la réponse d’un serveur à une requête ; elle contient un code d’état, des en-têtes et généralement un corps avec des données ou une erreur.
La réponse HTTP indique 404 et explique dans son corps que le livre demandé est introuvable.
Réponse opaque
Une réponse opaque cache au code de la page les détails de son état, ses en-têtes et son corps, et expose une valeur d’état égale à zéro.
Un appel fetch en mode no-cors donne une réponse opaque : la page ne peut donc pas extraire le JSON qu’elle espérait afficher.
Requête HTTP
Une requête HTTP est un message envoyé par un client à un serveur, qui comporte une méthode, une URL, des en-têtes et, pour certaines opérations, un corps.
La requête HTTP demande /books et comprend un paramètre de requête qui limite le nombre de résultats.
Requête préliminaire
Une requête préliminaire est une requête OPTIONS envoyée par le navigateur pour vérifier l’autorisation entre origines d’une méthode et d’en-têtes de requête prévus.
Un POST JSON peut nécessiter une requête préliminaire avant que le navigateur envoie l’enregistrement que la page veut créer.
Retry-After
L’en-tête Retry-After indique au client quand réessayer, au moyen d’un délai en secondes ou d’une date HTTP dans une réponse appropriée.
Une valeur Retry-After de 15 demande à la page d’attendre quinze secondes avant une autre requête.

S

Sérialisation
La sérialisation convertit une valeur en un format qui peut être stocké ou transmis, par exemple en transformant un objet JavaScript en texte JSON.
La sérialisation avec JSON.stringify préserve les champs d’une note lorsqu’ils sont envoyés dans un corps de requête JSON.
sessionStorage
sessionStorage est un espace Web Storage limité à une origine et à la session de page d’un onglet, qui conserve les valeurs entre les rechargements pendant cette session.
Un formulaire utilise sessionStorage pour une progression qui doit survivre à un rechargement sans devenir un état persistant partagé.
Solution de repli
Une solution de repli est un autre moyen d’accomplir une tâche lorsque la fonctionnalité privilégiée n’est pas prise en charge, est refusée ou ne peut pas aboutir.
Sélectionner un champ contenant un lien pour le copier au clavier fournit une solution de repli lorsque l’accès automatique au presse-papiers échoue.

T

Temps universel coordonné (UTC)
Le temps universel coordonné (UTC) est la référence temporelle commune utilisée pour identifier les instants entre fuseaux horaires, représentée par Z à la fin d’une date et heure ISO.
L’API renvoie un instant en UTC et la page met cet instant en forme pour un lecteur situé dans un autre fuseau horaire.
textContent
La propriété textContent lit ou définit le texte d’un élément sans interpréter la chaîne fournie comme du balisage HTML.
Affecter un titre à textContent affiche ses chevrons littéralement au lieu de créer un élément HTML.

U

Unité monétaire divisionnaire
Une unité monétaire divisionnaire est une subdivision de l’unité principale d’une devise, comme le cent pour USD, utilisée par certaines API pour les montants entiers.
Lorsqu’une API indique des unités monétaires divisionnaires USD, l’entier 4680 représente 46.80 dollars américains.

W

Web Storage
Web Storage fournit des espaces de stockage clé-valeur synchrones dans le navigateur pour de petites valeurs sous forme de chaînes, séparés par origine et selon la durée de vie choisie.
Web Storage conserve un objet de paramètres sérialisé que la page restaure lorsqu’elle redémarre.

À propos de cette unité

Par StudeliSignaler une erreur

Crée ton propre Matériel d'Étude

Transforme tes notes, diapos et documents en Guides d'Étude, Questions Pratiques, Flashcards et 6 autres outils.

Commencer