読み込み中...

JavaScriptのFetch APIを使ったHTTP通信の基本10選

JavaScriptのFetch APIを使ったHTTP通信の基本的な使い方 JS
この記事は約26分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

●Fetch APIとは?

Fetch APIは、JavaScriptを使ってサーバーとの通信を行うための強力なツールです。

従来のXMLHttpRequestよりも使いやすく、モダンなウェブ開発に欠かせない機能となっています。

○Fetch APIの特徴

Fetch APIの大きな特徴は、Promiseベースの非同期処理を採用していることです。

Promiseを使うことで、複雑な非同期処理を簡潔に記述できるようになりました。

また、Fetch APIはレスポンスのステータスコードやヘッダー情報へのアクセスが容易で、柔軟なデータ処理が可能です。

たとえば、Fetch APIを使ってJSONデータを取得する場合、レスポンスのステータスコードをチェックし、適切なエラーハンドリングを行うことができます。

これにより、サーバーとのやり取りがスムーズに行えるようになります。

○Fetch APIとXMLHttpRequestの違い

従来のXMLHttpRequestと比べると、Fetch APIはよりシンプルで直感的な記述が可能です。

XMLHttpRequestでは、リクエストの送信やレスポンスの処理にコールバック関数を使用する必要がありましたが、Fetch APIではPromiseを使ってスッキリと記述できます。

また、Fetch APIはリクエストやレスポンスのヘッダー情報をオブジェクトとして扱えるため、柔軟なカスタマイズが可能です。

ヘッダーの設定やレスポンスの解析が簡単にできるようになっています。

○Fetch APIのブラウザ対応状況

Fetch APIは、モダンブラウザのほとんどでサポートされています。

Chrome、Firefox、Safari、Edgeといった主要なブラウザで問題なく動作します。

ただし、古いブラウザ、特にInternet Explorer 11以前のバージョンでは対応していないことがあるので注意が必要です。

古いブラウザをサポートする必要がある場合は、ポリフィルを使ってFetch APIの機能を実現することができます。

ポリフィルを導入することで、幅広いブラウザ環境でFetch APIを使用できるようになります。

●Fetch APIの基本的な使い方

さて、Fetch APIの特徴や利点について理解が深まったところで、実際の使い方を見ていきましょう。

Fetch APIを使ったHTTP通信は、非常にシンプルで直感的です。

基本的な流れとしては、fetch()メソッドを使ってリクエストを送信し、Promiseを使ってレスポンスを処理するという流れになります。

では早速、具体的なコードを見ながら、Fetch APIの使い方を学んでいきましょう。

○サンプルコード1:GETリクエストの例

Fetch APIを使ってGETリクエストを送信するには、fetch()メソッドにURLを指定するだけです。

たとえば、あるAPIからデータを取得する場合は、次のようなコードを書くことができます。

fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('エラーが発生しました:', error);
  });

このコードでは、fetch()メソッドにAPIのURLを指定しています。

そして、Promiseを使ってレスポンスを処理しています。

response.json()でレスポンスのJSONデータを解析し、then()でデータを受け取ります。

エラーが発生した場合は、catch()で処理します。

実行結果

{
  "id": 1,
  "name": "John Doe",
  "email": "john@example.com"
}

このように、Fetch APIを使えば、非常にシンプルにGETリクエストを送信し、データを取得することができます。

○サンプルコード2:POSTリクエストの例

次に、Fetch APIを使ってPOSTリクエストを送信する方法を見ていきましょう。

POSTリクエストを送信する場合は、fetch()メソッドの第2引数にオプションオブジェクトを指定します。

const data = {
  title: 'New Post',
  body: 'This is the body of the new post.',
  userId: 1
};

fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(data => {
    console.log('新しい投稿が作成されました:', data);
  })
  .catch(error => {
    console.error('エラーが発生しました:', error);
  });

このコードでは、fetch()メソッドの第2引数に、methodプロパティを'POST'に設定したオプションオブジェクトを指定しています。

また、headersプロパティでリクエストヘッダーを設定し、bodyプロパティでリクエストボディに送信するデータを指定しています。

実行結果

新しい投稿が作成されました: {
  id: 101,
  title: 'New Post',
  body: 'This is the body of the new post.',
  userId: 1
}

このようにして、Fetch APIを使ってPOSTリクエストを送信し、サーバーにデータを送信することができます。

