はじめに (対象読者・この記事でわかること)

この記事は、JavaScriptの基本的な知識を持ち、Web APIからのデータ取得に興味がある方、または既存のWebサービスと連携するフロントエンドアプリケーションを開発したいと考えているプログラミング初学者の方を対象としています。

この記事を読むことで、JavaScriptの標準機能であるfetch APIを使って、Web上にあるJSON形式のデータを非同期で取得する基本的な方法を理解し、実際にコードを書いてデータを表示できるようになります。また、データ取得時に発生しうるエラーへの対処法(エラーハンドリング)も学ぶことで、より堅牢なアプリケーション開発の一歩を踏み出せるようになるでしょう。API連携の基礎を固めたい方にとって、この記事は強力な出発点となるはずです。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。 * HTML/CSSの基本的な知識(Webページを構成する要素とスタイルの理解) * JavaScriptの基本的な構文(変数、関数、オブジェクト、配列など) * JSONの基本概念(JavaScript Object Notationがデータ形式として使われること、その構造)

JavaScriptの非同期処理とfetch APIの基本

現代のWebアプリケーションでは、画面の表示をブロックすることなく、外部のサーバーからデータを取得したり、データを送信したりする「非同期処理」が不可欠です。例えば、ユーザーがボタンをクリックしたときに裏でデータを取得し、その間もUIを操作できるような体験は非同期処理によって実現されています。

かつてはXMLHttpRequest(XHR)がこの非同期通信の中心でしたが、よりシンプルで強力なAPIとして登場したのがfetch APIです。fetch APIは、ネットワークリソースの取得を行うためのモダンなインターフェースを提供し、Promiseベースで設計されているため、非同期処理をより直感的に記述できます。JSON形式のデータを取得する際も、fetch APIを使うことで非常に簡潔にコードを書くことが可能です。fetchはHTTPリクエストを送信し、レスポンスを受け取るまでの一連の処理を抽象化してくれるため、開発者はデータの取得と利用に集中できます。

fetch APIでJSONデータを取得する具体的な手順

それでは、fetch APIを使って実際にJSONデータを取得し、利用する手順を見ていきましょう。今回は、テスト用の公開APIであるJSONPlaceholderからダミーのユーザーデータを取得する例を扱います。

ステップ1:fetchの基本的な使い方

fetch関数は、第一引数に取得したいリソースのURLを渡します。fetch関数はPromiseを返すため、.then()メソッドを使ってレスポンスを処理します。

