Network Requests

Fetch API & AJAX

Toute application web moderne communique avec un serveur. La Fetch API est la méthode standard pour envoyer des requêtes, lire des réponses et mettre à jour la page sans rechargement complet.

intermediate15 min readUpdated 15 sept. 2026
js
// api.js
async function getUsers() {
  const res = await fetch("/api/users", {
    headers: { Accept: "application/json" },
  });
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json();
}

const users = await getUsers();
console.log(users);
Standard
Fait partie du Fetch Living Standard
Retourne
Une Promise<Response>
Remplace
XMLHttpRequest
Lecture du corps en
json, text, blob, formData
Annulation via
AbortController
Rejet lors de
Erreurs réseau uniquement

Pratique

Essayer une requête fetch

Cette démo récupère une URL de données JSON, elle fonctionne donc hors ligne.

Essayer une requête fetch

Cette démo récupère une URL de données JSON, elle fonctionne donc hors ligne.

Pourquoi c'est important

Pourquoi fetch est essentiel

Une seule API pour tout

Le même appel fetch gère les API JSON, le texte, les fichiers, les streams et les données de formulaire sur tous les navigateurs et runtimes.

Basé sur les Promises

Fetch retourne une promise, ce qui s'intègre parfaitement avec async/await et les combinateurs de Promise.

Sécurisé par défaut

Des configurations par défaut cohérentes concernant CORS et les identifiants vous aident à éviter les fuites de données accidentelles.

Le tableau complet

Les trois piliers de chaque requête

Une requête réseau se compose d'une requête, d'une réponse et de la gestion des erreurs qui les entourent. Maîtrisez ces trois aspects et le reste n'est que du détail.

La requête

Envoyer

L'URL, la méthode, les headers et le corps décrivent exactement ce que vous voulez que le serveur fasse.

La réponse

Lire

Le statut, les headers et un corps que vous analysez en JSON, texte, blob ou stream.

Les erreurs

Récupérer

Distinguez les pannes réseau des statuts d'erreur HTTP, puis affichez quelque chose d'utile à l'utilisateur.

Fetch en un coup d'œil

Ce que la Fetch API vous apporte

Requêtes GET

Récupérer des données depuis une URL et lire le corps de la réponse.

POST & PUT

Envoyer des données au serveur avec une méthode, des headers et un corps.

Lecture de JSON

res.json() analyse le corps de la réponse en une valeur JavaScript.

Gestion des erreurs

Vérifiez res.ok pour les erreurs HTTP et utilisez catch pour les pannes réseau.

Annulation

AbortController arrête les requêtes qui ne sont plus nécessaires.

CORS & identifiants

Comprendre les origines, les requêtes preflight et le moment où les cookies sont envoyés.

Un bref aperçu

De XMLHttpRequest à fetch

  1. 1999

    XMLHttpRequest

    Microsoft introduit XHR, et l'ère de l'AJAX commence.

    99
  2. 2005

    L'AJAX se démocratise

    Gmail et Google Maps prouvent que les pages peuvent se mettre à jour sans rechargement.

    05
  3. 2015

    La Fetch API

    Un remplaçant plus propre et basé sur les promises pour XHR arrive dans les navigateurs.

    15
  4. 2017

    async / await

    Fetch devient considérablement plus lisible grâce à la nouvelle syntaxe.

    17
  5. Aujourd'hui

    Le standard

    Fetch est l'API de requête standard dans les navigateurs, Node.js, Deno et les runtimes edge.

    Aujourd'hui

Le guide complet

Fetch API & AJAX: Tout ce que vous devez savoir

Qu’est-ce que l’AJAX ?

AJAX signifie Asynchronous JavaScript and XML, un terme apparu en 2005 lorsque Gmail et Google Maps ont démontré pour la première fois qu’une page pouvait récupérer de nouvelles données sans rechargement complet. La partie XML appartient désormais largement au passé — les API modernes renvoient du JSON — mais l’idée fondamentale reste la même : communiquer avec un serveur en arrière-plan et mettre à jour la page dynamiquement.