○サンプルコード3:カスタムヘッダーの設定

Fetch APIでは、リクエストヘッダーを自由に設定することができます。

headersプロパティを使って、任意のヘッダーを指定できます。

fetch('https://api.example.com/data', {
  headers: {
    'Authorization': 'Bearer your_access_token_here',
    'X-Custom-Header': 'Some value'
  }
})
  .then(response => response.json())
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('エラーが発生しました:', error);
  });

このコードでは、'Authorization'ヘッダーと'X-Custom-Header'という独自のヘッダーを設定しています。

このように、必要に応じてカスタムヘッダーを設定することができます。

○サンプルコード4:レスポンスデータの取得

Fetch APIを使ってリクエストを送信した後は、レスポンスを適切に処理する必要があります。

レスポンスの処理には、Promiseを使います。

fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error('ネットワークエラーが発生しました');
    }
    return response.json();
  })
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('エラーが発生しました:', error);
  });

このコードでは、fetch()メソッドでリクエストを送信した後、then()メソッドでレスポンスを処理しています。

response.okプロパティを使って、レスポンスのステータスコードが200番台かどうかをチェックしています。

ステータスコードが200番台以外の場合は、エラーをスローしています。

レスポンスが正常な場合は、response.json()メソッドを使ってレスポンスのJSONデータを解析し、次のthen()メソッドでデータを受け取ります。

エラーが発生した場合は、catch()メソッドでエラーを処理します。

実行結果

{
  "id": 1,
  "name": "John Doe",
  "email": "john@example.com"
}

このように、Fetch APIを使ったHTTP通信では、リクエストの送信からレスポンスの処理までを一連の流れで行うことができます。

Promiseを活用することで、非同期処理を簡潔に記述できるのが大きな利点ですね。

●Promiseとasync/awaitの活用

Fetch APIを使ったHTTP通信では、Promiseを活用することでより効率的で可読性の高いコードを書くことができます。

さらに、async/awaitを使えば、非同期処理をより直感的に記述できるようになります。

ここでは、Promiseとasync/awaitの基本的な使い方を押さえつつ、Fetch APIでの活用方法を具体的なサンプルコードとともに解説していきます。

非同期処理に苦手意識がある方も、これを機に理解を深めていきましょう。

○Promiseの基本

Promiseは、非同期処理の結果を表すオブジェクトです。

Promiseを使うことで、非同期処理の成功(resolve)と失敗(reject)を分けて処理することができます。

Promiseの基本的な構文は次のようになります。

new Promise((resolve, reject) => {
  // 非同期処理を行う
  // 処理が成功した場合は resolve(結果) を呼ぶ
  // 処理が失敗した場合は reject(エラー) を呼ぶ
})
  .then(result => {
    // 非同期処理が成功した場合の処理
  })
  .catch(error => {
    // 非同期処理が失敗した場合の処理
  });

Promiseを使うことで、非同期処理の結果を簡潔に処理できるようになります。

○サンプルコード5:Promiseを使ったFetch API

では、Promiseを使ってFetch APIでデータを取得する例を見てみましょう。

fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error('ネットワークエラーが発生しました');
    }
    return response.json();
  })
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('エラーが発生しました:', error);
  });

このコードでは、fetch()メソッドでデータを取得し、最初のthen()でレスポンスのステータスをチェックしています。

レスポンスが正常な場合は、response.json()でJSONデータを解析し、次のthen()で結果を処理しています。

エラーが発生した場合は、catch()でエラーを処理しています。

実行結果

{
  "id": 1,
  "name": "John Doe",
  "email": "john@example.com"
}

Promiseを使うことで、非同期処理の流れを明確に表現できます。

○async/awaitの利用

async/awaitは、Promiseをよりシンプルに記述するための構文です。

async/awaitを使うことで、非同期処理を同期的に記述できるようになります。

async/awaitの基本的な構文は次のようになります。

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('エラーが発生しました:', error);
  }
}

fetchData();

asyncキーワードを関数の前につけることで、その関数が非同期関数になります。

非同期関数内では、awaitキーワードを使って非同期処理の完了を待つことができます。

○サンプルコード6:async/awaitを使ったFetch API

