Fermer

novembre 2, 2023

Comment utiliser l’API Fetch dans Node.js, Deno et Bun —


Dans cet article, nous verrons comment utiliser le Récupérer l’API avec Node.js, Deno et Bun.

Table des matières

Récupérer l’API et XMLHttpRequest

La récupération de données via une requête HTTP est une activité fondamentale des applications Web. Vous avez peut-être effectué de tels appels dans le navigateur, mais l’API Fetch est nativement prise en charge dans Node.js, Deno et Bun.

Dans un navigateur, vous pouvez demander des informations à un serveur afin de pouvoir les afficher sans actualisation en plein écran. Ceci est généralement connu sous le nom de Demande Ajax ou une application d’une seule page (SPA). Entre 1999 et 2015, XMLHttpRequête était la seule option – et le reste si tu le souhaites afficher la progression du téléchargement du fichier. XMLHttpRequest est une API basée sur le rappel assez lourde, mais elle permet un contrôle précis et, malgré son nom, elle gérera les réponses dans des formats autres que XML, tels que le texte, le binaire, le JSON et le HTML.

Les navigateurs ont implémenté le Récupérer l’API à partir de 2015. Il s’agit d’une alternative plus simple, plus facile, plus cohérente et basée sur des promesses à XMLHttpRequest.

Votre code côté serveur peut également vouloir effectuer des requêtes HTTP, généralement pour appeler des API sur d’autres serveurs. Dès leur première sortie, les deux Pas et Chignon les environnements d’exécution reproduisaient utilement l’API Fetch du navigateur afin qu’un code similaire puisse s’exécuter à la fois sur le client et sur le serveur. Node.js nécessitait un module tiers tel que récupération de nœud ou axios jusqu’en février 2022, date à laquelle la version 18 a ajouté l’API Fetch standard. C’est toujours considéré expérimentalmais vous pouvez maintenant utiliser fetch() partout avec un code identique dans la plupart des cas.

Un exemple de récupération de base

Cet exemple simple récupère les données de réponse à partir d’un URI :

const response = await fetch('https://example.com/data.json');

Le fetch() call renvoie une promesse qui se résout avec un Objet de réponse fournir des informations sur le résultat. Vous pouvez analyser le corps de la réponse HTTP dans un objet JavaScript à l’aide de la méthode basée sur la promesse .json() méthode:

const data = await response.json();



Récupération côté client ou côté serveur

L’API peut être identique sur toutes les plates-formes, mais les navigateurs appliquent des restrictions lors de la création de données côté client. fetch() demandes :

  • Partage de ressources multi-origines (CORS)

    JavaScript côté client ne peut communiquer qu’avec les points de terminaison de l’API au sein de son propre domaine. Un script chargé depuis https://domainA.com/js/main.js peut appeler n’importe quel service au https://domainA.com/tel que https://domainA.com/api/ ou https://domainA.com/data/.

    Il est impossible d’appeler un service au https://domainB.com/ – à moins que ce serveur autorise l’accès en définissant un En-tête HTTP Access-Control-Allow-Origin.

  • Politique de sécurité du contenu (CSP)

    Vos sites Web/applications peuvent définir un Content-Security-Policy En-tête HTTP ou balise méta pour contrôler les actifs autorisés dans une page. Il peut empêcher l’injection accidentelle ou malveillante de scripts, iframes, polices, images, vidéos, etc. Par exemple, définir default-src 'self' s’arrête fetch() demander des données en dehors de son propre domaine (XMLHttpRequest, WebSocket, les événements envoyés par le serveur et les balises sont également restreints).

Les appels d’API Fetch côté serveur dans Node.js, Deno et Bun ont moins de restrictions et vous pouvez demander des données à n’importe quel serveur. Cela dit, les API tierces peuvent :

  • exiger une sorte d’authentification ou d’autorisation à l’aide de clés ou d’OAuth
  • avoir des seuils de demande maximum, par exemple pas plus d’un appel par minute, ou
  • facturer des frais commerciaux pour l’accès

