Utiliser l'API Fetch
[Link]/fr/docs/Web/API/Fetch_API/Using_Fetch
7 septembre 2025
La méthode fetch() permet l'utilisation optionnelle d'un deuxième paramètre, un objet init
pour contrôler différents paramètres.
Voir la page sur la méthode fetch() pour plus de détails et l'exhaustivité des options
disponibles.
// Exemple d'implémentation pour une requête POST
async function postData(url = "", donnees = {}) {
// Les options par défaut sont indiquées par *
const response = await fetch(url, {
method: "POST", // *GET, POST, PUT, DELETE, etc.
mode: "cors", // no-cors, *cors, same-origin
cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json",
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: "follow", // manual, *follow, error
referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin,
origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin,
unsafe-url
body: [Link](donnees), // le type utilisé pour le corps doit correspondre à
l'en-tête "Content-Type"
});
return [Link](); // transforme la réponse JSON reçue en objet JavaScript natif
}
postData("[Link] { solution: 42 }).then((donnees) => {
[Link](donnees); // Les données JSON analysées par l'appel `[Link]()`
});
On notera que mode: "no-cors" ne permet qu'un ensemble limité d'en-têtes dans la requête :
Accept
Accept-Language
Content-Language
Content-Type avec une valeur application/x-www-form-urlencoded,
multipart/form-data, ou text/plain
Pour interrompre une opération fetch() en cours, on pourra utiliser les interfaces
AbortController et AbortSignal.
1/11
const controleur = new AbortController();
const signal = [Link];
const url = "video.mp4";
const btnTelechargement = [Link]("#telechargement");
const btnInterruption = [Link]("#interrompre");
[Link]("click", async () => {
try {
const reponse = await fetch(url, { signal });
[Link]("Téléchargement terminé", reponse);
} catch (error) {
[Link](`Erreur lors du téléchargement : ${[Link]}`);
}
});
[Link]("click", () => {
[Link]();
[Link]("Téléchargement interrompu");
});
Pour que les navigateurs envoient une requête avec les informations d'authentification, tant
pour les requêtes sur la même origine qu'entre origines différentes, on ajoutera credentials:
'include' à l'objet init passé à la méthode fetch().
fetch("[Link] {
credentials: "include",
});
Note : On ne pourra pas utiliser Access-Control-Allow-Origin: * pour les requêtes avec
credentials: 'include'. Pour ces cas-là, il faut fournir l'origine exacte. Même si une
extension de débridage du CORS est utilisée, la requête échouera.
Note : Les navigateurs ne devraient pas envoyer d'informations d'authentification dans les
requêtes préparatoires (preflight requests), quelle que soit la valeur de cette option. Pour plus
d'informations, voir la section de la page CORS sur les requêtes avec informations
d'authentification.
Si on souhaite uniquement envoyer les informations d'authentification lorsque l'URL de la
requête se situe sur la même origine que le script appelant, on utilisera credentials: 'same-
origin'.
// Le script qui appelle se situe sur l'origine '[Link]
fetch("[Link] {
credentials: "same-origin",
});
Pour s'assurer que les navigateurs n'envoient aucune information d'authentification dans la
requête, on utilisera credentials: 'omit'.
2/11
fetch("[Link] {
credentials: "omit",
});
On peut utiliser fetch() pour envoyer des données au format JSON à un serveur avec une
requête POST.
async function postJSON(donnees) {
try {
const reponse = await fetch("[Link] {
method: "POST", // ou 'PUT'
headers: {
"Content-Type": "application/json",
},
body: [Link](donnees),
});
const resultat = await [Link]();
[Link]("Réussite :", resultat);
} catch (erreur) {
[Link]("Erreur :", erreur);
}
}
const donnees = { login: "Jean Biche" };
postJSON(donnees);
Les fichiers peuvent être envoyés à l'aide d'un élément HTML <input type="file" />, de
FormData, et de fetch().
async function upload(donneesFormulaires) {
try {
const reponse = await fetch("[Link] {
method: "PUT",
body: donneesFormulaires,
});
const resultat = await [Link]();
[Link]("Réussite :", resultat);
} catch (erreur) {
[Link]("Erreur :", erreur);
}
}
const donneesFormulaires = new FormData();
const champFichier = [Link]('input[type="file"]');
[Link]("username", "abc123");
[Link]("avatar", [Link][0]);
upload(donneesFormulaires);
3/11
On peut envoyer plusieurs fichiers en utilisant un élément HTML <input type="file"
multiple />, FormData, et fetch().
async function uploadMultiple(donneesFormulaires) {
try {
const reponse = await fetch("[Link] {
method: "POST",
body: donneesFormulaires,
});
const resultat = await [Link]();
[Link]("Réussite :", resultat);
} catch (erreur) {
[Link]("Erreur :", erreur);
}
}
const photos = [Link]('input[type="file"][multiple]');
const donneesFormulaires = new FormData();
[Link]("title", "Mes vacances");
for (const [i, photo] of [Link]([Link]).entries()) {
[Link](`photos_${i}`, photo);
}
uploadMultiple(donneesFormulaires);
Les fragments reçus dans une réponse ne sont pas segmentés proprement à chaque fin de
ligne. Il s'agit d'objets binaires Uint8Array, pas de chaînes de caractères. Si on récupère un
fichier texte et qu'on souhaite le traiter ligne à ligne, il faut gérer cette représentation. Dans
l'exemple qui suit, on illustre une façon de procéder en créant un itérateur sur les lignes (pour
garder l'exemple simple, on considère que le texte est encodé en UTF-8 et on ne gère pas les
erreurs de récupération).
4/11
async function* makeTextFileLineIterator(fileURL) {
const utf8Decoder = new TextDecoder("utf-8");
const response = await fetch(fileURL);
const reader = [Link]();
let { value: chunk, done: readerDone } = await [Link]();
chunk = chunk ? [Link](chunk) : "";
const newline = /\r?\n/gm;
let startIndex = 0;
let result;
while (true) {
const result = [Link](chunk);
if (!result) {
if (readerDone) break;
const remainder = [Link](startIndex);
({ value: chunk, done: readerDone } = await [Link]());
chunk = remainder + (chunk ? [Link](chunk) : "");
startIndex = [Link] = 0;
continue;
}
yield [Link](startIndex, [Link]);
startIndex = [Link];
}
if (startIndex < [Link]) {
// Last line didn't end in a newline char
yield [Link](startIndex);
}
}
async function run() {
for await (const line of makeTextFileLineIterator(urlOfFile)) {
processLine(line);
}
}
run();
Une promesse fetch() échouera avec une exception TypeError s'il y a une erreur réseau ou
que la politique CORS est incorrectement configurée côté serveur. En revanche, une réponse
404 qui indiquerait un problème de permission ou autre ne déclencherait pas une telle erreur.
Aussi, pour bien vérifier que l'opération fetch() est réussie, il faudra vérifier que la promesse
est tenue, mais aussi vérifier que la propriété [Link] vaut true. Le code correspondant
ressemblerait à :
5/11
async function fetchImage() {
try {
const response = await fetch("[Link]");
if (![Link]) {
throw new Error("La réponse n'est pas OK");
}
const myBlob = await [Link]();
[Link] = [Link](myBlob);
} catch (error) {
[Link]("Un problème est survenu lors de la récupération :", error);
}
}
Plutôt que de passer le chemin de la ressource à l'appel fetch(), on peut créer un objet
représentant une requête à l'aide du constructeur Request() et passer cet objet comme
argument à la méthode fetch() :
async function fetchImage(request) {
try {
const response = await fetch(request);
if (![Link]) {
throw new Error("La réponse n'est pas OK");
}
const monBlob = await [Link]();
[Link] = [Link](monBlob);
} catch (error) {
[Link]("Erreur :", error);
}
}
const mesEntetes = new Headers();
const maRequete = new Request("[Link]", {
method: "GET",
headers: mesEntetes,
mode: "cors",
cache: "default",
});
fetchImage(maRequete);
Request() accepte les mêmes paramètres que la méthode fetch(). On peut même lui passer
un objet représentant une requête existante pour en créer une copie :
const uneAutreRequete = new Request(maRequete, monInit);
Ce mécanisme de duplication est plutôt utile, car les corps des requêtes et des réponses ne
peuvent être utilisés qu'une seule fois. En construisant une telle copie, on peut à nouveau
utiliser la requête ou la réponse tout en adaptant les options init si besoin. Attention, la copie
doit être effectuée avant que le corps ait été lu.
6/11
Note : Il existe également la méthode clone() pour créer une copie. Ces deux méthodes de
copie échoueront si le corps de la requête ou de la réponse originale a déjà été lu. En
revanche, lire le corps d'une réponse ou d'une requête clonée ne modifiera pas l'état de lecture
de l'original.
L'interface Headers permet de créer ses propres objets représentant des en-têtes HTTP à
l'aide du constructeur Headers(). Un objet d'en-têtes est un tableau de correspondance entre
des noms et des valeurs :
const contenu = "Coucou le monde";
const mesEntetes = new Headers();
[Link]("Content-Type", "text/plain");
[Link]("Content-Length", [Link]());
[Link]("X-Custom-Header", "ATraiterImmediatement");
On pourra obtenir le même résultat en passant un tableau de tableaux ou un littéral objet au
constructeur :
const mesEntetes = new Headers({
"Content-Type": "text/plain",
"Content-Length": [Link](),
"X-Custom-Header": "ATraiterImmediatement",
});
Le contenu de ces en-têtes peut être consulté et modifié :
[Link]([Link]("Content-Type")); // true
[Link]([Link]("Set-Cookie")); // false
[Link]("Content-Type", "text/html");
[Link]("X-Custom-Header", "UneAutreValeur");
[Link]([Link]("Content-Length")); // 11
[Link]([Link]("X-Custom-Header")); // ['ATraiterImmediatement',
'UneAutreValeur']
[Link]("X-Custom-Header");
[Link]([Link]("X-Custom-Header")); // null
Certaines de ces opérations ne sont utiles qu'avec les service workers, néanmoins, elles
fournissent une API plus pratique pour manipuler les en-têtes.
Toutes les méthodes de Headers lèvent une exception TypeError si le nom d'en-tête utilisé
n'est pas valide en HTTP. Les opérations de modification déclencheront une exception
TypeError s'il y a une garde d'immuabilité (). Sinon, elles échouent de façon silencieuse :
const maReponse = [Link]();
try {
[Link]("Origin", "[Link]
} catch (e) {
[Link]("On ne se fait pas passer pour une banque !");
}
7/11
Un bon usage des en-têtes consiste à vérifier si le type de contenu est correct avant d'aller
plus loin dans le traitement. Par exemple :
async function fetchJSON(requete) {
try {
const reponse = await fetch(requete);
const typeContenu = [Link]("content-type");
if (!typeContenu || ) {
throw new TypeError("Ah, nous n'avons pas eu de JSON !");
}
const donneesJSON = await [Link]();
// on continue le traitement des données
} catch (erreur) {
[Link]("Erreur :", erreur);
}
}
Les en-têtes sont envoyés avec les requêtes et reçus avec les réponses. Plusieurs règles
indiquent les informations qui peuvent ou non être modifiées et pour traduire cela, les objets
des en-têtes ont une propriété interne guard. Cette dernière n'est pas exposée sur le Web,
mais a un impact sur les opérations de modification qui sont permises.
Les valeurs pour guard sont :
La valeur par défaut.
Une garde pour l'objet d'en-têtes obtenus avec une requête ([Link]).
Une garde pour l'objet d'en-têtes obtenus avec une requête créée avec [Link] no-
cors.
Une garde pour l'objet d'en-têtes obtenus avec une réponse ([Link]).
Une garde qui indique que l'objet d'en-têtes est en lecture seule. Elle est principalement
utilisée pour les service workers.
Note : Il n'est pas possible d'ajouter ou de modifier l'en-tête Content-Length d'un objet d'en-
têtes de réponse avec une garde. De même, on ne pourra pas insérer d'en-tête Set-Cookie
pour une réponse : les service workers ne sont pas autorisés à écrire des cookies dans des
réponses de synthèse.
Nous l'avons vu ci-avant, ce sont des instances de Response qui sont renvoyées lors de la
résolution des promesses fournies par fetch().
Les propriétés les plus fréquemment utilisées pour ces objets Response sont :
[Link]
Un entier contenant le code de statut HTTP de la réponse (la valeur par défaut est 200).
8/11
[Link]
Une chaîne de caractères qui contient le message du code de statut HTTP (la valeur par
défaut est la chaîne vide ""). On notera que HTTP/2 ne prend pas en charge les messages de
statut.
[Link]
Nous avons vu cette propriété plus tôt dans cet article : il s'agit d'un raccourci pour vérifier que
le statut appartient à l'intervalle 200-299. Cette propriété est une valeur booléenne.
On peut également créer des réponses artificiellement en JavaScript. Cela n'est généralement
utile qu'au sein des service workers, lorsqu'on fournit une réponse sur mesure à une requête
reçue en utilisant la méthode respondWith() :
const monCorps = new Blob();
addEventListener("fetch", (event) => {
// Un ServiceWorker qui intercepte une requête de récupération
[Link](
new Response(monCorps, {
headers: { "Content-Type": "text/plain" },
}),
);
});
Le constructeur Response() prend deux arguments optionnels :
Un corps pour la réponse
Un objet d'initialisation des paramètres, semblable à celui qu'on fournit au constructeur
Request().
Note : La méthode statique error() renvoie une réponse d'erreur. De même, redirect()
renvoie une réponse résultant en une redirection vers l'URL indiquée. Ces méthodes sont
uniquement pertinentes dans le cadre des service workers.
Les requêtes et les réponses peuvent avoir un corps, contenant des données. Un corps pourra
être une instance d'un des types suivants :
ArrayBuffer
TypedArray (Uint8Array, etc.)
DataView
Blob
File
String ou une chaîne de caractères littérale
URLSearchParams
FormData
9/11
Les interfaces Request et Response partagent les méthodes suivantes pour extraire les
données du corps. Toutes ces méthodes renvoient une promesse qui pourra être résolue avec
le contenu effectif.
[Link]() / [Link]()
[Link]() / [Link]()
[Link]() / [Link]()
[Link]() / [Link]()
[Link]() / [Link]()
Note : Ces méthodes permettent de travailler plus facilement avec du contenu non-textuel (par
rapport à ce que permettait XMLHttpRequest).
On peut fournir des corps aux requêtes en utilisant le deuxième paramètre et sa propriété
form :
const form = new FormData([Link]("login-form"));
fetch("/login", {
method: "POST",
body: form,
});
Tant la requête que la réponse, ou la fonction fetch() essaieront de déterminer intelligemment
le type de contenu. Une requête définira automatiquement un en-tête Content-Type si aucun
n'a été fourni avec le paramètre options.
La prise en charge de l'API Fetch peut être détectée en vérifiant la présence de Headers,
Request, Response ou fetch() au sein des portées Window ou Worker. Par exemple :
if ([Link]) {
// On exécute la requête avec Fetch ici
} else {
// On tente autre chose avec XMLHttpRequest ?
}
La spécification de fetch() diffère de [Link]() :
La promesse renvoyée par fetch() ne lèvera pas d'exception en cas d'erreurs HTTP,
même si le statut de la réponse HTTP est 404 ou 500. Dès que le serveur répond avec
les en-têtes, la promesse sera bien résolue (la propriété [Link] étant fixée à false
si le statut de la réponse est en dehors de l'intervalle [200, 299]). La promesse sera
uniquement rompue s'il y a une erreur réseau ou tout autre évènement qui a empêché sa
complétion.
À moins que fetch() ne soit appelé avec l'option credentials valant include, fetch() :
N'enverra pas de cookies pour les requêtes vers d'autres origines
N'écrira pas de cookies provenant de réponses d'autres origines
10/11
L'API Service Worker
La politique HTTP d'accès aux ressources entre origines (CORS)
HTTP
Une prothèse d'émulation (polyfill) pour fetch()
D'autres exemples (en anglais) sur d'utilisation de Fetch sur GitHub
11/11