それでは、async/awaitを使ってFetch APIでデータを取得する例を見てみましょう。

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    if (!response.ok) {
      throw new Error('ネットワークエラーが発生しました');
    }
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('エラーが発生しました:', error);
  }
}

fetchData();

このコードでは、asyncキーワードを使ってfetchData()関数を非同期関数として定義しています。awaitキーワードを使って、fetch()の結果を待ち、レスポンスのステータスをチェックしています。

レスポンスが正常な場合は、response.json()の結果を待ち、データを処理しています。

エラーが発生した場合は、catchブロックでエラーを処理しています。

実行結果

{
  "id": 1,
  "name": "John Doe",
  "email": "john@example.com"
}

async/awaitを使うことで、非同期処理を同期的に記述できるため、コードの可読性が向上します。

●よくあるエラーと対処法

Fetch APIを使ってサーバーとの通信を行う際、思わぬエラーに遭遇することがあります。

エラーに適切に対処できなければ、アプリケーションの動作に支障をきたすことになりかねません。

ここでは、Fetch APIを使う上でよく発生するエラーとその対処法について、具体的なサンプルコードを交えながら解説していきます。

エラーにうまく対処できるようになれば、安定したアプリケーションを開発できるようになるでしょう。

○CORSエラーとその対処法

CORSエラーは、Fetch APIを使う上で最もよく遭遇するエラーの1つです。

CORSとは、Cross-Origin Resource Sharing(クロスオリジンリソースシェアリング)の略で、異なるオリジン間でのリソースのやり取りを制御するセキュリティ機構のことを指します。

たとえば、https://example.comというオリジンからhttps://api.example.comというオリジンにリクエストを送る場合、CORSの設定が適切でないとエラーが発生します。

CORSエラーが発生した場合、次のようなエラーメッセージが表示されます。

Access to fetch at 'https://api.example.com/data' from origin 'https://example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

このエラーを解決するには、サーバー側でCORSの設定を行う必要があります。

サーバー側でAccess-Control-Allow-Originヘッダーを設定し、リクエスト元のオリジンを許可するようにします。

たとえば、Node.jsのExpressフレームワークを使っている場合は、次のようにCORSの設定を行うことができます。

const express = require('express');
const cors = require('cors');

const app = express();

app.use(cors());

// ルーティングの設定など

app.listen(3000, () => {
  console.log('サーバーが起動しました');
});

ここでは、corsミドルウェアを使って、すべてのオリジンからのリクエストを許可しています。

実際のアプリケーションでは、許可するオリジンを適切に制限することが重要です。

○ネットワークエラーへの対応

ネットワークエラーは、サーバーとの通信が何らかの理由で失敗した場合に発生します。

ネットワークエラーが発生すると、Promiseがrejectされ、catchブロックでエラーを処理することができます。

たとえば、次のようなコードでネットワークエラーをハンドリングできます。

fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error('ネットワークエラーが発生しました');
    }
    return response.json();
  })
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('エラーが発生しました:', error);
  });

ここでは、fetch()メソッドでリクエストを送信した後、response.okプロパティをチェックしています。

response.okがfalseの場合は、ネットワークエラーが発生したとみなし、エラーをスローしています。

エラーはcatchブロックで処理されます。

○レスポンスのステータスコードの確認

レスポンスのステータスコードを確認することで、サーバーからのレスポンスが正常かどうかを判断することができます。

たとえば、ステータスコードが200番台であれば、リクエストが成功したことを表します。

以下のようなコードで、レスポンスのステータスコードをチェックできます。

fetch('https://api.example.com/data')
  .then(response => {
    if (response.status >= 200 && response.status < 300) {
      return response.json();
    } else {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
  })
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('エラーが発生しました:', error);
  });

ここでは、response.statusプロパティを使ってレスポンスのステータスコードをチェックしています。

ステータスコードが200番台の場合は、レスポンスのJSONデータを解析します。

それ以外の場合は、エラーをスローし、catchブロックでエラーを処理します。

実行結果(ステータスコードが200の場合)

{
  "id": 1,
  "name": "John Doe",
  "email": "john@example.com"
}

実行結果(ステータスコードが404の場合)

エラーが発生しました: Error: HTTP error! status: 404

このように、レスポンスのステータスコードを確認することで、サーバーとの通信が正常に行われたかどうかを判断し、適切にエラーハンドリングを行うことができます。

●Fetch APIの応用例

