Tutoriel API JavaScript Fetch : GET, POST, gestion des erreurs et délais d’attente

  1. Accueil
  2. Blog
  3. Développement de logiciels

Développement de logiciels

Tutoriel API JavaScript Fetch : GET, POST, gestion des erreurs et délais d’attente

Fetch est le moyen intégré d’appeler des API à partir de JavaScript, mais il réserve une surprise qui surprend presque tout le monde. Apprenez à envoyer des requêtes, à gérer tous les types d’échecs et à créer un petit assistant que vous pouvez réutiliser.

9 min de lecture
Tutoriel API JavaScript Fetch : GET, POST, gestion des erreurs et délais d'attente

À retenir

  • fetch() renvoie une promesse pour un Response, et la lecture du corps prend une seconde await.
  • Les erreurs HTTP telles que 404 et 500 ne sont pas rejetées, alors vérifiez toujours response.ok.
  • Pour envoyer du JSON, utilisez JSON.stringify et définissez l’en-tête Content-Type.
  • Fetch n’a pas d’option de délai d’expiration par défaut, utilisez donc AbortSignal.timeout().

La plupart des applications Web modernes communiquent en permanence avec un serveur. L’API JavaScript Fetch est le moyen standard de le faire, et elle est intégrée aux navigateurs et à Node.js 18 et versions ultérieures, il n’y a donc rien à installer.

L’utilisation de base prend deux lignes, mais de nombreux tutoriels s’arrêtent là et laissent de côté la partie qui provoque de vrais bugs : la gestion des échecs. Nous avons testé les exemples de ce guide sur un petit serveur local sur Node.js 24, et le résultat affiché provient de cette exécution. example.com dans le code représente votre propre API. Si les promesses sont nouvelles pour vous, commencez par Explication des promesses JavaScript.

Qu’est-ce que l’API Fetch ?

Fetch est une interface basée sur des promesses pour effectuer des requêtes HTTP. Il a remplacé l’ancien, basé sur le rappel XMLHttpRequest, et de nombreux projets l’utilisent désormais plutôt que d’ajouter une bibliothèque pour des appels simples.

Caractéristique Récupérer Axios (bibliothèque)
Mise en place Intégré Ajouté en tant que dépendance
Corps JSON Stringifiez-le vous-même Automatique
Analyser la réponse JSON Appeler response.json() Automatique
Les erreurs HTTP sont-elles rejetées ? Non Oui, par défaut
Délai d’attente Grâce à AbortSignal Une option timeout

Une requête GET

Fetch effectue une requête GET par défaut. Il y a deux étapes, et chacune nécessite await : d’abord les en-têtes de réponse arrivent, puis vous lisez le corps.

const response = await fetch("https://example.com/users/1");
const user = await response.json();

console.log(user);

// { id: 1, name: 'Asha' }

Les deux étapes existent car le corps peut être volumineux et arriver plus tard que les en-têtes. Dans un script de navigateur, le niveau supérieur await a besoin d’un module, vous le placerez donc généralement dans une fonction async. Consultez notre Guide asynchrone/attente JavaScript.

L’objet Réponse

Avant de lire le corps, vous pouvez inspecter la réponse :

console.log(response.status, response.ok, response.headers.get("content-type"));

// 200 true application/json
Propriété ou méthode Vous donne
response.ok true pour les statuts 200 à 299
response.status Le code d’état, tel que 404
response.headers.get(name) Un en-tête de réponse
response.json() Le corps analysé en JSON
response.text() Le corps comme une ficelle
response.blob() Données binaires, telles qu’une image

Un corps ne peut être lu qu’une seule fois. L’appel de json() une deuxième fois a échoué lors de notre test :

await res.json();
await res.json();

// TypeError: Body is unusable: Body has already been read

Si vous devez le lire deux fois, appelez d’abord response.clone().

La grosse surprise : une 404 ne lance pas

C’est la chose la plus importante dans cet article. Nous avons demandé à un utilisateur qui n’existe pas :

const res = await fetch("https://example.com/users/999");
console.log(res.status, res.ok);

// 404 false

Aucune exception n’a été levée. En ce qui concerne le fetch, la requête a fonctionné : le serveur a été atteint et il a répondu. La promesse n’est rejetée que lorsqu’aucune réponse utilisable n’arrive, comme en cas de panne de réseau. Un code comme celui-ci a donc un bug caché :