Vous pouvez utiliser côté serveur fetch() appels aux requêtes proxy côté client afin que vous puissiez éviter les problèmes CORS et CSP. Cela dit, n’oubliez pas d’être un citoyen du Web consciencieux et de ne pas bombarder les services de milliers de requêtes qui pourraient les faire disparaître !

Demandes de récupération personnalisées

L’exemple ci-dessus demande des données à l’URI https://example.com/data.json. Sous la surface, JavaScript crée un Objet de requêtequi représente tous les détails de cette requête, tels que la méthode, les en-têtes, le corps, etc.

fetch() accepte deux arguments :

  • le Ressource – une chaîne ou Objet URLet
  • un facultatif choix paramètre avec d’autres paramètres de demande

Par exemple:

const response = await fetch('https://example.com/data.json', {
   method: 'GET',
   credentials: 'omit',
   redirect: 'error',
   priority: 'high'
});

Le choix L’objet peut définir les propriétés suivantes dans Node.js ou dans le code côté client :

propriétévaleurs
methodGET (le défaut), POST, PUT, PATCH, DELETEou HEAD
headersune chaîne ou Objet en-têtes
bodypeut être une chaîne, un JSON, un blob, etc.
modesame-origin, no-corsou cors
credentialsomit, same-originou include cookies et en-têtes d’authentification HTTP
redirectfollow, errorou manual gestion des redirections
referrerl’URL de référence
integrityintégrité des sous-ressources hacher
signalun Objet AbortSignal à annuler la demande

En option, vous pouvez créer un Objet de requête et transmettez-le à fetch(). Cela peut être pratique si vous pouvez définir les points de terminaison de l’API à l’avance ou si vous souhaitez envoyer une série de requêtes similaires :

const request = new Request('https://example.com/api/', {
  method: 'POST',
  body: '{"a": 1, "b": 2, "c": 3}',
  credentials: 'omit'
});

console.log(`fetching ${ request.url }`);
const response = await fetch(request);

Gestion des en-têtes HTTP

Vous pouvez manipuler et examiner les en-têtes HTTP dans le demande et réponse utilisant un Objet en-têtes. L’API vous sera familière si vous avez utilisé Cartes JavaScript:


const headers = new Headers({
  'Content-Type': 'text/plain',
});


headers.append('Authorization', 'Basic abc123');


headers.set('Content-Type', 'application/json');


const type = headers.get('Content-Type');


if (headers.has('Authorization')) {

   
   headers.delete('Authorization');

}


headers.forEach((value, name) => {
  console.log(`${ name }: ${ value }`);
});


const response = await fetch('https://example.com/data.json', {
   method: 'GET',
   headers
});


response.headers.forEach((value, name) => {
  console.log(`${ name }: ${ value }`);
});

Récupérer la promesse résolue et rejetée

Vous pourriez présumer un fetch() je promets que rejeter lorsqu’un point de terminaison renvoie un 404 Not Found ou une erreur de serveur similaire. Ce n’est pas le cas ! La promesse sera résoudreparce que cet appel a réussi, même si le résultat n’était pas celui que vous attendiez.

UN fetch() la promesse n’est rejetée que lorsque :

  • vous faites une demande invalide, telle que fetch('httttps://!invalid\URL/');
  • toi avorter le fetch() demande, ou
  • il y a une erreur réseau, telle qu’un échec de connexion

Analyse des réponses de récupération

Réussi fetch() les appels renvoient un Objet de réponse contenant des informations sur l’état et les données renvoyées. Les propriétés sont :

propriétédescription
oktrue si la réponse a été positive
statusle code d’état HTTP, tel que 200 pour le succès
statusTextle texte d’état HTTP, tel que OK pour un code 200
urll’URL
redirectedtrue si la demande a été redirigée
typele type de réponse : basic, cors, error, opaqueou opaqueredirect
headersla réponse Objet en-têtes
bodyun Flux lisible du contenu du corps (ou nul)
bodyUsedtrue si le corps a été lu

