JavaScript でサーバーからデータを取得したり、フォームの内容を送信したりするときに使うのが fetch() です。外部の API からデータを読み込んで画面に表示する、といった処理の基本になります。この記事では、fetch() の基本的な使い方を、async / await やエラーハンドリング、POST 送信まで含めて解説します。
目次
fetch() とは
fetch() は、指定した URL に HTTP リクエストを送り、その結果を受け取るための関数です。ブラウザに標準で備わっているため、ライブラリを読み込まずにそのまま使えます。
fetch() は Promise(非同期処理の結果を表すオブジェクト)を返します。通信は時間がかかる処理なので、結果を「待ってから」次の処理に進む、という書き方をします。Promise や async / await の基礎については別記事も参考にしてください。
基本の使い方(データを取得する)
もっとも基本的な使い方は、URL を渡して結果を受け取る形です。fetch() が返す Promise を .then() でつなぎ、レスポンスを JSON に変換して使います。
fetch('https://api.example.com/users')
.then((response) => response.json()) // レスポンスをJSONに変換
.then((data) => {
console.log(data); // 取得したデータ
});
1つ目の .then() で受け取る response は「レスポンス本体」で、まだデータそのものではありません。response.json() を呼んで JSON に変換すると、2つ目の .then() で実際のデータ(data)を受け取れます。
async / await で書く
.then() をつなげる書き方は、処理が増えるとネストが深くなりがちです。async / await を使うと、上から下に読める自然なコードになります。
async function getUsers() {
const response = await fetch('https://api.example.com/users');
const data = await response.json();
console.log(data);
}
getUsers();
await は「この処理が終わるまで待つ」という意味です。await を使う関数には async を付ける必要があります。.then() 版と同じ動きですが、こちらのほうが読みやすいことが多いです。
エラーを正しく処理する
ここが fetch() でつまずきやすいポイントです。fetch() は通信そのものに失敗したときだけエラー(reject)になり、404 や 500 などの HTTP エラーではエラーになりません。そのため、response.ok を自分でチェックする必要があります。
async function getUsers() {
try {
const response = await fetch('https://api.example.com/users');
// 404や500などのHTTPエラーはここで自分で判定する
if (!response.ok) {
throw new Error(`HTTPエラー: ${response.status}`);
}
const data = await response.json();
console.log(data);
} catch (error) {
// 通信エラーや上のthrowをまとめて受け取る
console.error('取得に失敗しました:', error);
}
}
response.ok はステータスコードが 200 番台のとき true になります。false のときは throw でエラーを投げ、catch でまとめて処理します。これで「サーバーは応答したがエラーだった」ケースも取りこぼしません。
POST でデータを送る
データを送信するときは、第2引数のオプションで method や headers、body を指定します。JSON を送る場合は、Content-Type を指定し、body を JSON.stringify() で文字列に変換します。
async function createUser() {
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: '山田太郎',
email: 'taro@example.com',
}),
});
const data = await response.json();
console.log(data);
}
送信するデータはオブジェクトのままでは送れないため、JSON.stringify() で文字列に変換するのを忘れないようにしましょう。
データが取れない・エラーになるときは
fetch() は手軽な反面、独特のクセでつまずきやすい関数です。思った通りに動かないときは、次のポイントを確認してみてください。
response.json() を呼んでいない
fetch() が返すのは「レスポンス本体」で、まだデータそのものではありません。response.json()(や response.text())を呼んで中身を取り出す必要があります。これを忘れると、データではなくレスポンスオブジェクトを扱おうとして、うまく中身を読めません。
HTTP エラーが検知できていない
これが一番のハマりどころです。fetch() は通信そのものに失敗したときだけエラーになり、404 や 500 などの HTTP エラーでは catch に入りません。つまり「サーバーは応答したがエラーだった」ケースは、自分で response.ok を確認しないと素通りしてしまいます。エラー時に throw して catch で処理する形にしておきましょう。
await を付け忘れている
await を付け忘れると、データではなく Promise(処理中の状態)がそのまま返ってきます。fetch() と response.json() の両方に await を付けているか、そして await を使う関数に async が付いているかを確認してください。
送信する body を文字列にしていない
POST などでデータを送るとき、body にオブジェクトをそのまま渡しても正しく送れません。JSON.stringify() で文字列に変換し、あわせて Content-Type: application/json を指定しているか確認しましょう。
まとめ
fetch() は、ブラウザだけで HTTP 通信ができる便利な関数です。基本の流れを押さえておけば、API からのデータ取得もフォームの送信も同じパターンで書けます。
- 取得は
fetch(url)→response.json()でデータを取り出す async / awaitを使うと上から下に読めるコードになる- HTTP エラーは
response.okで自分で判定する - 送信は
method・headers・body(JSON.stringify())を指定する
まずは公開されている練習用の API を使って、データを取得して console.log() で表示するところから試してみると理解が早いです。