Introduction à fetch()

fetch() vous permet d'effectuer des requêtes réseau semblables à XMLHttpRequest (XHR). La principale différence est que l'API Fetch utilise des promesses, qui disposent d'une API plus simple pour vous aider à éviter les rappels complexes de l'API XMLHttpRequest.

Navigateurs pris en charge

  • Chrome: 42.
  • Edge: 14.
  • Firefox: 39.
  • Safari: 10.1.

Source

Si vous n'avez jamais utilisé de promesses, consultez Présentation des promesses JavaScript.

Requête de récupération de base

Voici un exemple implémenté avec un XMLHttpRequest, puis avec fetch. Nous souhaitons demander une URL, obtenir une réponse et l'analyser au format JSON.

XMLHttpRequest

Un XMLHttpRequest a besoin de deux écouteurs pour gérer les cas de réussite et d'erreur, ainsi que d'un appel à open() et send(). Exemple tiré de la documentation MDN

function reqListener () {
  const data = JSON.parse(this.responseText);
  console.log(data);
}

function reqError (err) {
  console.log('Fetch Error :-S', err);
}

const oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;
oReq.open('get', './api/some.json', true);
oReq.send();

Récupérer

Notre requête de récupération se présente comme suit:

fetch('./api/some.json')
  .then(response => {
    if (response.status !== 200) {
      console.log(`Looks like there was a problem. Status Code: ${response.status}`);

      return;
    }

    // Examine the text in the response
    response.json().then(function(data) {
      console.log(data);
    });
  })
  .catch(err => {
    console.log('Fetch Error :-S', err);
  });

La requête fetch() n'a besoin que d'un seul appel pour effectuer la même tâche que l'exemple XHR. Pour traiter la réponse, nous vérifions d'abord que l'état de la réponse est 200, puis analysons la réponse au format JSON. La réponse à une requête fetch() est un objet Stream, ce qui signifie qu'après avoir appelé la méthode json(), une promesse est renvoyée. Le flux se produit de manière asynchrone.

Métadonnées de réponse

L'exemple précédent a montré l'état de l'objet Response et comment analyser la réponse au format JSON. Voici comment gérer les autres métadonnées auxquelles vous souhaitez accéder, comme les en-têtes:

fetch('users.json').then(response => {
  console.log(response.headers.get('Content-Type'));
  console.log(response.headers.get('Date'));

  console.log(response.status);
  console.log(response.statusText);
  console.log(response.type);
  console.log(response.url);
});

Types de réponses

Lorsque nous effectuons une requête de récupération, la réponse reçoit un response.type de basic, cors ou opaque. Ces types indiquent d'où vient la ressource, et vous pouvez les utiliser pour déterminer comment traiter l'objet de réponse.

Lorsque le navigateur demande une ressource sur la même origine, la réponse a un type basic avec des restrictions sur ce que vous pouvez afficher à partir de la réponse.

Si une requête est envoyée pour une ressource sur une autre origine et que cette origine renvoie des en-têtes CORS, le type est cors. Les réponses cors sont similaires aux réponses basic, mais elles limitent les en-têtes que vous pouvez afficher à Cache-Control, Content-Language, Content-Type, Expires, Last-Modified et Pragma.

Les réponses opaque proviennent d'une autre origine qui ne renvoie pas d'en-têtes CORS. Avec une réponse opaque, nous ne pourrons pas lire les données renvoyées ni afficher l'état de la requête. Vous ne pourrez donc pas vérifier si la requête a abouti.

Vous pouvez définir un mode pour une requête de récupération afin que seuls certains types de requêtes soient résolus. Vous pouvez définir les modes suivants:

  • same-origin ne réussit que pour les requêtes d'éléments de la même origine et rejette toutes les autres requêtes.
  • cors autorise les requêtes d'éléments de la même origine et d'autres origines qui renvoient les en-têtes CORS appropriés.
  • cors-with-forced-preflight effectue une vérification préalable au vol avant d'effectuer une requête.
  • no-cors est destiné à envoyer des requêtes à d'autres origines qui ne disposent pas d'en-têtes CORS et à générer une réponse opaque. Toutefois, comme indiqué , cela n'est pas possible dans le champ d'application global de la fenêtre pour le moment.

Pour définir le mode, ajoutez un objet d'options comme deuxième paramètre de la requête fetch et définissez le mode dans cet objet:

fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'})
  .then(response => response.text())
  .then(text => {
    console.log('Request successful', text);
  })
  .catch(error => {
    log('Request failed', error)
  });

Chaînage de promesses

L'une des grandes caractéristiques des promesses est la possibilité de les enchaîner. Pour fetch(), cela vous permet de partager la logique entre les requêtes de récupération.

Si vous travaillez avec une API JSON, vous devez vérifier l'état et analyser le JSON pour chaque réponse. Vous pouvez simplifier votre code en définissant l'état et l'analyse JSON dans des fonctions distinctes qui renvoient des promesses, et en utilisant la requête de récupération pour ne gérer que les données finales et le cas d'erreur.

function status (response) {
  if (response.status >= 200 && response.status < 300) {
    return Promise.resolve(response)
  } else {
    return Promise.reject(new Error(response.statusText))
  }
}

function json (response) {
  return response.json()
}

fetch('users.json')
  .then(status)
  .then(json)
  .then(data => {
    console.log('Request succeeded with JSON response', data);
  }).catch(error => {
    console.log('Request failed', error);
  });

Cet exemple définit une fonction status qui vérifie le response.status et renvoie une promesse résolue sous la forme Promise.resolve() ou une promesse refusée sous la forme Promise.reject(). Il s'agit de la première méthode appelée dans la chaîne fetch().

Si la promesse est résolue, le script appelle ensuite la méthode json(), qui renvoie une deuxième promesse à partir de l'appel response.json() et crée un objet contenant le fichier JSON analysé. Si l'analyse échoue, la promesse est rejetée et l'instruction de capture s'exécute.

Cette structure vous permet de partager la logique entre toutes vos requêtes de récupération, ce qui facilite la maintenance, la lecture et les tests du code.

Requête POST

Parfois, une application Web doit appeler une API avec une méthode POST et inclure certains paramètres dans le corps de la requête. Pour ce faire, définissez les paramètres method et body dans les options fetch():

fetch(url, {
    method: 'post',
    headers: {
      "Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
    },
    body: 'foo=bar&lorem=ipsum'
  })
  .then(json)
  .then(data => {
    console.log('Request succeeded with JSON response', data);
  })
  .catch(error => {
    console.log('Request failed', error);
  });

Envoyer des identifiants avec une requête de récupération

Pour effectuer une requête de récupération avec des identifiants tels que des cookies, définissez la valeur credentials de la requête sur "include":

fetch(url, {
  credentials: 'include'
})