Les méthodes d’objet Response suivantes renvoient toutes une promesse, vous devez donc utiliser await ou .then blocs :

méthodedescription
text()renvoie le corps sous forme de chaîne
json()analyse le corps en un objet JavaScript
arrayBuffer()renvoie le corps comme un TableauBuffer
blob()renvoie le corps comme un Goutte
formData()renvoie le corps comme un Objet FormData de paires clé/valeur
clone()clone la réponse, généralement pour que vous puissiez analyser le corps de différentes manières

const response = await fetch('https://example.com/data.json');


if ( response.ok && response.headers.get('Content-Type') === 'application/json') {

   
   const obj = await response.json();

}

Abandon des demandes de récupération

Node.js n’expirera pas un fetch() demande; ça pourrait durer éternellement ! Les navigateurs peuvent également attendre entre une et cinq minutes. Tu devrais abandonner fetch() dans des circonstances normales où vous attendez une réponse raisonnablement rapide.

L’exemple suivant utilise un Abandonner le contrôleur objet, qui passe un signal propriété au deuxième fetch() paramètre. Un timeout exécute le .abort() méthode si la récupération ne se termine pas dans les cinq secondes :


const
  controller = new AbortController(),
  signal = controller.signal,
  timeout = setTimeout(() => controller.abort(), 5000);

try {

  const response = await fetch('https://example.com/slowrequest/', { signal });

  clearTimeout(timeout);

  console.log( response.ok );

}
catch (err) {

  
  console.log(err);

}

Node.js, Deno, Bun et la plupart des navigateurs sortis depuis mi-2022 prennent également en charge Signal d’abandon. Cela offre une solution plus simple temps mort() méthode pour que vous n’ayez pas à gérer vos propres minuteries :

try {

  
  const response = await fetch('https://example.com/slowrequest/', {
    signal: AbortSignal.timeout( 5000 ),
  });

  console.log( response.ok );

}
catch (err) {

  
  console.log(err);

}

Récupérations efficaces

Comme toute opération asynchrone basée sur des promesses, vous ne devez effectuer que fetch() appels en série lorsque l’entrée d’un appel dépend de la sortie d’un précédent. Le code suivant ne fonctionne pas aussi bien qu’il le pourrait, car chaque appel d’API doit attendre que le précédent soit résolu ou rejeté. Si chaque réponse prend une seconde, cela prendra au total trois secondes :


const response1 = await fetch('https://example1.com/api/');
const response2 = await fetch('https://example2.com/api/');
const response3 = await fetch('https://example3.com/api/');

Le Méthode Promise.allSettled() exécute les promesses simultanément et les remplit lorsque toutes ont été résolues ou rejetées. Ce code se termine à la vitesse de réponse la plus lente. Ce sera trois fois plus rapide :

const data = await Promise.allSettled(
  [
    'https://example1.com/api/',
    'https://example2.com/api/',
    'https://example3.com/api/'
  ].map(url => fetch( url ))
);

data renvoie un tableau d’objets où :

  • chacun a un status chaîne de propriété de "fullfilled" ou "rejected"
  • si résolu, un value la propriété renvoie le fetch() réponse
  • en cas de rejet, un reason la propriété renvoie l’erreur

Résumé

Sauf si vous utilisez une ancienne version de Node.js (17 ou inférieure), l’API Fetch est disponible en JavaScript sur le serveur et le client. Il est flexible, facile à utiliser et cohérent sur tous les environnements d’exécution. Un module tiers ne devrait être nécessaire que si vous avez besoin de fonctionnalités plus avancées telles que la mise en cache, les tentatives ou la gestion des fichiers.






Source link

novembre 2, 2023