Fetch APIをNode.jsにもたらす軽量モジュール

V2ドキュメントを探しているかもしれません
node.jsにXMLHttpRequestを実装してブラウザ固有のフェッチPolyfillを実行する代わりに、ネイティブhttpからAPIを直接fetchために移動してみませんか?したがって、node.jsランタイムのwindow.fetch互換APIの最小コード、 node-fetch 、 window.fetch互換性のあるAPI。
Jason MillerのIsomorphic-UnfetchまたはLeonardo Quixadaの同型使用については、クライアント側のwhatwg-fetchのエクスポートnode-fetch )を参照してください。
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に切り替えられない場合は、CommonJSと互換性のあるV2を使用してください。重要なバグ修正は、V2用に引き続き公開されます。
npm install node-fetch@2または、CommonJSからASYNC import()関数を使用して、 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'
// ... ノードフェッチの古いバージョンを使用していますか?次のファイルをご覧ください。
注:以下のドキュメントは、 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 ) ;URLSearchParams 、v10.0.0の時点でnode.jsのグローバルオブジェクトで利用できます。より多くの使用方法については、公式ドキュメントを参照してください。
注: Content-Typeヘッダーは、 URLSearchParamsのインスタンスが与えられた場合にのみ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ブロックにラッピングすると、ネットワークエラーなどのノードコアライブラリに由来するエラーや、フェッチェロールのインスタンスである運用エラーなど、すべての例外がキャッチされます。詳細については、エラー処理ドキュメントを参照してください。
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はデフォルトで保存されません。ただし、クッキーは、リクエストと応答のヘッダーを操作することで抽出および渡すことができます。詳細については、Extract Set-Cookieヘッダーを参照してください。
「node.js way」は、可能な場合はストリームを使用することです。 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では、Async Iteratorsを使用して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では、Async Iteratorsを使用してbodyを読み取ることもできます。ただし、ストリームを備えた非同期イテレーターはnode.js 14まで成熟しなかったため、ストリームから直接エラーを処理し、その応答を待って完全に閉じるために追加の作業を行う必要があります。
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()を使用して、生の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には、MultiPart/Form-Dataペイロードを投稿するためのスペックに準拠したFormData実装が付属しています
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 )何らかの理由で、任意の場所から来るストリームを投稿する必要がある場合は、BlobまたはFile look-a-likeアイテムを追加することができます。
最小要件は、それが持っていることです:
Symbol.toStringTag getterまたはBlobまたはFileいずれかのプロパティstream()メソッドまたはarrayBuffer()メソッドのいずれか。 stream() UINT8ARRAY(またはバッファー)を生成する限り、非同期反復オブジェクトを返す必要があるため、Node.Readable StreamsおよびWhatWGストリームは正常に機能します。
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を表す文字列optionsオプションPromise<Response>http(s)fetchを実行します。
url 、 https://example.com/などの絶対的なURLである必要があります。パス関連の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真実であることに注意してください。 node.jsの以前のバージョンでkeepaliveを有効にする場合は、次のコードサンプルに従ってエージェントをオーバーライドできます。
さらに、 agentオプションは、現在のURLが与えられたhttp (s) .Agentインスタンスを返す関数を受け入れます。これは、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のストリームは、クライアント側のブラウザ(> 1MB、ブラウザ間で一貫性がない)からの内部バッファサイズ(16kb、 highWaterMark )が小さくなります。そのため、同型アプリを作成し、 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).requestのinsecureHTTPParserオプションに渡されました。詳細については、 http.requestを参照してください。
redirect: 'manual'オプションは、ブラウザと仕様とは異なり、不透明なリダイレクトフィルタリングされた応答をもたらします。ノードフェッチは、代わりに典型的な基本フィルタリングされた応答を提供します。
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 ) ;
}URL、メソッド、ヘッダー、および本体に関する情報を含むHTTP要求。このクラスは、ボディインターフェイスを実装します。
Node.jsの性質により、現時点では次のプロパティが実装されていません。
typedestinationmodecredentialscacheintegritykeepalive次のノードフェッチ拡張プロパティが提供されます。
followcompresscounteragenthighWaterMarkこれらの拡張機能の正確な意味のオプションを参照してください。
(スペックに準拠)
Request input (クローン化されます)optionsオプション新しいRequestオブジェクトを構築します。コンストラクターは、ブラウザのコンストラクターと同じです。
ほとんどの場合、直接fetch(url, options) Requestオブジェクトを作成するよりも簡単です。
HTTP応答。このクラスは、ボディインターフェイスを実装します。
現時点では、次のプロパティはノードフェッチに実装されていません。
trailer(スペックに準拠)
body StringまたはReadableストリームoptionsのResponseInit辞書新しいResponseオブジェクトを構築します。コンストラクターは、ブラウザのコンストラクターと同じです。
node.jsはサービスワーカー(このクラスが設計された)を実装していないため、 Responseを直接構築する必要はほとんどありません。
(スペックに準拠)
リクエストが正常に終了した場合に表す利益のプロパティ。応答ステータスが200以上であるが300よりも小さい場合、trueに評価します。
(スペックに準拠)
リクエストが少なくとも一度はリダイレクトされた場合に表現するコンビニエンスプロパティ。内部リダイレクトカウンターが0より大きい場合、trueに評価します。
(仕様からの逸脱)
応答のタイプを表す便利なプロパティ。ノードフェッチは、 'default'と'error'のみをサポートし、フィルタリングされた応答を使用しません。
このクラスでは、HTTPヘッダーのセットを操作して反復することができます。フェッチ標準で指定されたすべてのメソッドが実装されています。
(スペックに準拠)
Headersオブジェクトを事前に充填するためのオプションの引数init新しい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であることを要求しますが、ノードフェッチではnode.js Readableストリームです。
(スペックに準拠)
Booleanこのボディが消費されている場合のブール特性。仕様に従って、消費されたボディを再び使用することはできません。
fetchにはmultipart/form-dataペイロードを解析する方法が付属していますx-www-form-urlencodedボディは.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 ( )
} )(ノードフェッチ拡張機能)
フェッチングプロセスの運用エラー。詳細については、Error Handling.mdを参照してください。
(ノードフェッチ拡張機能)
AbortSignalのabortイベントに応じてリクエストが中止されたときにスローされるエラー。 AbortErrorのnameのプロパティがあります。詳細については、Error Handling.mdを参照してください。
3.xタイプにはnode-fetchがバンドルされているため、追加のパッケージをインストールする必要はありません。
古いバージョンの場合は、EnculationTeptedのタイプ定義を使用してください。
npm install --save-dev @types/[email protected]堅実な実装リファレンスを提供してくれたGitHub/Fetchに感謝します。
![]() | ![]() | ![]() | ![]() | ![]() |
|---|---|---|---|---|
| デビッド・フランク | ジミー・ウェアティング | アントーニ・ケピンスキー | リッチー・ベンドール | グレゴール・マーティヌス |
mit