Node.jsでFetch APIを使ってのHTTPリクエスト

このガイドでは、Node.jsでFetch APIを使用ってHTTPリクエストを行う方法を説明します
2 分読
Fetch API in NodeJS

Fetch APIは、Node.jsでHTTPリクエストを実行してローカルリソースを取得するための、新しく公式にサポートされた方法です。つまり、プロジェクトに外部HTTPクライアントの依存関係が不要となりました。必要なのは、このガイドを読んでNode Fetch APIの使い方を覚えることだけです。

ここに表示されます:

  • Fetch APIの概要
  • Node Fetch APIを使ってみる
  • Node.jsでFetch APIを使って HTTPリクエストを行う
  • その他のオプションと機能

さっそく始めましょう!

Fetch APIの概要

Fetch API は、ローカルまたはネットワーク経由でリソースをフェッチするための JavaScriptインターフェースです。詳細には、非同期HTTPリクエストの実行を容易にするグローバルfetch()関数を提供します。同じメソッドを使ってローカルファイルを取得することもできます。JavaScript Fetch APIは、従来のXMLHttpRequest APIの代わりに使える柔軟な手段です。

fetch()メソッドはリクエストおよびレスポンスオブジェクトに基づいています。必須の引数は1つだけで、フェッチしたいリソースのローカルパスまたはURLです。オプションとしてはCORS、HTTP ヘッダー、キャッシュ設定などが使えます。非同期メソッドであるため、fetch()はサーバーが生成した応答を解決するプロミスを返します。これはレスポンスオブジェクトで表され、コンテンツ本文にアクセスして解析するためのいくつかのメソッドを公開します。