try {
  const res = await fetch(url);
  const data = await res.json();   // may be an error payload
  showUser(data);                  // runs anyway for 404 and 500
} catch (error) {
  showError();                     // does not run for 404 or 500
}

Consultez notre aide-mémoire sur les codes d’état HTTP pour voir la signification de chaque code.

Une aide réutilisable

Ne répétez pas cette vérification partout. Enveloppez-le une fois :

async function getJson(url, options) {
  const response = await fetch(url, options);
  if (!response.ok) {
    throw new Error(`Request failed with status ${response.status}`);
  }
  return response.json();
}

try {
  await getJson("https://example.com/users/999");
} catch (error) {
  console.log("caught:", error.message);
}

// caught: Request failed with status 404

Désormais, les erreurs HTTP et les erreurs réseau se retrouvent toutes deux dans le même catch. Cette petite fonction vaut la peine d’être présente dans chaque projet. Une version réelle peut également lire un message d’erreur dans le corps de la réponse et gérer une réponse 204 No Content, qui n’a pas de JSON à analyser.

Données POST-JSON

Passez un objet options comme deuxième argument. Pour JSON, vous devez faire deux choses vous-même : convertir les données en chaîne et définir l’en-tête.

const created = await getJson("https://example.com/users", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "Ben" }),
});

console.log(created);

// { id: 2, name: 'Ben', type: 'application/json' }

Notre serveur de test a renvoyé le type de contenu qu’il a reçu, confirmant l’arrivée de l’en-tête. Oublier cet en-tête est une cause fréquente d’erreurs de serveur confuses, car de nombreux frameworks n’analysent JSON que lorsqu’il est déclaré. Pour télécharger un formulaire ou des fichiers, transmettez un objet FormData comme corps et ne pas définissez Content-Type, car le navigateur doit lui-même ajouter une valeur limite.

Autres méthodes et options

Options Exemple Objectif
méthode "PUT", "PATCH", "DELETE" La méthode HTTP
en-têtes { Autorisation : "Porteur..." } En-têtes de requête
corps JSON.stringify(data) Le corps de la requête
signaler AbortSignal.timeout(5000) Annulation
informations d'identification "inclure" Envoi de cookies cross-origin
cache "sans magasin" Comportement du cache du navigateur

Choisir entre REST et d’autres styles d’API ? Notre comparaison de REST vs GraphQL montre comment la récupération s’adapte à chacun.

Chaînes de requête

Ne créez pas de chaînes de requête en joignant du texte, car les caractères spéciaux les briseraient. URLSearchParams gère l’encodage pour vous :

const params = new URLSearchParams({ q: "red shoes", page: 2 });
console.log(params.toString());

// q=red+shoes&page=2

await getJson(`https://example.com/search?${params}`);

// { q: 'red shoes', page: '2' }

Le serveur a reçu red shoes correctement, avec l’espace restauré.

Délais d’attente et annulation

Fetch attendra longtemps sur un serveur lent, sauf indication contraire de votre part. AbortSignal.timeout() fixe une limite. Notre point final de test a duré deux secondes, contre une limite de 200 millisecondes :

try {
  await fetch("https://example.com/slow", { signal: AbortSignal.timeout(200) });
} catch (error) {
  console.log(error.name);
}

// TimeoutError

Pour annuler manuellement, par exemple lorsqu’un utilisateur quitte une page ou saisit un nouveau terme de recherche, utilisez un AbortController :

const controller = new AbortController();
const pending = fetch("https://example.com/slow", { signal: controller.signal });

controller.abort();

try {
  await pending;
} catch (error) {
  console.log(error.name);
}

// AbortError

Pour exécuter plusieurs requêtes à la fois, utilisez Promise.all, ce qui est beaucoup plus rapide que de les attendre une à la fois :

const [user, search] = await Promise.all([
  getJson("https://example.com/users/1"),
  getJson("https://example.com/search?q=a&page=1"),
]);

Toutes sortes d’échecs

Voici à quoi ressemblait chaque échec lors de notre analyse, ainsi que comment les distinguer :

Situation Que se passe-t-il Comment le détecter
Le serveur renvoie 404 ou 500 La promesse est remplie response.ok est faux
Le serveur n’est pas accessible Rejette avec TypeError attraper
Délai d’attente atteint Rejette avec TimeoutError error.name
Annulé manuellement Rejette avec AbortError error.name
Le corps n’est pas un JSON valide json() rejette avec SyntaxError attraper

