Un módulo de peso ligero que trae API de Fetch a Node.js.

Es posible que esté buscando los documentos V2
En lugar de implementar XMLHttpRequest en node.js para ejecutar el polyfill de búsqueda específico del navegador, ¿por qué no pasar de http nativo a fetch API directamente? Por lo tanto, node-fetch , código mínimo para una window.fetch Fetch API compatible en Node.js Runtime.
Consulte el campo cruzado Isomorphic-Unfetch de Jason Miller o el uso cruzado de Leonardo Quixada para el uso isomórfico (exporta node-fetch para el lado del servidor, whatwg-fetch para el lado del cliente).
window.fetch . Fetch API.res.text() y res.json() ) a UTF-8 automáticamente.window.fetch Oferta, no dude en abrir un problema. La versión estable actual ( 3.x ) requiere al menos nodo.js 12.20.0.
npm install node-fetch import fetch from 'node-fetch' ; node-fetch de V3 es un módulo solo ESM: no puede importarlo con require() .
Si no puede cambiar a ESM, use V2, que permanece compatible con CommonJS. Las correcciones críticas de errores continuarán publicando para V2.
npm install node-fetch@2 Alternativamente, puede usar la función Async import() de CommonJS para cargar node-fetch asincrónico:
// mod.cjs
const fetch = ( ... args ) => import ( 'node-fetch' ) . then ( ( { default : fetch } ) => fetch ( ... args ) ) ; Para usar fetch() sin importarlo, puede parchear el objeto global en el nodo:
// 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'
// ... ¿Usando una versión antigua de Node-Fetch? Consulte los siguientes archivos:
Nota: La siguiente documentación está actualizada con las versiones 3.x , si está utilizando una versión anterior, verifique cómo actualizar.
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 en el objeto global en Node.js a partir de V10.0.0. Consulte la documentación oficial para obtener más métodos de uso.
Nota: El encabezado Content-Type solo se establece automáticamente en x-www-form-urlencoded cuando una instancia de URLSearchParams se da como tal:
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 ) ; Nota: Las respuestas 3xx-5xx no son excepciones, y deben manejarse en then() , consulte la siguiente sección.
Envolver la función de búsqueda en un bloque de try/catch captará todas las excepciones, como errores que se originan en bibliotecas de núcleo de nodo, como errores de red y errores operativos que son instancias de Fetcherror. Consulte el documento de manejo de errores para obtener más detalles.
import fetch from 'node-fetch' ;
try {
await fetch ( 'https://domain.invalid/' ) ;
} catch ( error ) {
console . log ( error ) ;
}Es común crear una función de ayuda para verificar que la respuesta no contenga respuestas de error de cliente (4xx) o servidor (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 } ` ) ;
}Las cookies no se almacenan de forma predeterminada. Sin embargo, las cookies se pueden extraer y pasar mediante la manipulación de encabezados de solicitud y respuesta. Consulte el encabezado de extracto de Set-Cookie para más detalles.
La "forma node.js" es usar transmisiones cuando sea posible. Puede canalizar res.body a otra corriente. Este ejemplo usa stream.pipeline para adjuntar los controladores de errores de transmisión y esperar a que se complete la descarga.
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' ) ) ; En Node.js 14 también puede usar iteradores asíncronos para leer body ; Sin embargo, tenga cuidado de atrapar errores: cuanto más se ejecute una respuesta, más probabilidades tendrá de encontrar un error.
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 ) ;
} En Node.js 12 también puede usar iteradores asíncronos para leer body ; Sin embargo, los iteradores de asíncrono con transmisiones no maduraron hasta el nodo.js 14, por lo que debe hacer un trabajo adicional para asegurarse de manejar errores directamente desde la transmisión y esperar su respuesta para cerrar completamente.
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' ) ) ; A diferencia de los navegadores, puede acceder a encabezados Set-Cookie procesar manualmente usando Headers.raw() . Esta es una API de solo node-fetch .
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 viene con una implementación de FormData compatible con especificaciones para publicar cargas útiles de datos multipart/formulario
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 por alguna razón necesita publicar una transmisión que provenga de cualquier lugar arbitrario, puede agregar una blob o un archivo de un elemento similar a un archivo.
El requisito mínimo es que tiene:
Symbol.toStringTag que es Blob o Filestream() o un método arrayBuffer() que devuelve un ArrayBuffer. El stream() debe devolver cualquier objeto asíncrito siempre que produce uint8Array (o búfer), por lo que nodo. Las secuencias legibles y las transmisiones de Whatwg funcionan 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' ) Puede cancelar solicitudes con AbortController . Una implementación sugerida es abort-controller .
Se podría lograr un ejemplo de tiempo de tiempo para programar una solicitud después de 150 ms como el siguiente:
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 ) ;
}Consulte los casos de prueba para obtener más ejemplos.
url una cadena que representa la URL para obteneroptions Opciones para la solicitud HTTP (S)Promise<Response>Realice una búsqueda HTTP (s).
url debe ser una URL absoluta, como https://example.com/ . Una URL relativa de ruta ( /file/under/root ) o URL-Relativa de Protocolo ( //can-be-http-or-https.com/ ) dará como resultado una Promise rechazada.
Los valores predeterminados se muestran después de cada clave de opción.
{
// 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 no se establecen valores, los siguientes encabezados de solicitud se enviarán automáticamente:
| Encabezamiento | Valor |
|---|---|
Accept-Encoding | gzip, deflate, br (cuando options.compress === true ) |
Accept | */* |
Content-Length | (calculado automáticamente, si es posible) |
Host | (Información de host y puerto del URI objetivo) |
Transfer-Encoding | chunked (cuando req.body es una transmisión) |
User-Agent | node-fetch |
Nota: Cuando body es una Stream , Content-Length no se establece automáticamente.
La opción agent le permite especificar opciones relacionadas con las redes que están fuera del alcance de la búsqueda, incluyendo y no se limitan a lo siguiente:
Consulte http.Agent para obtener más información.
Si no se especifica ningún agente, se utiliza el agente predeterminado proporcionado por Node.js. Tenga en cuenta que esto cambió en Node.js 19 para tener un verdadero keepalive de forma predeterminada. Si desea habilitar keepalive en una versión anterior de Node.js, puede anular el agente según la siguiente muestra de código.
Además, la opción agent acepta una función que devuelve http (s) .Agent
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 ;
}
}
} ; Stream en Node.js tiene un tamaño de búfer interno más pequeño (16kb, también conocido como highWaterMark ) de los navegadores del lado del cliente (> 1 MB, no consistente entre los navegadores). Debido a eso, cuando escribe una aplicación isomórfica y usa res.clone() , se colgará con una gran respuesta en el nodo.
La forma recomendada de solucionar este problema es resolver la respuesta clonada en paralelo:
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 por alguna razón no le gusta la solución anterior, ya que 3.x puede modificar la opción 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 ) ; Pasó a la opción insecureHTTPParser en http (s) .Request. Consulte http.request para obtener más información.
La opción redirect: 'manual' para Fetch Node es diferente del navegador y la especificación, lo que da como resultado una respuesta filtrada de Opque-Redirect. Node-Fetch le brinda la respuesta filtrada básica típica.
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 ) ;
}Una solicitud HTTP (s) que contiene información sobre URL, método, encabezados y el cuerpo. Esta clase implementa la interfaz del cuerpo.
Debido a la naturaleza de Node.js, las siguientes propiedades no se implementan en este momento:
typedestinationmodecredentialscacheintegritykeepaliveSe proporcionan las siguientes propiedades de extensión de fanges de nodo:
followcompresscounteragenthighWaterMarkConsulte las opciones para el significado exacto de estas extensiones.
(compatible con especificaciones)
input una cadena que represente una URL u otra Request (que se clonará)options Opciones para la solicitud HTTP (S) Construye un nuevo objeto Request . El constructor es idéntico al del navegador.
En la mayoría de los casos, fetch(url, options) es más simple que crear un objeto Request .
Una respuesta HTTP (S). Esta clase implementa la interfaz del cuerpo.
Las siguientes propiedades no se implementan en Node-Fetch en este momento:
trailer(compatible con especificaciones)
body una String o transmisión Readableoptions un diccionario de opciones ResponseInit Construye un nuevo objeto Response . El constructor es idéntico al del navegador.
Debido a que Node.js no implementa trabajadores de servicio (para los cuales se diseñó esta clase), uno rara vez tiene que construir una Response directamente.
(compatible con especificaciones)
Propiedad de conveniencia que representa si la solicitud terminaba normalmente. Se evaluará como cierto si el estado de respuesta fue mayor o igual a 200 pero menor que 300.
(compatible con especificaciones)
Propiedad de conveniencia que representa si la solicitud ha sido redirigida al menos una vez. Se evaluará como verdadero si el contador de redirección interna es mayor que 0.
(desviación de la especificación)
Propiedad de conveniencia que representa el tipo de respuesta. Node-Fetch solo admite 'default' y 'error' y no utiliza las respuestas filtradas.
Esta clase permite manipular e iterarse sobre un conjunto de encabezados HTTP. Se implementan todos los métodos especificados en el estándar de búsqueda.
(compatible con especificaciones)
init para llenar el objeto Headers Construya un nuevo objeto Headers . init puede ser null , un objeto Headers , un objeto de mapa de valor clave o cualquier objeto Iterable.
// 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 es una interfaz abstracta con métodos aplicables a las clases Request y Response .
(desviación de la especificación)
Readable node.js Los datos están encapsulados en el objeto Body . Tenga en cuenta que si bien el estándar de búsqueda requiere que la propiedad sea siempre un Whatwg ReadableStream , en Node-Fetch es una secuencia Readable de nodo.js.
(compatible con especificaciones)
BooleanUna propiedad booleana para si este cuerpo se ha consumido. Según las especificaciones, un cuerpo consumido no se puede volver a usar.
fetch viene con métodos para analizar las cargas útiles multipart/form-data , así como los cuerpos x-www-form-urlencoded usando .formData() Esto proviene de la idea de que el trabajador de servicio puede interceptar dichos mensajes antes de que se envíe al servidor para alterarlos. Esto es útil para cualquiera que construya un servidor para que pueda usarlo para analizar y consumir cargas útiles.
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 ( )
} )(Extensión de fetch de nodo)
Un error operativo en el proceso de recuperación. Consulte el manejo de errores.md para obtener más información.
(Extensión de fetch de nodo)
Un error lanzado cuando la solicitud se aborta en respuesta al evento abort de un AbortSignal . Tiene una propiedad de name de AbortError . Consulte el manejo de errores.md para obtener más información.
Dado que los tipos 3.x se incluyen con node-fetch , por lo que no necesita instalar ningún paquete adicional.
Para versiones anteriores, utilice las definiciones de tipo de definitivamente Typed:
npm install --save-dev @types/[email protected]Gracias a GitHub/Fetch por proporcionar una referencia de implementación sólida.
![]() | ![]() | ![]() | ![]() | ![]() |
|---|---|---|---|---|
| David Frank | Jimmy Wärting | Antoni Kepinski | Richie Bendall | Gregor Martynus |
MIT