基本的なFetch API呼び出しの例を示します:

  fetch(u0022https://httpbin.io/ipu0022, {nn  // optional configs...nn}).then((response) =u003e {nn  // print the JSON response bodynn  console.log(response.json()) // {  u0022originu0022: u0022u003cYOUR_IP_ADDRESSu003eu0022 }nn})nnOr if you prefer the equivalent async/await syntax, you can write:nnconst response = await fetch(u0022https://httpbin.io/ipu0022, {nn  // optional configs...nn})nn// print the JSON response bodynnconsole.log(await response.json()) // { u0022originu0022: u0022u003cYOUR_IP_ADDRESSu003eu0022 }n

Node Fetch APIを使ってみる

Fetch APIは主要なブラウザで何年もサポートされてきました。しかし、標準のNode.jsライブラリに組み込まれたのは2022年4月にリリースされたバージョン18.0.0以降です。具体的には、Node Fetch APIはUndiciの実装に基づいています。

Node.js 18以前は、fetch()を実験的な機能として有効にしたり、別の一般的なFetch APIの実装であるnode-fetch npmライブラリを利用することでfetch()を使うことができました。今では、fetch()は公式のNode.js標準ライブラリに組み込まれたため、インポートなしに直接コードで使えます。以下の構文でfetch()メソッドを呼び出すだけで済みます。

fetch(url, options)

URLは必須で、以下を含めることができます:

  • ローカルリソースへのパス(例: movies.json) 
  • リモートエンドポイントまたはリモートリソースのURL(例:https://httpbin.io/ipまたはhttps://example.com/movies.json)

options は、以下のオプションフィールドを受け入れるオプションオブジェクトです:

  • method: GET、POST、PUT、PATCH、DELETEなどのリクエストのHTTPメソッドデフォルトはGETです。 
  • headers: リクエストに追加するHTTPヘッダーを含むヘッダーまたはオブジェクトリテラルデフォルトでは、ヘッダーは設定されていません。
  • body: リクエストの本文として使うデータを格納したオブジェクトGETおよびHEADリクエストに本文を含めることはできません。
  • mode: リクエストに使うモード(例: cors、no-cors、same-origin、navigate、websocket)デフォルトではcorsに設定されています。
  • credentials: ブラウザが認証情報を送信するかどうかを指定します。omit、same-origin、includeのいずれかの文字列であることが必要です。
  • redirect: HTTPリダイレクトレスポンスの処理方法を決定します。follow、error、manualが使えます。デフォルトではfollowに設定されています。
  • referrer: リクエストのリファラーを格納した文字列デフォルトでは空の文字列です。
  • referrerPolicy: リクエストに使うリファラーポリシーを指定します。
  • signal: AbortControllerインターフェース経由でリクエストを中止できるようにする AbortSignalオブジェクトインスタンス
  • priority: 同じタイプの他のリクエストに対する現在のFetchリクエストの優先度を指定する文字列high、low、autoが使えます。デフォルトはautoです。

詳細は、公式ドキュメントのfetch()パラメータセクションを参照してください。

これはオプションオブジェクトを使ったNode.js Fetchリクエストの例です:

  const response = await fetch(u0022https://your-domain.com/api/v1/usersu0022, {nn  method: u0022POSTu0022,nn  credentials: u0022includeu0022,nn  headers: {nn    u0022Content-Typeu0022: u0022application/jsonu0022,nn  },nn  body: JSON.stringify({nn    username: u0022jane-doeu0022,nn    email: [email protected]    role: u0022superuseru0022,nn    age: 23,nn    birthplace: u0022New Yorku0022,nn  }),nn})n

本文データはContent-Typeヘッダーと一致する必要があります。

Node.jsでFetch APIを使って HTTPリクエストを行う

それでは、最も一般的なHTTPメソッドの実際のリクエスト例でNode Fetch APIが実際に動作するのを見てみましょう。

GET

Fetch APIでGETリクエストを実行する方法は以下の通りです。

  const response = await fetch(u0022https://your-domain.com/your-endpointu0022)const response = await fetch(u0022https://your-domain.com/your-endpointu0022)

ご覧のとおり、必要なコードは1行だけです。これは、fetch()がデフォルトでGETリクエストを実行するためです。

次に、以下のいずれかの方法でレスポンスコンテンツにアクセスできます。

  • response.text(): レスポンス本文をテキストとして解決するPromiseを返します。
  • response.json(): JSONレスポンスから解析されたオブジェクトで解決するPromiseを返します。
  • response.blob(): レスポンス本文をBlobオブジェクトとして解決するPromiseを返します。
  • response.ArrayBuffer(): レスポンス本文をArrayBufferインスタンスとして解決するPromiseを返します。
  • response.FormData(): レスポンス本文をFormDataオブジェクトとして解決するPromiseを返します。

したがって、サンプルコード全体は以下のようになります。

  const response = await fetch(u0022https://httpbin.io/ipu0022)nnconst jsonResponseContent = await response.json() // { u0022originu0022: u0022u003cYOUR_IP_ADDRESSu003eu0022 }nnconst origin = jsonResponseContent.origin // u003cYOUR_IP_ADDRESSu003e

サーバーから返されたレスポンスがJSON形式でない場合、response.json()命令は構文エラーで失敗します。

POST

Node Fetch API呼び出しによるPOSTリクエスト実行には数行しか要りません:

  const formData = new FormData()nnformData.append(u0022usernameu0022, u0022serena-smithu0022)nnformData.append(u0022emailu0022, [email protected])nnconst response = await fetch(u0022https://example.com/api/v1/usersu0022, {nn  method: u0022POSTu0022,nn  body: formData,nn})

fetch()でPOSTリクエストを送信する鍵は、サーバーに送信するデータをbodyオプションで指定することです。形式はJSON、FormData、textなどから選択できます。FormDataオブジェクトを送信する場合、Content-Typeヘッダーを指定する必要はありません。それ以外の場合は必須です。 

PUT

Fetch APIによるPUTリクエストの実行は、 POSTの実行と似ています: 

  const response = await fetch(u0022https://example.com/api/v1/usersu0022, {nn  method: u0022PUTu0022,nn  credentials: u0022includeu0022,nn  headers: {nn    u0022Content-Typeu0022: u0022application/jsonu0022,nn  },nn  body: JSON.stringify({nn    username: u0022john-doeu0022,nn    email: [email protected]    role: u0022regular-useru0022,nn    age: 47,nn    birthplace: u0022Chicagou0022,nn  }),nn})n

唯一の違いは、メソッド設定としてPUTを指定することです。同様に、PATCHを設定するとPATCHリクエストを送信できます。

DELETE

以下はfetch()を使ったHTTP DELETEリクエストの例です:

  const response = await fetch(u0022https://example.com/api/v1/users/45u0022, {nn  method: u0022DELETEu0022,nn})

ここでも重要なのは正しいHTTPメソッドを設定することです。あとはFetch APIの実装が面倒を見てくれます。

その他のオプションと機能

ここまでで、一般的なシナリオでのfetch()の使い方を説明しました。ここからはNode Fetch APIの詳細オプションを見ていきましょう。

ヘッダーの設定

fetch()では、オプションオブジェクトのheadersフィールドを使って、リクエストの HTTPヘッダーをカスタマイズできます。特にヘッダーはHeadersオブジェクトまたは特定の文字列値を持つオブジェクトリテラルを受け入れます。

fetch()リクエストにContent-TypeヘッダーとUser-Agentヘッダーを設定してみましょう。以下のようにHeadersオブジェクトを使用することができます:

  const customHeaders = new Headers()nncustomHeaders.append(u0022Content-Typeu0022, u0022application/jsonu0022)nncustomHeaders.append(u0022User-Agentu0022, u0022Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36u0022)nnconst response = fetch(u0022https://your-domain.com/your-endpointu0022, {nn  headers: customHeaders,nn  // other options...nn})

もしくは、オブジェクトリテラルを使って同じように設定できます:

  const response = fetch(u0022https://your-domain.com/your-endpointu0022, {nn  headers: {nn    u0022Content-Typeu0022: u0022application/jsonu0022,nn    u0022User-Agentu0022: u0022Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36u0022,nn  },nn  // other options...nn})

この構文はよりコンパクトで読みやすくなっています。

ヘッダーの読み取り

応答でサーバーが設定したHTTPヘッダーを読み取る場合、次のようにアクセスできます。

  const response = await fetch(u0022https://your-domain.com/your-endpointu0022, {nn  // optional configs...nn})nn// accessing the u0022Content-Typeu0022 response headernnconst responseHeaders = response.headersnnconst responseContentType = response.headers.get(u0022Content-Typeu0022)

response.headersフィールドはHeadersオブジェクトを返します。このオブジェクトから get()メソッドを使って特定のヘッダーにアクセスできます。

Node Fetch APIのエラー処理

Node.js Fetch API呼び出しが失敗する理由は以下の2つだけです。

  • AbortError例外: リクエストがAbortControllerによって意図的に中止されたとき。
  • TypeError例外: これは無効なヘッダー名、無効なURL、一般的なネットワークエラーなど、いくつかの理由で発生します。ドキュメントでその他の原因を参照してください。

理解しておくべき重要なことは、Fetch APIにとって4xxおよび5xxのレスポンスはすべてリクエスト成功と見なされるということです。すなわち、サーバーが生成したエラー応答はJavaScriptエラーをトリガーしません。この挙動の理由は、fetch()がリクエストを行い、サーバーが応答を返したということです。概念的には、ネットワークの観点からはエラーとは見なされないのです。結局、リクエストは正常に終了したということです。

つまり、サーバーから返されたデータを処理する前に、応答が成功したかを確認する必要があるということです。そのためには、以下のエラー処理ロジックを実装できます。

  try {nn  const response = await fetch(u0022https://your-domain.com/your-endpointu0022, {nn    // optional configs...nn  })nn  if (response.ok) {nn    // use the data returned by the server...nn    // e.g., nn    // await response.json()nn  } else {nn    // handle 4xx and 5xx errors...nn  }nn} catch (error) {nn  // handle network or abort errors...nn}n

Responseのokプロパティがtrueになるのは、リクエストが成功した場合のみであることに注目してください。

Fetchリクエストの中止

Fetch API は、AbortController APIを介して開始済みリクエストの中止をサポートしています。 

進行中のfetch()リクエストを停止するには、まず以下のようにシグナルオブジェクトを生成する必要があります:

  const controller = new AbortController()nnconst signal = controller.signalnnThen, specify it in the options object of your request:nnconst response = await fetch(u0022https://your-domain.com/your-endpointu0022, {nn  signal: signal,nn  // other configs...nn})

これで、以下の命令を呼び出せば、リクエストはAbortErrorによって中断します:

  controller.abort()controller.abort()

サーバーは既にリクエストを受信している可能性があることに注意してください。その場合、サーバーはリクエストの実行を継続しますが、その応答はNode.jsによって無視されます。

おめでとうございます!これであなたはNode.js Fetch APIマスターです!

まとめ

この記事ではFetch APIの概要とNode.jsでの使い方を説明しました。fetch()の基本から始めて、その高度なオプションと機能を掘り下げました。このような強力なHTTPクライアントを使用すると、オンラインデータを容易に取得できます。たとえば、弊社のSERP APIエンドポイントを呼び出してSERPデータのスクレイピングを開始できます。

Bright Dataは、世界中で20,000を超える企業にサービスを提供する世界最大のウェブデータプラットフォームです。弊社のデータ専門家にご相談ください。お客様とウェブスクレイピングのニーズにマッチする製品をご紹介いたします。