Cette dernière rangée est courante en production. Un proxy renvoyant un 502 envoie souvent une page d’erreur HTML. Nous avons reproduit cela et res.json() a lancé un SyntaxError. Cocher response.ok avant l’analyse signifie que vous signalez le vrai problème plutôt qu’une erreur d’analyse déroutante.

Astuce : Testez volontairement ces chemins d’échec. Les outils de développement de navigateur peuvent simuler une mise hors ligne et les outils de test peuvent simuler une réponse 500. Notre guide Tests d’API avec Postman couvre la vérification du côté API.

CORS et informations d’identification

Dans un navigateur, une requête d’une origine à une autre est soumise à CORS, les règles de partage de ressources entre origines. Si vous voyez une erreur mentionnant Access-Control-Allow-Origin, le correctif appartient au serveur, qui doit autoriser votre site. Dans votre JavaScript, l’échec n’apparaît que sous forme générique TypeError, alors regardez la console du navigateur pour connaître la raison réelle. Node.js n’applique pas CORS, donc une requête qui fonctionne dans un script peut toujours échouer dans le navigateur.

Par défaut, les navigateurs n’envoient pas de cookies sur les requêtes cross-origin. Définissez credentials: "include" si vous en avez besoin et assurez-vous que le serveur le permet. Ne mettez jamais de clés API secrètes dans le JavaScript du navigateur, car tout le monde peut les lire. Gardez-les sur votre serveur.

Erreurs courantes

  • Ne pas vérifier response.ok. Les réponses d’erreur sont traitées comme un succès.
  • Oublier le deuxième await. response.json() renvoie également une promesse.
  • Oublier JSON.stringify. Passer un objet au fur et à mesure que le corps l’envoie [object Object].
  • Régler Content-Type avec FormData. Cela brise la limite, alors laissez-la de côté.
  • N’avoir aucun délai d’attente. Une requête bloquée peut laisser le spinner d’une page fonctionner indéfiniment.
  • Analyse JSON pour une réponse vide. Un 204 n’a pas de corps et json() le lancera.

Pour conclure

La récupération est simple une fois que l’on se souvient de sa règle principale : une réponse n’est pas la même chose qu’un succès. Copiez le petit assistant dans votre projet, ajoutez un délai d’attente et testez vos chemins d’échec. Dans l’étape suivante, créez une petite page qui charge les données d’une API, affiche un message d’erreur clair et permet à l’utilisateur d’annuler une recherche lente.

Questions fréquentes

La récupération génère-t-elle une erreur sur un 404 ?

La récupération de numéro est rejetée uniquement lorsqu’aucune réponse n’est reçue, par exemple en cas de panne de réseau. Pour les erreurs HTTP, vérifiez vous-même Response.ok ou Response.status.

Comment envoyer du JSON avec fetch ?

Définissez la méthode sur POST, ajoutez un en-tête Content-Type de application/json et transmettez les données via JSON.stringify comme corps.

Pourquoi ai-je besoin de deux attentes avec récupération ?

Le premier se résout une fois que les en-têtes de réponse arrivent. La seconde attend que le corps soit téléchargé et analysé, ce qui peut arriver plus tard.

Comment définir un délai d’attente lors de la récupération ?

Signal de réussite : AbortSignal.timeout(5000) dans les options. La demande est ensuite rejetée avec une TimeoutError si elle prend plus de temps que ce nombre de millisecondes.

La récupération est-elle disponible dans Node.js ?

Oui. Fetch est disponible dans le monde entier dans Node.js 18 et versions ultérieures. Les anciennes versions nécessitent un package, bien que les règles CORS ne s’appliquent que dans les navigateurs.

Continuez à apprendre

Travailler avec Stack Quora

Besoin d’aide pour les tests, WordPress ou le référencement ?

Nous aidons les équipes à proposer de meilleurs logiciels et à développer leurs sites. Dites-nous sur quoi vous travaillez et nous vous proposerons une prochaine étape claire.

Continuez à lire

Plus de guides sur tests, IA et développement moderne

Vous avez apprécié cet article ? Choisissez un sujet et accédez directement à nos nouveaux didacticiels.

Intelligence artificielle

Les hallucinations de l'IA expliquées : pourquoi les modèles de langage inventent les choses et comment les réduire

Les hallucinations de l'IA ont expliqué : ce qu'elles sont, pourquoi les modèles de langage les produisent, les types courants, comment les réduire …

