JavaScript Fetch API
1. Fetch API とは
fetch() は、サーバーからデータをリクエストするためのモダンな手法です。
fetch()は非同期(Asynchronous)であり、プロミス(Promise)を返します。- モダンなアプリケーションでは、データの取得に非同期コードを使用するのが一般的です。
fetch()は、その最も代表的な例と言えるでしょう。
2. fetch はプロミスを返す
fetch() は、呼び出し直後にデータそのものを返すわけではありません。
後でレスポンス(Response)を解決するためのプロミスを返します。
fetch("data.json")
.then(function(response) {
console.log(response);
});この結果として得られるのは Response オブジェクトであり、JSON データそのものではありません。
3. JSON データの取得
JSON データを取得するには、レスポンスのボディ(Body)を読み取る必要があります。response.json() メソッドを実行すると、これ自体もまたプロミスを返します。
fetch("data.json")
.then(function(response) {
// レスポンスを JSON として解析し、次のプロミスを返します
return response.json();
})
.then(function(data) {
// 解析されたデータにアクセスできます
console.log(data);
});これはプロミスチェーン(Promise chain)と呼ばれる構造です。
4. fetch と async / await
async と await を使用すると、fetch のコードをより直感的で読みやすく書くことができます。
これは特に初心者の方に推奨される、モダンな記述スタイルです。
async function loadData() {
let response = await fetch("data.json");
let data = await response.json();
console.log(data);
}
loadData();5. 重要:HTTP エラーの扱い
初心者がよく陥るミスに、「404(Not Found)や 500(Internal Server Error)が発生したときに fetch が失敗(Reject)する」と思い込んでしまうことがあります。
実際には、fetch がプロミスを拒否(Reject)するのはネットワークエラー(物理的な通信断絶など)の場合のみです。
404 レスポンスが返ってきても、プロミスは拒否されません。
そのため、必ず response.ok プロパティを確認する必要があります。
async function loadData() {
let response = await fetch("missing.json");
// HTTP ステータスが 200-299 以外の場合は対処が必要
if (!response.ok) {
console.log("HTTP エラーが発生しました:", response.status);
return;
}
let data = await response.json();
console.log(data);
}
loadData();上記のように記述することで、HTTP エラーを正しくハンドリングできます。
6. ネットワークエラー
ネットワークエラーは、オフライン時や DNS エラーなど、リクエスト自体を完了できない場合に発生します。
この場合に限り、fetch のプロミスは拒否(Reject)されます。
async function loadData() {
try {
let response = await fetch("data.json");
let data = await response.json();
console.log(data);
} catch (error) {
// ネットワーク障害などはここでキャッチします
console.log("ネットワークエラーが発生しました");
}
}7. fetch のよくあるミス
await を忘れると、データではなくプロミスそのものを操作しようとしてしまいます。
間違った例
async function loadData() {
let response = await fetch("data.json");
let data = response.json(); // await がない!
console.log(data); // プロミスオブジェクトがログ出力されてしまいます
}JSON を取得するには、必ず await を使用してください。
正しい例
async function loadData() {
let response = await fetch("data.json");
let data = await response.json();
console.log(data);
}8. デバッグのヒント
もし fetch がうまく動かない場合は、以下のステップでデバッグを行いましょう。
- コンソール(Console)を確認し、JavaScript のエラーが出ていないか見る。
- 次にブラウザの Network タブを確認する。
- ファイルパス(URL)は正しいか。
- ステータスコードは 200 か。
- レスポンスの中身は本当に正しい JSON 形式か。
実のところ、fetch の不具合の多くは JavaScript 自体のバグではなく、パスの設定ミスやサーバー側のレスポンスの問題です。
9. コールバック vs Fetch
ここでは、古い手法(コールバック)と新しい手法(Fetch)を比較してみましょう。
コールバックを使用した data.json の読み込み
function loadFile(callback) {
let xhr = new XMLHttpRequest();
xhr.open("GET", "data.json", true);
xhr.onload = function() {
if (xhr.status === 200) {
callback(null, JSON.parse(xhr.responseText));
} else {
callback("HTTP エラー: " + xhr.status, null);
}
};
xhr.onerror = function() {
callback("ネットワークエラー", null);
};
xhr.send();
}
loadFile(function(error, data) {
if (error) {
console.log(error);
return;
}
console.log(data);
});10. コールバック手法の解説
loadFile()自体はデータを返しません。- 処理結果を受け取るためのコールバック関数を引数に渡す必要があります。
- ファイルが読み込まれた「後」にコールバックが実行されます。
- エラー処理を手動で細かく記述する必要があります。
- 処理ステップが増えるたびに、ネスト(入れ子)が深くなっていきます。
11. Fetch を使用したデータ読み込み
同じ処理を fetch で記述すると、非常にスッキリします。
async function loadFile() {
try {
let response = await fetch("data.json");
if (!response.ok) {
throw new Error("HTTP エラー: " + response.status);
}
let data = await response.json();
console.log(data);
} catch (error) {
console.log(error);
}
}
loadFile();12. Fetch 手法の解説
fetch()はプロミスを返します。awaitを使うことで、非同期処理を待機している間、関数の実行を一時停止できます。- エラーは
try...catchで一括管理できます。 - コードのフローが上から下へ流れるため、読みやすさが格段に向上します。
- コールバックのネストから解放されます。
13. 主な違いのまとめ
| 特徴 | コールバック(XMLHttpRequest) | Promise / async-await(Fetch) |
|---|---|---|
| 基本的な考え方 | 後で実行する関数を渡す | プロミスの解決を待機する |
| エラー処理 | 手動のエラー優先パターンが必要 | try...catch による組み込みフロー |
| 可読性 | ネストが深くなりやすい | 通常の同期コードのように読める |
| チェーン処理 | 困難 | メソッドチェーンで容易に記述可能 |