L’outil originel était XMLHttpRequest. Il fonctionne toujours, mais son API est maladroite et repose sur des callbacks. Le remplaçant moderne est la Fetch API, une interface basée sur les promesses, disponible dans les navigateurs, Node.js, Deno et les runtimes edge.

Votre première requête fetch

fetch prend une URL et renvoie une promesse pour un Response.

// basic.js
const response = await fetch("https://api.example.com/users");
const users = await response.json();

console.log(users);

C’est tout pour le cas nominal. La subtilité est que fetch se résout même pour les codes de statut d’erreur, donc une erreur 404 ne lève pas d’exception. Vous devez inspecter la réponse vous-même.

L’objet Response

L’objet Response vous indique ce que le serveur a renvoyé.

// response.js
const response = await fetch("/api/users");

response.ok;      // true for status 200–299
response.status;  // 200, 404, 500, ...
response.statusText;
response.headers.get("content-type");

const data = await response.json();   // parse JSON
const text = await response.text();   // raw text
const blob = await response.blob();   // binary data
const form = await response.formData();

Le corps d’une réponse ne peut être lu qu’une seule fois. Si vous avez besoin à la fois du texte brut et du JSON analysé, appelez response.clone() avant la lecture, ou analysez le texte vous-même. Notez également que response.json() rejette la promesse si le corps n’est pas un JSON valide — une autre raison d’envelopper vos appels dans un bloc try/catch.

Gérer les erreurs correctement

Il existe deux types d’échecs, et ils se comportent différemment.

  1. Erreurs réseau — absence de connexion, échec DNS, CORS bloqué. fetch est rejeté, donc catch les gère.
  2. Erreurs HTTP — 404, 401, 500. fetch est résolu ; vous devez vérifier response.ok ou response.status.
// errors.js
async function getUser(id) {
  try {
    const response = await fetch(`/api/users/${id}`);
    if (!response.ok) {
      throw new Error(`Request failed with status ${response.status}`);
    }
    return await response.json();
  } catch (error) {
    console.error("Could not load user:", error);
    throw error;
  }
}

Traiter explicitement ces deux cas est ce qui différencie un code fragile d’un code résilient. Le guide de gestion des erreurs détaille la stratégie globale.

Envoyer des données avec POST, PUT et DELETE

Passez un objet d’options pour modifier la méthode, ajouter des headers et joindre un corps de requête (body).

// create.js
async function createUser(user) {
  const response = await fetch("/api/users", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Accept: "application/json",
    },
    body: JSON.stringify(user),
  });

  if (!response.ok) throw new Error("Could not create user");
  return response.json();
}

await createUser({ name: "Ada", role: "engineer" });

Utilisez PUT pour remplacer une ressource, PATCH pour en mettre à jour une partie, et DELETE pour la supprimer. Pour l’upload de fichiers, créez un objet FormData et passez-le comme body — le navigateur définira automatiquement le type de contenu multipart approprié.

En-têtes et authentification

Les en-têtes transportent des métadonnées sur la requête. Vous pouvez les définir pour chaque requête, et de nombreuses API attendent un jeton d’autorisation.

// auth.js
const response = await fetch("/api/me", {
  headers: {
    Authorization: `Bearer ${token}`,
    Accept: "application/json",
  },
});

Ne codez jamais de secrets en dur dans le code côté client — tout ce qui est envoyé au navigateur est public. Les jetons doivent provenir d’un flux de connexion et être stockés avec prudence.

Annuler des requêtes

Une requête qui n’est plus pertinente — parce que l’utilisateur a saisi un autre caractère, a changé de page ou que le composant a été démonté — doit être annulée. AbortController permet de faire précisément cela.

// abort.js
const controller = new AbortController();

fetch("/api/search?q=javascript", { signal: controller.signal })
  .then((res) => res.json())
  .then(console.log)
  .catch((error) => {
    if (error.name === "AbortError") return;
    console.error(error);
  });

// Cancel when it is no longer needed
controller.abort();

Comme fetch ne possède pas d’option de timeout, AbortController est également la méthode standard pour en implémenter un.

// timeout.js
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 5000);