Lire l'article →
DevOps

Variables d'environnement expliquées : fichiers .env, secrets et configuration correctement effectués

Variables d'environnement expliquées avec des exemples Python que nous avons exécutés : lecture et définition, pourquoi chaque valeur est une chaîne…

Lire l'article →
Développement logiciel

Limitation du débit de l'API expliquée : algorithmes, en-têtes et gestion des erreurs 429

Limitation du débit de l'API expliquée avec une simulation que nous avons exécutée : compartiment de jetons, fenêtre fixe, fenêtre glissante, 429 ré…

Lire l'article →
Automatisation des tests

Se moquer en Python : unittest.mock, patch et les erreurs qui font mentir les tests

Moquerie en Python avec unittest.mock, testée : Mock et return_value, side_effect, correctifs où un nom est utilisé, spec et autospec, dates moqueus…

Lire l'article →
Tests logiciels

Couverture du code expliquée : couverture des lignes par rapport aux branches et ce que signifie réellement 100 %

Couverture du code expliquée avec une véritable exécution de cover.py : couverture des lignes, des branches et des conditions, lecture d'un rapport,…

Lire l'article →
Bases de données et SQL

DELETE vs TRUNCATE vs DROP dans SQL : différences, restauration et quand les utiliser

DELETE vs TRUNCATE vs DROP expliqué avec SQL testé : ce que chacun supprime, restauration, déclencheurs, réinitialisation d'identité, vitesse et en …

Lire l'article →
Bases de données et SQL

Vues SQL expliquées : créez, utilisez et évitez les pièges, avec des exemples

Vues SQL expliquées avec les requêtes que nous avons exécutées : création d'une vue, résultats en direct, masquage des colonnes, performances, vues …

Lire l'article →
Développement logiciel

Interface TypeScript vs Type : différences réelles, testées avec le compilateur

Interface TypeScript vs type, vérifiée avec le vrai compilateur : ce que les deux peuvent faire, ce qu'un seul peut faire, la fusion des déclaration…

Lire l'article →
Développement logiciel

Python *args et **kwargs expliqués : fonctions flexibles avec des exemples clairs

Python *args et **kwargs expliqués avec le code que nous avons exécuté : emballage et déballage, ordre des paramètres, arguments de mot-clé uniqueme…

Lire l'article →
Développement logiciel

Fonctions Python Lambda : syntaxe, utilisations réelles et quand ne pas les utiliser

Fonctions Python lambda expliquées avec le code que nous avons exécuté : syntaxe, tri avec clé, carte et filtre, fermetures, piège de liaison tardiv…

Lire l'article →
Intelligence artificielle

Que sont les agents IA ? Comment ils fonctionnent, avec une simple boucle d'agent que vous pouvez exécuter

Que sont les agents IA ? Un guide simple sur la boucle d'agent, les outils, la mémoire et les garde-fous, avec une petite boucle Python que nous avo…

Lire l'article →
DevOps

Surveillance vs observabilité : la vraie différence, avec les journaux, les métriques et les traces

Surveillance et observabilité expliquées : échecs connus et inconnus, journaux, métriques et traces, présentation pas à pas des incidents de paiemen…

Lire l'article →
DevOps

Volumes Docker vs montages Bind : conserver les données du conteneur de la bonne manière

Volumes Docker et montages de liaison expliqués : pourquoi les données du conteneur disparaissent, volumes nommés, montages de liaison, tmpfs, exemp…

Lire l'article →
Automatisation des tests

TDD vs BDD : principales différences, une fonctionnalité conçue dans les deux sens et quand les utiliser

TDD vs BDD expliqué avec une fonctionnalité de remise construite dans les deux sens : refactor rouge-vert avec le code que nous avons exécuté, scéna…

Lire l'article →
Tests logiciels

Tests d'acceptation utilisateur (UAT) : processus, liste de contrôle et exemples réels

Les tests d'acceptation des utilisateurs sont expliqués : qui les exécute, en quoi ils diffèrent du contrôle qualité, un processus en sept étapes, u…

Lire l'article →
Bases de données et SQL

Explication des valeurs SQL NULL : IS NULL, COALESCE, NULLIF et les pièges à éviter

Les valeurs SQL NULL expliquées avec les requêtes que nous avons exécutées : logique à trois valeurs, IS NULL, COALESCE, NULLIF, comment les agrégat…

Lire l'article →
Bases de données et SQL

