Fetch API
HTTP リクエストを送信するためのモダンな Web API で、XMLHttpRequest の後継
Fetch API とは
Fetch API は、ブラウザと Node.js で HTTP リクエストを送信するためのモダンな API である。Promise ベースで、XMLHttpRequest と比較してシンプルな記法で非同期通信を行える。
基本的な使い方
基本的な使い方のコード例を示す。
// GET リクエスト
const response = await fetch('https://api.example.com/users');
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const users: User[] = await response.json();
// POST リクエスト
const created = await fetch('https://api.example.com/orders', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userId: '123', items: [{ productId: 'abc', qty: 1 }] }),
});
fetch の注意点
HTTP エラーで reject しない
// ❌ fetch は 404 や 500 でも reject しない
const response = await fetch('/api/users/999');
// response.ok === false, response.status === 404 だが、例外は投げない
// ✅ response.ok をチェック
if (!response.ok) {
throw new Error(`API error: ${response.status} ${response.statusText}`);
}
タイムアウト
fetch にはデフォルトのタイムアウトがない。AbortSignal.timeout() か AbortController で明示的に打ち切る。
// AbortSignal.timeout() — 主要ブラウザでは 2024 年 4 月以降の版で利用できる
const response = await fetch(url, { signal: AbortSignal.timeout(5000) });
// 古い実行環境では AbortController + タイマー (成功時もタイマーを解除する)
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch(url, { signal: controller.signal });
} finally {
clearTimeout(timer);
}
打ち切られた fetch は例外で終わるが、理由の名前が違う。AbortSignal.timeout() は TimeoutError、controller.abort() は既定で AbortError で reject する。「タイムアウトだけ再試行してユーザー操作によるキャンセルは再試行しない」という分岐を書くなら、err.name を見分ける必要がある。
XMLHttpRequest との比較
XMLHttpRequest との主な違いを以下に比較する。
| 観点 | Fetch API | XMLHttpRequest |
|---|---|---|
| 構文 | Promise ベース | コールバックベース |
| ストリーミング | ReadableStream 対応 | 非対応 |
| リクエストキャンセル | AbortController | abort() |
| Cookie | 既定は同一オリジンのみ (credentials: 'same-origin') | 同一オリジンは送信・クロスオリジンは withCredentials が必要 |
| 進捗取得 | ダウンロードのみ ReadableStream で実装可 | onprogress でダウンロード・アップロード両方 |
Cookie の扱いは現行仕様ではほぼ同等で、どちらもクロスオリジンで送るにはサーバー側の Access-Control-Allow-Credentials の同意が要る。実務で差が出るのはアップロードの進捗で、fetch はリクエスト本体の送信量を通知しない。進捗バーが要件なら XMLHttpRequest の upload.onprogress を使うか、分割アップロードして完了数を数える。
fetch は Node.js 18 でグローバルに追加され、Node.js 21 で安定版になった (それ以前は experimental 扱いで初回使用時に警告が出る)。Lambda などサーバーサイドでも同じ書き方が使える。
Fetch API の理解を深めるには関連書籍が参考になる。
この記事は役に立ちましたか?