Javascript
fetch('https://jsonplaceholder.typicode.com/users') .then(response => { // レスポンスが正常かどうかを確認 if (!response.ok) { // HTTPステータスが200番台以外の場合 throw new Error(`HTTP error! status: ${response.status}`); } // レスポンスボディをJSONとして解析 return response.json(); }) .then(data => { // 取得したJSONデータを利用 console.log(data); // 例: 最初のユーザーの名前を表示 if (data.length > 0) { console.log(`最初のユーザーの名前: ${data[0].name}`); } }) .catch(error => { // エラーが発生した場合の処理 console.error('データの取得中にエラーが発生しました:', error); });

上記のコードでは、まずfetch('https://jsonplaceholder.typicode.com/users')でリクエストを送信します。 最初の.then(response => { ... })ブロックでは、サーバーからのレスポンスオブジェクトを受け取ります。ここで重要なのがresponse.okプロパティです。これはHTTPステータスコードが200番台(成功)であることを示す真偽値で、falseの場合はエラーとしてthrow new Error()で例外を発生させ、.catch()ブロックで捕捉させます。 response.json()メソッドは、レスポンスボディをJSONとして解析し、その結果もPromiseとして返します。

ステップ2:JSONデータのパースと利用

response.json()が返したPromiseが解決されると、次の.then(data => { ... })ブロックで実際に解析されたJSONデータを受け取ることができます。このdata変数には、APIから取得したユーザー情報の配列がJavaScriptのオブジェクトとして格納されています。

このdataオブジェクトは、通常のJavaScriptオブジェクトや配列と同じようにアクセスできます。例えば、data[0].nameで最初のユーザーの名前を取得し、コンソールに表示しています。このようにして、取得したデータをWebページに表示したり、他の処理に利用したりすることが可能になります。

ステップ3:async/awaitを使ったよりモダンな書き方(補足)

Promiseのチェーンは強力ですが、より複雑な非同期処理ではコードが読みにくくなることがあります。JavaScriptのasync/await構文を使うと、非同期処理を同期処理のように記述でき、可読性が向上します。

Javascript
async function fetchUsers() { try { const response = await fetch('https://jsonplaceholder.typicode.com/users'); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); console.log(data); if (data.length > 0) { console.log(`最初のユーザーの名前 (async/await): ${data[0].name}`); } } catch (error) { console.error('データの取得中にエラーが発生しました (async/await):', error); } } fetchUsers();

asyncキーワードを関数宣言の前につけることで、その関数内でawaitキーワードを使用できるようになります。awaitはPromiseが解決されるまでコードの実行を一時停止させ、解決された値を受け取ります。これにより、.then()のネストを避けて、より線形的なコードを書くことができます。エラーハンドリングはtry...catchブロックで行います。

ハマった点やエラー解決

fetch APIを使った開発では、いくつかの一般的な問題に遭遇することがあります。

  1. CORS (Cross-Origin Resource Sharing) エラー:
    • 現象: ブラウザのコンソールに「Access to fetch at '...' from origin '...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.」のようなエラーが表示される。
    • 原因: Webページを提供しているドメインと、APIが提供されているドメインが異なる場合に発生します。セキュリティ上の理由から、ブラウザは異なるオリジン(ドメイン、プロトコル、ポートの組み合わせ)へのリクエストを制限しています。APIサーバーがAccess-Control-Allow-Originヘッダーを設定していないと、このエラーが発生します。
  2. JSONパースエラー:
    • 現象: SyntaxError: Unexpected token < in JSON at position 0SyntaxError: Unexpected end of JSON input などが表示される。
    • 原因: response.json()を呼び出しているにもかかわらず、サーバーからのレスポンスが実際のJSON形式ではなかった場合(例: HTMLエラーページが返された、空のレスポンスだったなど)。
  3. ネットワーク接続がない、またはURLが間違っている:
    • 現象: TypeError: Failed to fetchNetworkError when attempting to fetch resource. などが表示される。
    • 原因: 指定したURLが存在しない、インターネット接続がない、またはURLのタイポがある場合など。

解決策

これらの問題には、以下のように対処できます。

  1. CORS エラーの解決策:
    • 開発時: 開発用プロキシサーバー(例: Webpack Dev Serverのproxy設定、Viteのserver.proxy設定)を利用して、ブラウザから見ると同じオリジンへのリクエストに見せかける。
    • 本番時: APIの提供者と連携し、APIサーバー側でCORSヘッダー(Access-Control-Allow-Origin)を適切に設定してもらう必要があります。ワイルドカード*を使うのはセキュリティリスクがあるため、特定のオリジンのみを許可するのが一般的です。
  2. JSONパースエラーの解決策:
    • response.text()を使って生のレスポンスボディを確認し、本当にJSON形式になっているかデバッグする。
    • response.okでのチェックを徹底し、成功レスポンス(HTTP 200番台)以外はJSONパースを試みないようにする。
    • try...catchブロックでresponse.json()の呼び出しを囲むことで、パースエラーが発生してもアプリケーションがクラッシュしないようにする。
  3. ネットワーク接続エラーの解決策:
    • URLのスペルミスがないか、再度確認する。
    • インターネット接続を確認する。
    • fetch関数の.catch()ブロック(またはasync/awaittry...catch)でこれらのエラーを適切に捕捉し、ユーザーに分かりやすいメッセージを表示するなどのフォールバック処理を実装する。

これらの解決策を念頭に置くことで、より堅牢でユーザーフレンドリーなWebアプリケーションを構築できるでしょう。

まとめ

本記事では、JavaScriptにおけるモダンなWeb APIデータ取得手法として、fetch APIに焦点を当てて解説しました。

  • fetch APIの基本: fetch関数がPromiseを返し、.then()でレスポンスを処理し、.catch()でエラーを捕捉する基本的な流れを学びました。
  • JSONデータの取得とパース: response.json()メソッドを使用してレスポンスボディをJSONオブジェクトに変換し、JavaScript内で利用する方法を理解しました。
  • エラーハンドリングの実践: response.okによるHTTPステータスのチェックや、try...catchブロック(または.catch())を用いたネットワークエラーやJSONパースエラーへの対処法を学びました。

この記事を通して、あなたは実際のWebサービスと連携し、JSON形式のデータを取得して活用するための基本的なスキルを身につけました。これにより、動的なコンテンツ表示やユーザーインタラクションを含む、よりリッチなWebアプリケーション開発への第一歩を踏み出せたはずです。

今後は、APIへのデータ送信(POST/PUTメソッド)、リクエストヘッダーの設定、認証情報を含むリクエストの送信、あるいは非同期処理をさらに効率的に記述するためのasync/await構文の深い活用など、発展的な内容についても学習を進めることで、さらに強力なWeb開発者となることができるでしょう。

参考資料