Instruction SQL CASE WHEN : syntaxe, exemples réels et erreurs courantes

SQL CASE WHEN expliqué avec les requêtes que nous avons exécutées : formulaires simples et recherchés, ordre des conditions, pivots avec SUM, astuce…

Lire l'article →
Développement logiciel

Qu'est-ce que JWT ? Les jetons Web JSON expliqués avec un exemple fonctionnel

Qu’est-ce que JWT ? JSON Web Tokens expliqué : les trois parties, un jeton construit et falsifié dans le code que nous avons exécuté, JWT vs session…

Lire l'article →
Développement logiciel

Boucle d'événements JavaScript expliquée : pile d'appels, microtâches et minuteries avec des exemples

La boucle d'événements JavaScript expliquée avec le code que nous avons exécuté : pile d'appels, files d'attente de tâches et de microtâches, pourqu…

Lire l'article →
Développement logiciel

Générateurs Python et rendement expliqués : économisez de la mémoire avec des exemples réels

Les générateurs Python et le rendement expliqués avec le code que nous avons exécuté : comment ils s'arrêtent et reprennent, les économies de mémoir…

Lire l'article →
Intelligence artificielle

Que sont les intégrations ? Vecteurs et similarité cosinus expliqués simplement

Que sont les intégrations ? Un guide en langage simple sur les vecteurs, la similarité cosinus et la recherche sémantique, avec un petit exemple que…

Lire l'article →
DevOps

Déploiement Bleu-Vert vs Canary : différences, compromis et comment choisir

Explication du déploiement bleu-vert ou canari : comment chacun fonctionne, coût, risque et restauration, regroupement d'utilisateurs stable que nou…

Lire l'article →
Automatisation des tests

Tests instables : quelles sont leurs causes et comment les corriger définitivement

Des tests irréguliers expliqués avec des démos que nous avons exécutées : les principales causes, comment en confirmer et en diagnostiquer une, les …

Lire l'article →
Tests logiciels

Tests de charge vs tests de contrainte : différences, métriques et exemples k6

Explication des tests de charge et des tests de stress : ce que chacun prouve, les tests de pointe et de trempage, les métriques qui comptent, pourq…

Lire l'article →
Tests logiciels

Scénario de test et scénario de test : principales différences, exemples et quand les utiliser

Scénario de test et scénario de test expliqués : des définitions claires, un tableau côte à côte, une fonctionnalité de réinitialisation de mot de p…

Lire l'article →
Bases de données et SQL

Optimisation des requêtes SQL : lire les plans d'exécution et corriger les requêtes lentes, avec des délais

Optimisation des requêtes SQL testée sur un million de lignes : lire les plans d'exécution, ajouter les bons index, corriger les filtres non Sargabl…

Lire l'article →
Bases de données et SQL

SQL UNION vs UNION ALL : différences, exemples et performances testées

SQL UNION vs UNION ALL expliqué avec les requêtes que nous avons exécutées : des doublons, les règles suivent toutes les deux, un véritable bug de d…

Lire l'article →
Développement logiciel

Tutoriel API JavaScript Fetch : GET, POST, gestion des erreurs et délais d'attente

Un didacticiel de l'API JavaScript Fetch testé sur un serveur local : GET et POST, pourquoi 404 ne lance pas, un assistant réutilisable, des chaînes…

Lire l'article →
Développement logiciel

Gestion des fichiers Python : lecture, écriture, CSV, JSON et pathlib avec exemples

Gestion des fichiers Python expliquée avec le code que nous avons exécuté : modes ouverts, avec lecture de fichiers volumineux, CSV, JSON, pathlib, …

Lire l'article →
Développement logiciel

Git merge vs rebase : différences, exemples et quand utiliser chacun

Git merge vs rebase expliqué avec de vraies sorties de log, un tableau comparatif, la règle d'or du rebase et un flux de travail sûr pour les équipes.

Lire l'article →
Développement logiciel

List comprehension Python : syntaxe, exemples et cas à éviter

La list comprehension Python expliquée : syntaxe, filtres, if-else, boucles imbriquées, temps mesurés et cas où une boucle for classique est préféra…

Lire l'article →
Bases de données et SQL

Jointures SQL expliquées avec exemples (Inner, Left, Right, Full)

Comprenez les jointures SQL pas à pas avec des tables et requêtes d'exemple : INNER, LEFT, RIGHT, FULL, CROSS et SELF, plus erreurs courantes et con…

Lire l'article →