Fetch APIの基本的な使い方を理解したら、より実践的な応用例に挑戦してみましょう。

ここでは、JSONデータの取得と表示、画像の取得と表示、WebSocketを使ったリアルタイム通信など、実際の開発現場でよく使われるシナリオを取り上げます。

これらの応用例を通して、Fetch APIの柔軟性と強力さを実感できるはずです。

実際のプロジェクトでFetch APIを活用する際の参考になれば幸いです。

それでは、具体的なサンプルコードを見ていきましょう。

○サンプルコード7:JSONデータの取得と表示

JSONデータの取得と表示は、Webアプリケーションでよく行われる操作です。

Fetch APIを使えば、簡単にJSONデータを取得し、画面に表示することができます。

fetch('https://api.example.com/data.json')
  .then(response => {
    if (!response.ok) {
      throw new Error('ネットワークエラーが発生しました');
    }
    return response.json();
  })
  .then(data => {
    // JSONデータを処理する
    const container = document.getElementById('data-container');
    data.forEach(item => {
      const element = document.createElement('div');
      element.textContent = item.name;
      container.appendChild(element);
    });
  })
  .catch(error => {
    console.error('エラーが発生しました:', error);
  });

このコードでは、fetch()メソッドを使ってJSONデータを取得し、取得したデータを画面上の要素に追加しています。

data.forEach()を使って、取得したJSONデータを1つずつ処理し、新しい<div>要素を作成して、textContentプロパティにデータを設定しています。

最後に、作成した要素をcontainer要素に追加しています。

実行結果(HTMLファイル)

<div id="data-container"></div>

実行結果(JSONデータ)

[
  {
    "id": 1,
    "name": "John Doe"
  },
  {
    "id": 2,
    "name": "Jane Smith"
  },
  {
    "id": 3,
    "name": "Bob Johnson"
  }
]

実行結果(表示)

John Doe
Jane Smith
Bob Johnson

このように、Fetch APIを使ってJSONデータを取得し、画面に表示することができます。

○サンプルコード8:画像の取得と表示

Fetch APIを使って、サーバーから画像を取得し、画面に表示することもできます。

サンプルコードを見てみましょう。

fetch('https://example.com/image.jpg')
  .then(response => {
    if (!response.ok) {
      throw new Error('ネットワークエラーが発生しました');
    }
    return response.blob();
  })
  .then(blob => {
    const imageURL = URL.createObjectURL(blob);
    const imageElement = document.createElement('img');
    imageElement.src = imageURL;
    document.body.appendChild(imageElement);
  })
  .catch(error => {
    console.error('エラーが発生しました:', error);
  });

このコードでは、fetch()メソッドを使って画像を取得し、response.blob()メソッドでBlobオブジェクトを取得しています。

取得したBlobオブジェクトから、URL.createObjectURL()メソッドを使って一時的なURLを作成し、新しく作成した<img>要素のsrc属性に設定しています。

最後に、作成した<img>要素をdocument.bodyに追加して、画面に表示しています。

実行結果(表示)

(画像が表示される)

このように、Fetch APIを使って画像を取得し、画面に表示することができます。

○サンプルコード9:WebSocketを使ったリアルタイム通信

Fetch APIとWebSocketを組み合わせることで、サーバーとのリアルタイム通信を実現できます。

下記のサンプルコードは、WebSocketを使ってサーバーからリアルタイムにデータを受信し、画面に表示する例です。

// WebSocketサーバーに接続する
const socket = new WebSocket('wss://api.example.com');

// メッセージを受信したときの処理
socket.onmessage = event => {
  const message = event.data;
  const messageElement = document.createElement('div');
  messageElement.textContent = message;
  document.body.appendChild(messageElement);
};

// メッセージを送信する関数
function sendMessage(message) {
  socket.send(message);
}

// メッセージ送信のイベントハンドラ
document.getElementById('send-button').addEventListener('click', () => {
  const messageInput = document.getElementById('message-input');
  const message = messageInput.value;
  sendMessage(message);
  messageInput.value = '';
});

このコードでは、WebSocketオブジェクトを使ってWebSocketサーバーに接続しています。

onmessageイベントハンドラを使って、サーバーからメッセージを受信したときの処理を定義しています。

受信したメッセージを新しい<div>要素に追加して、画面に表示しています。

