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 compliqués de l'API XMLHttpRequest.

Navigateurs pris en charge

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

Source

Si vous n'avez jamais utilisé Promesses auparavant, consultez Introduction to JavaScript Promises (Présentation des promesses JavaScript).

Demande de récupération de base

Voici un exemple implémenté avec 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 la réussite et les cas d'erreur, ainsi qu'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 le même travail que la requête XHR. à titre d'exemple. 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 a lieu de manière asynchrone.

Métadonnées de réponse

L'exemple précédent montre l'état l'objet Response et comment la réponse au format JSON. Voici comment gérer d'autres métadonnées que vous pourriez vouloir auxquels 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 effectuée pour une ressource située sur une autre origine et que cette origine renvoie En-têtes COR, le type est cors. cors sont semblables aux réponses basic, mais elles limitent les en-têtes que vous peut afficher pour Cache-Control, Content-Language, Content-Type, Expires, Last-Modified et Pragma.

Les réponses opaque proviennent d'une origine différente qui ne renvoie pas de CORS en-têtes. Avec une réponse opaque, nous ne pourrons pas lire les données renvoyées ou consulter l'état de la requête, ce qui signifie que vous ne pouvez 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 résoudre. Les modes que vous pouvez définir sont les 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 pour des éléments ayant la même origine ou d'autres origines renvoyer les en-têtes COR 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 n'utilisent pas le CORS et aboutissent à une réponse opaque, mais comme indiqué , il ne s'agit pas possible dans le champ d'application global de la fenêtre pour le moment.

Pour définir le mode, ajoutez un objet "options" comme deuxième paramètre dans la 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 principales caractéristiques des promesses est leur capacité à 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 la méthode json(), qui renvoie une deuxième promesse à partir de l'appel response.json() et crée une contenant le fichier JSON analysé. Si l'analyse échoue, la promesse est rejeté et l’instruction catch 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.

Demande POST

Parfois, une application Web doit appeler une API avec une méthode POST et inclure certaines dans le corps de la requête. Pour ce faire, définissez les paramètres method et body paramètres 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'
})