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.
fetch()renvoie une promesse pour unResponse, et la lecture du corps prend une secondeawait.- 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.stringifyet définissez l’en-têteContent-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-TypeavecFormData. 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
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.
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.
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 →DevOpsVariables 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 logicielLimitation 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 testsSe 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 logicielsCouverture 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 SQLDELETE 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 SQLVues 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 logicielInterface 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 logicielPython *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 logicielFonctions 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 artificielleQue 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 →DevOpsSurveillance 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 →DevOpsVolumes 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 testsTDD 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 logicielsTests 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 SQLExplication 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 SQLInstruction 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 logicielQu'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 logicielBoucle 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 logicielGé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 artificielleQue 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 →DevOpsDé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 testsTests 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 logicielsTests 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 logicielsScé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 SQLOptimisation 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 SQLSQL 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 logicielTutoriel 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 logicielGestion 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 logicielGit 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 logicielList 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 SQLJointures 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 →