try {
  const res = await fetch("/api/slow", { signal: controller.signal });
  return await res.json();
} finally {
  clearTimeout(timer);
}

CORS et identifiants

Les navigateurs appliquent la politique de même origine (same-origin policy) : JavaScript ne peut pas lire les réponses provenant d’une origine différente, à moins que le serveur ne l’autorise explicitement. Cette autorisation est assurée par le CORS, qui se configure entièrement côté serveur via des en-têtes de réponse tels que Access-Control-Allow-Origin. Si vous rencontrez une erreur CORS, la solution se trouve dans la configuration du serveur, et non dans votre appel fetch.

Par défaut, fetch n’envoie pas de cookies vers des URL d’origines différentes. Pour les inclure, définissez credentials: "include" et assurez-vous que le serveur autorise les requêtes avec identifiants. C’est une source courante de confusion du type « ça fonctionne dans Postman, mais pas dans le navigateur ».

Patterns pratiques

États de chargement, de succès et d’erreur. Reflétez toujours le cycle de vie de la requête dans l’UI.

// state.js
async function loadPosts() {
  showSpinner();
  try {
    const res = await fetch("/api/posts");
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    renderPosts(await res.json());
  } catch (error) {
    showError("Could not load posts. Try again.");
  } finally {
    hideSpinner();
  }
}

Recherche avec debounce. Annulez la requête précédente dès qu’une nouvelle commence, afin que des réponses lentes n’écrasent pas des résultats récents. Associez AbortController à un court délai de debounce.

Requêtes parallèles. Utilisez Promise.all lorsque plusieurs endpoints sont nécessaires simultanément, et Promise.allSettled lorsqu’un résultat partiel reste utile.

Bonnes pratiques

  • Vérifiez toujours response.ok avant d’analyser le corps de la requête.
  • Définissez un header Accept explicite et un Content-Type lors de l’envoi d’un corps de requête.
  • Enveloppez les requêtes attendues (awaited) dans un bloc try/catch et affichez un message utile.
  • Annulez les requêtes obsolètes avec AbortController.
  • Regroupez les appels API dans un petit module au lieu de disperser les URLs dans vos composants.
  • Ne placez jamais de secrets dans le code côté client.
  • Affichez des états de chargement et d’erreur pour que l’UI ne semble jamais plantée.

Erreurs courantes

  • Supposer que fetch lève une exception en cas d’erreur 404 ou 500.
  • Oublier JSON.stringify sur le corps d’une requête.
  • Oublier le header Content-Type et recevoir une erreur de parsing du serveur.
  • Lire le corps d’une réponse deux fois.
  • Ignorer le CORS jusqu’à ce que le navigateur bloque la requête en production.
  • Ne pas annuler les requêtes et laisser des données obsolètes gagner une course critique (race condition).

Et après ?

Fetch est le pont entre votre front end et le monde extérieur. Combinez-le avec le DOM pour afficher les résultats, async/await pour séquencer vos opérations, et la gestion des erreurs pour gérer les échecs avec élégance. À partir de là, approfondissez vos connaissances sur les méthodes, les codes de statut et les headers, car ils structurent chaque requête que vous envoyez.

Vérification de la réponse

fetch ne rejette la promise qu'en cas de panne réseau. Un code 404 ou 500 résout toujours la promise, vérifiez donc res.ok.

Préférer
const res = await fetch("/api/data");
if (!res.ok) {
  throw new Error(`HTTP ${res.status}`);
}
const data = await res.json();
Éviter
const res = await fetch("/api/data");
const data = await res.json();
// silently parses error pages

Envoi de JSON

Indiquez au serveur ce que vous envoyez et transformez le corps en chaîne de caractères.

Préférer
await fetch("/api/users", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ name: "Ada" }),
});
Éviter
await fetch("/api/users", {
  method: "POST",
  body: { name: "Ada" },
});

FAQ

Foire aux questions

Keep learning

Related topics from the roadmap.

$ commencer à apprendre

Prêt à apprendre Fetch API & AJAX ?

Notre tutoriel interactif vous guide à travers Fetch API & AJAX pas à pas — avec des quiz et du vrai code que vous pouvez exécuter dans le navigateur.