一個輕巧的模塊,將fetch api帶到node.js。

您可能正在尋找V2文檔
與其在node.js中實現XMLHttpRequest以運行特定於瀏覽器的獲取polyfill,為什麼不直接從本機http轉到fetch API呢?因此,node for window.fetch的node-fetch ,最小代碼。
請參閱Jason Miller的同構不取,或Leonardo Quixada的同構用法(用於服務器端的Exports node-fetch , whatwg-fetch for client端)。
window.fetch api保持一致。res.text()和res.json() )自動轉換為UTF-8。window.fetch缺失功能。當前穩定版本( 3.x )至少需要Node.js 12.20.0。
npm install node-fetch import fetch from 'node-fetch' ; V3的node-fetch是一個僅ESM的模塊 - 您無法使用require()導入它。
如果您不能切換到ESM,請使用與CommonJ兼容的V2。關鍵的錯誤修復將繼續為V2發布。
npm install node-fetch@2另外,您可以使用async import()函數從commonjs加載node-fetch異步:
// mod.cjs
const fetch = ( ... args ) => import ( 'node-fetch' ) . then ( ( { default : fetch } ) => fetch ( ... args ) ) ;要使用fetch()而不導入它,您可以在節點中修補global對象:
// 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'
// ... 使用舊版本的node-fetch?查看以下文件:
注意:下面的文檔是最新的3.x版本,如果您使用的是舊版本,請檢查如何升級。
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 ) ;從v10.0.0開始,在node.js中的全局對像上可用URLSearchParams 。有關更多用法方法,請參見官方文檔。
注意:當URLSearchParams的實例提供時, Content-Type標頭僅自動設置為x-www-form-urlencoded :
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 ) ;注意:3xx-5xx響應不是例外,應在then()中處理,請參見下一節。
將獲取函數包裝到try/catch塊中將捕獲所有異常,例如源自節點核心庫(例如網絡錯誤)的錯誤,以及fetcherror實例的操作錯誤。有關更多詳細信息,請參見錯誤處理文檔。
import fetch from 'node-fetch' ;
try {
await fetch ( 'https://domain.invalid/' ) ;
} catch ( error ) {
console . log ( error ) ;
}創建輔助功能是通常的,以檢查響應是否包含客戶端(4xx)或服務器(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 } ` ) ;
}默認情況下不會存儲cookie。但是,可以通過操縱請求和響應標題來提取餅乾並通過。有關詳細信息,請參見提取物set-cookie標頭。
“ node.js方法”是在可能的情況下使用流。您可以將res.body帶到另一個流。此示例使用Stream.Pipeline附加流誤差處理程序並等待下載完成。
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' ) ) ;在Node.js 14中,您也可以使用異步迭代器讀取body ;但是,請小心捕獲錯誤 - 響應越長,遇到錯誤的可能性就越大。
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 ) ;
}在Node.js 12中,您還可以使用異步迭代器讀取body ;但是,在Node.js 14之前,具有流的異步迭代器才成熟,因此您需要做一些額外的工作以確保直接從流中處理錯誤,並等待IT響應才能完全關閉。
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' ) ) ;與瀏覽器不同,您可以使用Headers.raw()手動訪問RAW Set-Cookie標頭。這是一個僅node-fetch API。
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帶有符合規格的FormData實現,用於發布多個型號/form-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 )如果您出於某種原因需要發布來自任何任意位置的流,那麼您可以附加斑點或類似a的文件。
最低要求是它具有:
Symbol.toStringTag或Blob或File屬性stream()方法或arrayBuffer()方法。只要它產生uint8array(或buffer),因此stream()必須返回任何異步峰值對象。
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' )您可以使用AbortController取消請求。建議的實現是abort-controller 。
可以在150ms之後提出請求的一個示例如下:
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 ) ;
}有關更多示例,請參見測試用例。
url代表url的字符串以獲取optionsPromise<Response>執行HTTP(S)提取。
url應該是絕對的URL,例如https://example.com/ 。路徑相關的URL( /file/under/root )或協議相關的URL( //can-be-http-or-https.com/ )將導致拒絕的Promise 。
在每個選項鍵之後顯示默認值。
{
// 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`.
} 如果未設置值,則將自動發送以下請求標頭:
| 標題 | 價值 |
|---|---|
Accept-Encoding | gzip, deflate, br (當options.compress === true時) |
Accept | */* |
Content-Length | (如果可能的話,會自動計算) |
Host | (來自目標URI的主機和端口信息) |
Transfer-Encoding | chunked (當req.body是流時) |
User-Agent | node-fetch |
注意:當body是Stream時,未自動設置Content-Length 。
agent選項允許您指定超出獲取範圍的網絡相關選項,包括但不限於以下內容:
有關更多信息,請參見http.Agent 。
如果未指定代理,則使用node.js提供的默認代理。請注意,這在Node.js 19中更改為默認情況下具有keepalive true。如果您希望在較早版本的node.js中啟用keepalive ,則可以根據以下代碼示例覆蓋代理。
此外, agent選項接受一個返回http (s)的函數.Agent給定當前URL,這在跨HTTP和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 ;
}
}
} ; Node.js上的流具有較小的內部緩衝區大小(16KB,又名highWaterMark ),可從客戶端瀏覽器(> 1MB,在瀏覽器中不一致)。因此,當您編寫同構應用程序並使用res.clone()時,它將在節點中懸掛較大的響應。
解決此問題的推薦方法是並行解決克隆的響應:
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 ] ) ;如果由於某種原因您不喜歡上面的解決方案,則因為3.x ,您可以修改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 ) ; 通過HTTP(s)上的insecureHTTPParser選項傳遞。有關更多信息,請參見http.request 。
Node-fetch的redirect: 'manual'選項不同於瀏覽器和規範,這導致了不透明的重新定義過濾響應。 Node-fetch為您提供了典型的基本過濾響應。
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 ) ;
}HTTP請求,其中包含有關URL,方法,標頭和身體的信息。該課程實現身體接口。
由於node.js的性質,目前尚未實現以下屬性:
typedestinationmodecredentialscacheintegritykeepalive提供了以下節點 - 提取擴展屬性:
followcompresscounteragenthighWaterMark有關這些擴展的確切含義,請參見選項。
(符合規格)
input代表URL或其他Request字符串(將被克隆)options構建一個新的Request對象。構造函數與瀏覽器中的構造函數相同。
在大多數情況下,直接fetch(url, options)比創建Request對象更簡單。
HTTP響應。該課程實現身體接口。
目前尚未在Node-fetch中實現以下屬性:
trailer(符合規格)
body String或Readable流options ResponseInit選項詞典構建一個新的Response對象。構造函數與瀏覽器中的構造函數相同。
由於Node.js沒有實施服務工作者(為此類型的設計),因此很少需要直接構建Response 。
(符合規格)
便利屬性表示請求是否正常結束。如果響應狀態大於或等於200但小於300,則將評估為true。
(符合規格)
便利屬性表示請求至少重定向一次。如果內部重定向計數器大於0,將評估為true。
(偏離規格)
便利屬性代表響應類型。 Node-fetch僅支持'default'和'error' ,並且不使用過濾的響應。
該課程允許在一組HTTP標頭上操縱和迭代。提取標準中指定的所有方法均已實現。
(符合規格)
init可選參數以預填充Headers對象構建一個新的Headers對象。 init可以是null , Headers對象,鍵值映射對像或任何可迭代的對象。
// 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是一種抽象接口,具有適用於Request和Response類的方法。
(偏離規格)
Readable流數據封裝在Body對像中。請注意,雖然獲取標準要求屬性始終為Whatwg ReadableStream ,但在節點fetch中,它是一個node.js Readable流。
(符合規格)
Boolean如果該屍體被消耗掉,則是布爾屬性的。根據規格,無法再次使用消耗的身體。
fetch帶來了使用.formData()的x-www-form-urlencoded Body的方法來解析multipart/form-data有效負載,這是從.formdata()的主體,這來自於這樣的想法,即服務工作者可以在發送到服務器之前攔截該消息以更改它們。這對於任何構建服務器的人都很有用,因此您可以使用它來解析和消費有效載荷。
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 ( )
} )(node-fetch擴展)
在獲取過程中的操作錯誤。有關更多信息,請參見錯誤處理。 md。
(node-fetch擴展)
當請求響應AbortSignal的abort事件而流產時,錯誤的錯誤。它具有AbortError的name屬性。有關更多信息,請參見錯誤處理。 md。
由於3.x類型與node-fetch捆綁在一起,因此您無需安裝任何其他軟件包。
對於較舊的版本,請使用esealy typed的類型定義:
npm install --save-dev @types/[email protected]感謝GitHub/Fetch提供了可靠的實現參考。
![]() | ![]() | ![]() | ![]() | ![]() |
|---|---|---|---|---|
| 大衛·弗蘭克(David Frank) | 吉米·瓦特 | Antoni Kepinski | 里奇·本德爾(Richie Bendall) | 格雷戈爾·馬丁努斯(Gregor Martynus) |
麻省理工學院