Jusqu’à présent, nous en savons pas mal sur fetch
.
Voyons le reste de l’API, pour couvrir toutes ses capacités.
Remarque: la plupart de ces options sont rarement utilisées. Vous pouvez ignorer ce chapitre et continuer à utiliser fetch
correctement.
Pourtant, il est bon de savoir ce que fetch
peut faire, donc si le besoin s’en fait sentir, vous pouvez revenir et lire les détails.
Voici la liste complète de toutes les options possibles de fetch
avec leurs valeurs par défaut (alternatives dans les commentaires) :
let promise = fetch(url, {
method: "GET", // POST, PUT, DELETE, etc.
headers: {
// la valeur de l'en-tête du type de contenu est généralement définie automatiquement
// selon la requête du body
"Content-Type": "text/plain;charset=UTF-8"
},
body: undefined, // string, FormData, Blob, BufferSource, ou URLSearchParams
referrer: "about:client", // ou "" to send no Referer header,
// or an url from the current origin
referrerPolicy: "strict-origin-when-cross-origin", // no-referrer-when-downgrade, no-referrer, origin, same-origin...
mode: "cors", // same-origin, no-cors
credentials: "same-origin", // omit, include
cache: "default", // no-store, reload, no-cache, force-cache, or only-if-cached
redirect: "follow", // manual, error
integrity: "", // un hash, comme "sha256-abcdef1234567890"
keepalive: false, // true
signal: undefined, // AbortController pour annuler la requête
window: window // null
});
Une liste impressionnante, non ?
Nous avons entièrement couvert method
, headers
et body
dans le chapitre Fetch.
L’option signal
est couverte dans Fetch: Abort.
Explorons maintenant le reste des capacités.
referrer, referrerPolicy
Ces options régissent la façon dont fetch
définit l’en-tête HTTP Referer
.
Habituellement, cet en-tête est défini automatiquement et contient l’url de la page à l’origine de la requête. Dans la plupart des scénarios, ce n’est pas important du tout, parfois, pour des raisons de sécurité, il est logique de le supprimer ou de le raccourcir.
L’option referer
permet de définir n’importe quel Referer
dans l’origine actuelle) ou de le supprimer.
Pour n’envoyer aucun referer, définissez une chaîne de caractères vide :
fetch('/page', {
referrer: "" // pas de header Referer
});
Pour définir une autre URL dans l’origine actuelle :
fetch('/page', {
// en supposant que nous sommes sur https://javascript.info
// nous pouvons définir n'importe quel en-tête Referer, mais uniquement dans l'origine actuelle
referrer: "https://javascript.info/anotherpage"
});
L’option referrerPolicy
établit des règles générales pour Referer
.
Les requêtes sont divisées en 3 types :
- Requête à la même origine.
- Requête à une autre origine.
- Requête de HTTPS à HTTP (du protocole sûr au protocole non sécurisé).
Contrairement à l’option referrer
qui permet de définir la valeur exacte de Referer
, referrerPolicy
indique les règles générales du navigateur pour chaque type de requête.
Les valeurs possibles sont décrites dans la spécification Referrer Policy:
"strict-origin-when-cross-origin"
– la valeur par défaut : pour la même origine, envoie leReferer
complet, pour l’origine croisée, envoie uniquement l’origine, à moins qu’il ne s’agisse d’une requête HTTPS→HTTP , puis n’envoie rien."no-referrer-when-downgrade"
– leReferer
complet est toujours envoyé, sauf si nous envoyons une requête de HTTPS à HTTP (vers le protocole le moins sécurisé)."no-referrer"
– n’envoie jamais leReferer
."origine"
– n’envoie que l’origine dans leReferer
, pas l’URL complète de la page, par ex. uniquementhttp://site.com
au lieu dehttp://site.com/path
."origin-when-cross-origin"
– envoie leReferer
complet à la même origine, mais uniquement la partie d’origine pour les requêtes cross-origin (comme ci-dessus)."same-origin"
– envoie leReferer
complet à la même origine, mais pas deReferer
pour les requêtes cross-origin."strict-origin"
– envoie uniquement l’origine, pas leReferer
pour les requêtes HTTPS→HTTP."unsafe-url"
– envoie toujours l’url complète dansReferer
, même pour les requêtes HTTPS→HTTP.
Voici un tableau avec toutes les combinaisons :
Valeur | Pour la même origine | Pour une autre origine | HTTPS→HTTP |
---|---|---|---|
"no-referrer" |
- | - | - |
"no-referrer-when-downgrade" |
full | full | - |
"origin" |
origin | origin | origin |
"origin-when-cross-origin" |
full | origin | origin |
"same-origin" |
full | - | - |
"strict-origin" |
origin | origin | - |
"strict-origin-when-cross-origin" or "" (default) |
full | origin | - |
"unsafe-url" |
full | full | full |
Disons que nous avons une zone d’administration avec une structure d’URL qui ne devrait pas être connue de l’extérieur du site.
Si nous envoyons un fetch
, alors par défaut, il envoie toujours l’en-tête Referer
avec l’url complète de notre page (sauf lorsque nous demandons de HTTPS à HTTP, alors pas de Referer
).
Par exemple : Referer: https://javascript.info/admin/secret/paths
.
Si nous souhaitons que d’autres sites Web connaissent uniquement la partie origin, pas le chemin URL, nous pouvons définir l’option :
fetch('https://another.com/page', {
// ...
referrerPolicy: "origin-when-cross-origin" // Referer: https://javascript.info
});
Nous pouvons le mettre à tous les appels fetch
, peut-être l’intégrer dans la bibliothèque JavaScript de notre projet qui fait toutes les requêtes et utilise fetch
à l’intérieur.
Sa seule différence par rapport au comportement par défaut est que pour les requêtes vers une autre origine, fetch
envoie uniquement la partie origine de l’URL (par exemple https://javascript.info
, sans le chemin). Pour les requêtes à notre origine, nous obtenons toujours le Referer
complet (peut-être utile à des fins de débogage).
fetch
La Referrer policy, décrite dans la spécification, n’est pas seulement pour fetch
, mais plus globale.
Plus particulièrement, il est possible de définir la politique par défaut pour toute la page en utilisant l’en-tête HTTP Referrer-Policy
, ou par lien, avec <a rel="noreferrer">
.
mode
L’option mode
est un garde-fou qui empêche les requêtes cross-origin occasionnelles :
"cors"
– par défaut, les requêtes cross-origin sont autorisées, comme décrit dans Fetch: Requêtes Cross-Origin,"same-origin"
– les requêtes cross-origin requests sont interdites,"no-cors"
– seules les requêtes cross-origin sécurisées sont autorisées.
Cette option peut être utile lorsque l’URL de fetch
provient d’un tiers, et nous voulons un “interrupteur de mise hors tension” pour limiter les capacités de cross-origin.
credentials
L’option credentials
spécifie si fetch
doit envoyer des cookies et des en-têtes d’autorisation HTTP avec la requête.
"same-origin"
– par défaut, n’envoyez pas de requêtes cross-origin,"include"
– toujours envoyer, nécessiteAccept-Control-Allow-Credentials
du serveur cross-origin pour que JavaScript accède à la réponse, qui a été traitée dans le chapitre Fetch: Requêtes Cross-Origin,"omit"
– ne jamais envoyer, même pour des requêtes cross-origin.
cache
Par défaut, les requêtes fetch
utilisent la mise en cache HTTP standard. Autrement dit, il honore les en-têtes Expires
et Cache-Control
, envoie If-Modified-Since
, et ainsi de suite. Tout comme les requêtes HTTP régulières.
Les options cache
permettent d’ignorer le cache HTTP ou d’affiner son utilisation :
"default"
–fetch
utilise des règles et des en-têtes de cache HTTP standard,"no-store"
– ignore totalement le cache HTTP, ce mode devient la valeur par défaut si nous définissons un en-têteIf-Modified-Since
,If-None-Match
,If-Unmodified-Since
,If-Match
, ouIf-Range
,"reload"
– ne prenez pas le résultat du cache HTTP (le cas échéant), mais remplissez le cache avec la réponse (si les en-têtes de réponse le permettent),"no-cache"
– créer une requête conditionnelle s’il y a une réponse mise en cache, et sinon une requête normale. Remplissez le cache HTTP avec la réponse,"force-cache"
– utilise une réponse du cache HTTP, même si elle est périmée. S’il n’y a pas de réponse dans le cache HTTP, fait une requête HTTP régulière, se comporte normalement,"only-if-cached"
– utilise une réponse du cache HTTP, même si elle est périmée. S’il n’y a pas de réponse dans le cache HTTP, alors erreur. Fonctionne uniquement lorsque lemode
est sur"same-origin"
.
redirect
Normalement, fetch
suit de manière transparente les redirections HTTP, comme 301, 302 etc.
L’option redirect
permet de changer cela :
"follow"
– par défaut, suit les redirections HTTP,"error"
– erreur en cas de redirection HTTP,"manual"
– permet de traiter manuellement les redirections HTTP. En cas de redirection, nous obtiendrons un objet de réponse spécial, avecresponse.hype="opaqueredirect"
et un statut zéro/vide ainsi que la plupart des autres propriétés.
integrity
L’option intégrité
permet de vérifier si la réponse correspond à la somme de contrôle connue à l’avance.
Comme décrit dans la spécification, les fonctions de hachage prises en charge sont SHA-256, SHA-384 et SHA-512, il peut y en avoir d’autres en fonction du navigateur.
Par exemple, nous téléchargeons un fichier et nous savons que sa somme de contrôle SHA-256 est “abcdef” (une vraie somme de contrôle est plus longue, bien sûr).
Nous pouvons le mettre dans l’option integrity
, comme ceci :
fetch('http://site.com/file', {
integrity: 'sha256-abcdef'
});
Ensuite, fetch
calculera SHA-256 seul et le comparera avec notre chaîne de caractères. En cas de non-concordance, une erreur est déclenchée.
keepalive
L’option keepalive
indique que la demande peut “survivre” à la page Web qui l’a initiée.
Par exemple, nous recueillons des statistiques sur la façon dont le visiteur actuel utilise notre page (clics de souris, fragments de page qu’il consulte), pour analyser et améliorer l’expérience utilisateur.
Lorsque le visiteur quitte notre page – nous aimerions enregistrer les données sur notre serveur.
Nous pouvons utiliser l’événement window.onunload
pour cela :
window.onunload = function() {
fetch('/analytics', {
method: 'POST',
body: "statistics",
keepalive: true
});
};
Normalement, lorsqu’un document est déchargé, toutes les requêtes réseau associées sont abandonnées. Mais l’option keepalive
indique au navigateur d’exécuter la requête en arrière-plan, même après avoir quitté la page. Cette option est donc essentielle à la réussite de notre demande.
Elle a quelques limitations :
- Nous ne pouvons pas envoyer des mégaoctets : la limite de corps pour les requêtes
keepalive
est de 64kb.- Si nous avons besoin de rassembler beaucoup de statistiques sur la visite, nous devons les envoyer régulièrement par paquets, afin qu’il ne reste plus grand-chose pour la dernière requête
onunload
. - Cette limite s’applique à toutes les demandes
keepalive
ensemble. En d’autres termes, nous pouvons effectuer plusieurs requêteskeepalive
en parallèle, mais la somme de leurs longueurs de corps ne doit pas dépasser 64 Kb.
- Si nous avons besoin de rassembler beaucoup de statistiques sur la visite, nous devons les envoyer régulièrement par paquets, afin qu’il ne reste plus grand-chose pour la dernière requête
- Nous ne pouvons pas gérer la réponse du serveur si le document est déchargé. Donc, dans notre exemple,
fetch
réussira grâce àkeepalive
, mais les fonctions suivantes ne fonctionneront pas.- Dans la plupart des cas, comme l’envoi de statistiques, ce n’est pas un problème, car le serveur accepte simplement les données et envoie généralement une réponse vide à de telles demandes.