Un module léger qui apporte une API récupérée à Node.js.

Vous cherchez peut-être les documents V2
Au lieu d'implémenter XMLHttpRequest dans Node.js pour exécuter le polyfill de récupération du navigateur, pourquoi ne pas passer de http natif pour fetch directement l'API? Par conséquent, node-fetch , un code minimal pour une API compatible window.fetch sur Node.js Runtime.
Voir Jason Miller Isomorphic-Unfetch ou Leonardo Quixada pour une utilisation isomorphe (exporte node-fetch pour le côté serveur, whatwg-fetch pour le côté client).
window.fetch API.res.text() et res.json() ) à UTF-8 automatiquement.window.fetch propose, n'hésitez pas à ouvrir un problème. La version stable actuelle ( 3.x ) nécessite au moins Node.js 12.20.0.
npm install node-fetch import fetch from 'node-fetch' ; node-fetch de V3 est un module ESM uniquement - vous n'êtes pas en mesure de l'importer avec require() .
Si vous ne pouvez pas passer à ESM, veuillez utiliser V2 qui reste compatible avec CommonJS. Les correctifs de bogues critiques continueront d'être publiés pour V2.
npm install node-fetch@2 Alternativement, vous pouvez utiliser la fonction Async import() à partir de CommonJS pour charger node-fetch de manière asynchrone:
// mod.cjs
const fetch = ( ... args ) => import ( 'node-fetch' ) . then ( ( { default : fetch } ) => fetch ( ... args ) ) ; Pour utiliser fetch() sans l'importation, vous pouvez corriger l'objet global dans le nœud:
// fetch-polyfill.js
import fetch , {
Blob ,
blobFrom ,
blobFromSync ,
File ,
fileFrom ,
fileFromSync ,
FormData ,
Headers ,
Request ,
Response ,
} from 'node-fetch'
if ( ! globalThis . fetch ) {
globalThis . fetch = fetch
globalThis . Headers = Headers
globalThis . Request = Request
globalThis . Response = Response
}
// index.js
import './fetch-polyfill'
// ... Utilisation d'une ancienne version de la feste de nœud? Consultez les fichiers suivants:
Remarque: La documentation ci-dessous est à jour avec les versions 3.x , si vous utilisez une version plus ancienne, veuillez vérifier comment mettre à niveau.
import fetch from 'node-fetch' ;
const response = await fetch ( 'https://github.com/' ) ;
const body = await response . text ( ) ;
console . log ( body ) ; import fetch from 'node-fetch' ;
const response = await fetch ( 'https://api.github.com/users/github' ) ;
const data = await response . json ( ) ;
console . log ( data ) ; import fetch from 'node-fetch' ;
const response = await fetch ( 'https://httpbin.org/post' , { method : 'POST' , body : 'a=1' } ) ;
const data = await response . json ( ) ;
console . log ( data ) ; import fetch from 'node-fetch' ;
const body = { a : 1 } ;
const response = await fetch ( 'https://httpbin.org/post' , {
method : 'post' ,
body : JSON . stringify ( body ) ,
headers : { 'Content-Type' : 'application/json' }
} ) ;
const data = await response . json ( ) ;
console . log ( data ) ; URLSearchParams est disponible sur l'objet global dans Node.js à partir de v10.0.0. Voir la documentation officielle pour plus de méthodes d'utilisation.
Remarque: L'en-tête Content-Type est défini automatiquement sur x-www-form-urlencoded lorsqu'une instance d' URLSearchParams est donnée comme telle:
import fetch from 'node-fetch' ;
const params = new URLSearchParams ( ) ;
params . append ( 'a' , 1 ) ;
const response = await fetch ( 'https://httpbin.org/post' , { method : 'POST' , body : params } ) ;
const data = await response . json ( ) ;
console . log ( data ) ; Remarque: les réponses 3xx-5xx ne sont pas des exceptions et doivent être gérées dans then() , voir la section suivante.
Envelopper la fonction Fetch dans un bloc try/catch Accassera toutes les exceptions, telles que des erreurs provenant des bibliothèques de nœuds de nœud, comme des erreurs de réseau et des erreurs opérationnelles qui sont des instances de FetchError. Voir le document de gestion des erreurs pour plus de détails.
import fetch from 'node-fetch' ;
try {
await fetch ( 'https://domain.invalid/' ) ;
} catch ( error ) {
console . log ( error ) ;
}Il est courant de créer une fonction d'assistance pour vérifier que la réponse ne contient aucune réponse d'erreur client (4xx) ou serveur (5xx):
import fetch from 'node-fetch' ;
class HTTPResponseError extends Error {
constructor ( response ) {
super ( `HTTP Error Response: ${ response . status } ${ response . statusText } ` ) ;
this . response = response ;
}
}
const checkStatus = response => {
if ( response . ok ) {
// response.status >= 200 && response.status < 300
return response ;
} else {
throw new HTTPResponseError ( response ) ;
}
}
const response = await fetch ( 'https://httpbin.org/status/400' ) ;
try {
checkStatus ( response ) ;
} catch ( error ) {
console . error ( error ) ;
const errorBody = await error . response . text ( ) ;
console . error ( `Error body: ${ errorBody } ` ) ;
}Les cookies ne sont pas stockés par défaut. Cependant, les cookies peuvent être extraits et passés en manipulant les en-têtes de demande et de réponse. Voir l'extrait de l'en-tête Set-Cookie pour plus de détails.
La "Way Node.js" est d'utiliser des flux lorsque cela est possible. Vous pouvez tuyser res.body à un autre flux. Cet exemple utilise Stream.pipeline pour joindre des gestionnaires d'erreurs Stream et attendre que le téléchargement se termine.
import { createWriteStream } from 'node:fs' ;
import { pipeline } from 'node:stream' ;
import { promisify } from 'node:util'
import fetch from 'node-fetch' ;
const streamPipeline = promisify ( pipeline ) ;
const response = await fetch ( 'https://github.githubassets.com/images/modules/logos_page/Octocat.png' ) ;
if ( ! response . ok ) throw new Error ( `unexpected response ${ response . statusText } ` ) ;
await streamPipeline ( response . body , createWriteStream ( './octocat.png' ) ) ; Dans Node.js 14, vous pouvez également utiliser des itérateurs asynchronisés pour lire body ; Cependant, veillez à capter des erreurs - plus une réponse est longue, plus il est probable que de rencontrer une erreur.
import fetch from 'node-fetch' ;
const response = await fetch ( 'https://httpbin.org/stream/3' ) ;
try {
for await ( const chunk of response . body ) {
console . dir ( JSON . parse ( chunk . toString ( ) ) ) ;
}
} catch ( err ) {
console . error ( err . stack ) ;
} Dans Node.js 12, vous pouvez également utiliser des itérateurs asynchronisés pour lire body ; Cependant, les itérateurs asynchronisés avec des flux n'ont pas mûri avant Node.js 14, vous devez donc faire un travail supplémentaire pour vous assurer de gérer les erreurs directement du flux et d'attendre la réponse à la fermeture.
import fetch from 'node-fetch' ;
const read = async body => {
let error ;
body . on ( 'error' , err => {
error = err ;
} ) ;
for await ( const chunk of body ) {
console . dir ( JSON . parse ( chunk . toString ( ) ) ) ;
}
return new Promise ( ( resolve , reject ) => {
body . on ( 'close' , ( ) => {
error ? reject ( error ) : resolve ( ) ;
} ) ;
} ) ;
} ;
try {
const response = await fetch ( 'https://httpbin.org/stream/3' ) ;
await read ( response . body ) ;
} catch ( err ) {
console . error ( err . stack ) ;
} import fetch from 'node-fetch' ;
const response = await fetch ( 'https://github.com/' ) ;
console . log ( response . ok ) ;
console . log ( response . status ) ;
console . log ( response . statusText ) ;
console . log ( response . headers . raw ( ) ) ;
console . log ( response . headers . get ( 'content-type' ) ) ; Contrairement aux navigateurs, vous pouvez accéder manuellement à des en-têtes de co Set-Cookie à l'aide Headers.raw() . Il s'agit d'une API node-fetch uniquement.
import fetch from 'node-fetch' ;
const response = await fetch ( 'https://example.com' ) ;
// Returns an array of values, instead of a string of comma-separated values
console . log ( response . headers . raw ( ) [ 'set-cookie' ] ) ; import fetch , {
Blob ,
blobFrom ,
blobFromSync ,
File ,
fileFrom ,
fileFromSync ,
} from 'node-fetch'
const mimetype = 'text/plain'
const blob = fileFromSync ( './input.txt' , mimetype )
const url = 'https://httpbin.org/post'
const response = await fetch ( url , { method : 'POST' , body : blob } )
const data = await response . json ( )
console . log ( data )Node-Fetch est livré avec une implémentation FormData conforme aux spécifications pour publier des charges utiles multipartiales / format de data
import fetch , { FormData , File , fileFrom } from 'node-fetch'
const httpbin = 'https://httpbin.org/post'
const formData = new FormData ( )
const binary = new Uint8Array ( [ 97 , 98 , 99 ] )
const abc = new File ( [ binary ] , 'abc.txt' , { type : 'text/plain' } )
formData . set ( 'greeting' , 'Hello, world!' )
formData . set ( 'file-upload' , abc , 'new name.txt' )
const response = await fetch ( httpbin , { method : 'POST' , body : formData } )
const data = await response . json ( )
console . log ( data )Si vous devez pour une raison quelconque de publier un flux provenant de n'importe quel endroit arbitraire, vous pouvez ajouter un blob ou un élément de type de fichier.
L'exigence minimale est qu'il ait:
Symbol.toStringTag getter ou propriété qui est soit Blob ou Filestream() ou une méthode arrayBuffer() qui renvoie un ArrayBuffer. Le stream() doit renvoyer n'importe quel objet asynchronisé tant qu'il cède uint8array (ou tampon), donc les flux réelables et les flux de whatwg fonctionnent très bien.
formData . append ( 'upload' , {
[ Symbol . toStringTag ] : 'Blob' ,
size : 3 ,
* stream ( ) {
yield new Uint8Array ( [ 97 , 98 , 99 ] )
} ,
arrayBuffer ( ) {
return new Uint8Array ( [ 97 , 98 , 99 ] ) . buffer
}
} , 'abc.txt' ) Vous pouvez annuler les demandes avec AbortController . Une mise en œuvre suggérée est abort-controller .
Un exemple de synchronisation d'une demande après 150 ms pourrait être réalisé comme suit:
import fetch , { AbortError } from 'node-fetch' ;
// AbortController was added in node v14.17.0 globally
const AbortController = globalThis . AbortController || await import ( 'abort-controller' )
const controller = new AbortController ( ) ;
const timeout = setTimeout ( ( ) => {
controller . abort ( ) ;
} , 150 ) ;
try {
const response = await fetch ( 'https://example.com' , { signal : controller . signal } ) ;
const data = await response . json ( ) ;
} catch ( error ) {
if ( error instanceof AbortError ) {
console . log ( 'request was aborted' ) ;
}
} finally {
clearTimeout ( timeout ) ;
}Voir les cas de test pour plus d'exemples.
url une chaîne représentant l'URL pour récupéreroptions Options pour la demande HTTP (S)Promise<Response>Effectuez un (s) http (s).
url doit être une URL absolue, comme https://example.com/ . Une URL-URL ( /file/under/root ) ou une URL relative au protocole ( //can-be-http-or-https.com/ ) entraînera une Promise rejetée.
Les valeurs par défaut sont affichées après chaque clé d'option.
{
// These properties are part of the Fetch Standard
method : 'GET' ,
headers : { } , // Request headers. format is the identical to that accepted by the Headers constructor (see below)
body : null , // Request body. can be null, or a Node.js Readable stream
redirect : 'follow' , // Set to `manual` to extract redirect headers, `error` to reject redirect
signal : null , // Pass an instance of AbortSignal to optionally abort requests
// The following properties are node-fetch extensions
follow : 20 , // maximum redirect count. 0 to not follow redirect
compress : true , // support gzip/deflate content encoding. false to disable
size : 0 , // maximum response body size in bytes. 0 to disable
agent : null , // http(s).Agent instance or function that returns an instance (see below)
highWaterMark : 16384 , // the maximum number of bytes to store in the internal buffer before ceasing to read from the underlying resource.
insecureHTTPParser : false // Use an insecure HTTP parser that accepts invalid HTTP headers when `true`.
} Si aucune valeur n'est définie, les en-têtes de demande suivants seront envoyés automatiquement:
| Tête | Valeur |
|---|---|
Accept-Encoding | gzip, deflate, br (quand options.compress === true ) |
Accept | */* |
Content-Length | (calculé automatiquement, si possible) |
Host | (Informations sur l'hôte et le port de l'URI cible) |
Transfer-Encoding | chunked (quand req.body est un flux) |
User-Agent | node-fetch |
Remarque: Lorsque body est un Stream , Content-Length n'est pas définie automatiquement.
L'option agent vous permet de spécifier des options liées à la mise en réseau qui sont hors de portée de la fetch, y compris et sans s'y limiter:
Voir http.Agent pour plus d'informations.
Si aucun agent n'est spécifié, l'agent par défaut fourni par Node.js est utilisé. Notez que cela a changé dans Node.js 19 pour avoir keepalive True par défaut. Si vous souhaitez activer keepalive dans une version antérieure de Node.js, vous pouvez remplacer l'agent conformément à l'échantillon de code suivant.
De plus, l'option agent accepte une fonction qui renvoie http (s) .Agent Instance étant donné l'URL de courant, ceci est utile pendant une chaîne de redirection à travers le protocole HTTP et HTTPS.
import http from 'node:http' ;
import https from 'node:https' ;
const httpAgent = new http . Agent ( {
keepAlive : true
} ) ;
const httpsAgent = new https . Agent ( {
keepAlive : true
} ) ;
const options = {
agent : function ( _parsedURL ) {
if ( _parsedURL . protocol == 'http:' ) {
return httpAgent ;
} else {
return httpsAgent ;
}
}
} ; Le flux sur Node.js a une taille de tampon interne plus petite (16 Ko, alias highWaterMark ) à partir de navigateurs côté client (> 1 Mo, non cohérents entre les navigateurs). À cause de cela, lorsque vous écrivez une application isomorphe et en utilisant res.clone() , il restera avec une grande réponse dans le nœud.
La façon recommandée de résoudre ce problème est de résoudre la réponse clonée en parallèle:
import fetch from 'node-fetch' ;
const response = await fetch ( 'https://example.com' ) ;
const r1 = response . clone ( ) ;
const results = await Promise . all ( [ response . json ( ) , r1 . text ( ) ] ) ;
console . log ( results [ 0 ] ) ;
console . log ( results [ 1 ] ) ; Si pour une raison quelconque, vous n'aimez pas la solution ci-dessus, puisque 3.x vous pouvez modifier l'option highWaterMark :
import fetch from 'node-fetch' ;
const response = await fetch ( 'https://example.com' , {
// About 1MB
highWaterMark : 1024 * 1024
} ) ;
const result = await res . clone ( ) . arrayBuffer ( ) ;
console . dir ( result ) ; Passé à l'option insecureHTTPParser sur http (s) .request. Voir http.request pour plus d'informations.
L'option redirect: 'manual' pour la mèche de nœud est différente du navigateur et des spécifications, ce qui se traduit par une réponse filtrée à redirect opaque. Le nœud-fetch vous donne à la place la réponse filtrée de base typique.
import fetch from 'node-fetch' ;
const response = await fetch ( 'https://httpbin.org/status/301' , { redirect : 'manual' } ) ;
if ( response . status === 301 || response . status === 302 ) {
const locationURL = new URL ( response . headers . get ( 'location' ) , response . url ) ;
const response2 = await fetch ( locationURL , { redirect : 'manual' } ) ;
console . dir ( response2 ) ;
}Une demande HTTP (s) contenant des informations sur l'URL, la méthode, les en-têtes et le corps. Cette classe implémente l'interface corporelle.
En raison de la nature de Node.js, les propriétés suivantes ne sont pas mises en œuvre en ce moment:
typedestinationmodecredentialscacheintegritykeepaliveLes propriétés d'extension de la recherche de nœuds suivantes sont fournies:
followcompresscounteragenthighWaterMarkVoir les options de signification exacte de ces extensions.
(conforme aux spécifications)
input une chaîne représentant une URL, ou une autre Request (qui sera clonée)options Options pour la demande HTTP (S) Construit un nouvel objet Request . Le constructeur est identique à celui du navigateur.
Dans la plupart des cas, fetch(url, options) est plus simple que la création d'un objet Request .
Une réponse HTTP (S). Cette classe implémente l'interface corporelle.
Les propriétés suivantes ne sont pas implémentées dans le nœud à ce moment:
trailer(conforme aux spécifications)
body une String ou un flux Readableoptions un dictionnaire d'options ResponseInit Construit un nouvel objet Response . Le constructeur est identique à celui du navigateur.
Étant donné que Node.js n'implémente pas les travailleurs de service (pour lesquels cette classe a été conçue), il faut rarement construire une Response directement.
(conforme aux spécifications)
Propriété de commodité représentant si la demande s'est terminée normalement. Évaluera à TRUE si le statut de réponse était supérieur ou égal à 200 mais inférieur à 300.
(conforme aux spécifications)
Propriété de commodité représentant si la demande a été redirigée au moins une fois. Évaluera TRUE si le compteur de redirection interne est supérieur à 0.
(déviation par rapport aux spécifications)
Propriété de commodité représentant le type de réponse. Node-Fetch ne prend en charge que 'default' et 'error' et n'utilise pas de réponses filtrées.
Cette classe permet de manipuler et d'itréter un ensemble d'en-têtes HTTP. Toutes les méthodes spécifiées dans la norme Fetch sont implémentées.
(conforme aux spécifications)
init Argument facultatif pour pré-remplir l'objet Headers Construisez un nouvel objet Headers . init peut être null , un objet Headers , un objet de carte de valeur clé ou tout objet itérable.
// Example adapted from https://fetch.spec.whatwg.org/#example-headers-class
import { Headers } from 'node-fetch' ;
const meta = {
'Content-Type' : 'text/xml'
} ;
const headers = new Headers ( meta ) ;
// The above is equivalent to
const meta = [ [ 'Content-Type' , 'text/xml' ] ] ;
const headers = new Headers ( meta ) ;
// You can in fact use any iterable objects, like a Map or even another Headers
const meta = new Map ( ) ;
meta . set ( 'Content-Type' , 'text/xml' ) ;
const headers = new Headers ( meta ) ;
const copyOfHeaders = new Headers ( headers ) ; Body est une interface abstraite avec des méthodes applicables aux classes Request et Response .
(déviation par rapport aux spécifications)
Readable Les données sont encapsulées dans l'objet Body . Notez que même si la norme Fetch nécessite que la propriété soit toujours un whatwg ReadableStream , dans le nœud-fetch, il s'agit d'un flux Readable Node.js.
(conforme aux spécifications)
BooleanUne propriété booléenne pour si cet corps a été consommé. Selon les spécifications, un corps consommé ne peut plus être utilisé.
fetch est livré avec des méthodes d'analyse des charges utiles multipart/form-data ainsi que des corps x-www-form-urlencoded utilisant .formData() Cela vient de l'idée que le travailleur du service peut intercepter ces messages avant qu'il ne soit envoyé au serveur pour les modifier. Ceci est utile pour quiconque construit un serveur afin que vous puissiez l'utiliser pour analyser et consommer des charges utiles.
import http from 'node:http'
import { Response } from 'node-fetch'
http . createServer ( async function ( req , res ) {
const formData = await new Response ( req , {
headers : req . headers // Pass along the boundary value
} ) . formData ( )
const allFields = [ ... formData ]
const file = formData . get ( 'uploaded-files' )
const arrayBuffer = await file . arrayBuffer ( )
const text = await file . text ( )
const whatwgReadableStream = file . stream ( )
// other was to consume the request could be to do:
const json = await new Response ( req ) . json ( )
const text = await new Response ( req ) . text ( )
const arrayBuffer = await new Response ( req ) . arrayBuffer ( )
const blob = await new Response ( req , {
headers : req . headers // So that `type` inherits `Content-Type`
} . blob ( )
} )(extension de fetch de nœud)
Une erreur opérationnelle dans le processus de récupération. Voir Error-Handling.md pour plus d'informations.
(extension de fetch de nœud)
Une erreur lancée lorsque la demande est interrompue en réponse à l'événement abort d' AbortSignal . Il a une propriété de name d' AbortError . Voir Error-Handling.md pour plus d'informations.
Étant donné que les types 3.x sont regroupés avec node-fetch , vous n'avez donc pas besoin d'installer de packages supplémentaires.
Pour les versions plus anciennes, veuillez utiliser les définitions de type de définitif:
npm install --save-dev @types/[email protected]Merci à GitHub / Fetch pour avoir fourni une référence de mise en œuvre solide.
![]() | ![]() | ![]() | ![]() | ![]() |
|---|---|---|---|---|
| David Frank | Jimmy Wärting | Antoni Kepinski | Richie Bendall | Gregor Martynus |
Mit