また、sendMessage()関数を定義して、クリックイベントのイベントハンドラから呼び出すことで、メッセージをサーバーに送信しています。

実行結果(HTMLファイル)

<input type="text" id="message-input">
<button id="send-button">送信</button>

実行結果(表示)

(サーバーから受信したメッセージが表示される)

このように、Fetch APIとWebSocketを組み合わせることで、サーバーとのリアルタイム通信を実現できます。

●セキュリティと最適化

Fetch APIを使ってサーバーとの通信を行う際は、セキュリティと最適化にも十分に気を配る必要があります。

安全で効率的な通信を実現するためには、適切な措置を講じることが不可欠です。

ここでは、セキュアなHTTP通信の実践方法とパフォーマンス改善のためのテクニックについて、具体的なサンプルコードとともに解説していきます。

これらの知識を身につけることで、より堅牢で高速なWebアプリケーションを開発できるようになるでしょう。

○セキュアなHTTP通信の実践

Fetch APIを使ってHTTP通信を行う際は、セキュリティに関する best practice を踏まえることが重要です。

特に、機密性の高いデータを扱う場合は、適切な暗号化と認証のメカニズムを導入する必要があります。

たとえば、SSLサーバー証明書を使ってHTTPS通信を行うことで、通信内容を暗号化し、なりすましを防ぐことができます。

また、リクエストヘッダーに適切な認証トークンを含めることで、不正アクセスを防ぐことができます。

下記のサンプルコードは、HTTPSを使ってセキュアにデータを取得する例です。

fetch('https://api.example.com/data', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer your_access_token_here'
  }
})
  .then(response => {
    if (!response.ok) {
      throw new Error('ネットワークエラーが発生しました');
    }
    return response.json();
  })
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('エラーが発生しました:', error);
  });

このコードでは、fetch()メソッドの第2引数にオプションオブジェクトを指定し、headersプロパティに認証トークンを含めています。

また、HTTPSを使って通信を暗号化しています。

セキュアなHTTP通信を実践するためには、サーバー側の設定も適切に行う必要があります。

SSL/TLSの適切な設定、強力な暗号スイートの選択、最新のセキュリティパッチの適用などが重要です。

○パフォーマンス改善のためのテクニック

Fetch APIを使った通信のパフォーマンスを改善するためには、いくつかのテクニックを活用できます。

たとえば、不要なデータの取得を避けたり、レスポンスのキャッシュを活用したりすることで、通信量を削減し、レスポンスタイムを短縮できます。

また、圧縮アルゴリズムを使ってデータを圧縮することで、通信量を削減できます。

サーバー側でgzip圧縮を有効にし、クライアント側でレスポンスを解凍することで、効率的なデータ通信が可能になります。

○サンプルコード10:Fetch APIの最適化例

下記のサンプルコードは、レスポンスのキャッシュを活用する例です。

function fetchData(url, options) {
  return caches.match(url)
    .then(response => {
      if (response) {
        return response;
      }
      return fetch(url, options)
        .then(response => {
          if (!response.ok) {
            throw new Error('ネットワークエラーが発生しました');
          }
          const clonedResponse = response.clone();
          caches.open('my-cache').then(cache => {
            cache.put(url, clonedResponse);
          });
          return response;
        });
    })
    .catch(error => {
      console.error('エラーが発生しました:', error);
      throw error;
    });
}

このコードでは、caches.match()メソッドを使ってリクエストURLに対応するキャッシュがあるかどうかを確認しています。

キャッシュがある場合は、キャッシュからレスポンスを返します。

キャッシュがない場合は、fetch()メソッドを使って新しいリクエストを送信し、レスポンスをクローンしてキャッシュに追加します。

実行結果(キャッシュがない場合)

{
  "id": 1,
  "name": "John Doe",
  "email": "john@example.com"
}

実行結果(キャッシュがある場合)

{
  "id": 1,
  "name": "John Doe",
  "email": "john@example.com"
}

このように、レスポンスのキャッシュを活用することで、不必要なネットワーク通信を避け、アプリケーションのパフォーマンスを改善できます。

まとめ

Fetch APIは、現代のウェブ開発に欠かせない技術の1つです。

この記事で得た知識を活かして、ぜひ実際のプロジェクトでFetch APIを活用してみてください。

効率的で高品質なコードを書けるようになり、開発スキルを大きく向上させることができるはずです。