Ajaxとは — 非同期ウェブ通信
このトピックを修了すると
ページのリロードなしでサーバーとデータを送受信するAjaxの原理を理解し、fetch APIを使ってGET/POSTリクエストを送信できるようになります。
リロードの問題
従来のウェブでは、サーバーに何かをリクエストすると、ページ全体が再読み込みされました。 検索語を入力してEnterを押すと、画面が白く点滅し、結果ページ全体がロードされます。
Google検索は異なります。検索語を入力すると、おすすめの検索語が下に表示されます。ページは再読み込みされません。これがAjaxです。ページを再読み込みせずに、必要なデータだけサーバーから取得します。
AjaxはAsynchronous JavaScript and XMLの略ですが、現在ではXMLの代わりにJSONを使用します。名前だけが残っているようなものです。
昔のやり方 — XMLHttpRequest
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/users');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
const data = JSON.parse(xhr.responseText);
console.log(data);
}
};
xhr.send();ご覧のように煩雑です。readyStateの値をチェックし、ステータスコードをチェックし、レスポンスを直接パースする必要があります。このコードがコールバックの中にコールバックとしてネストされると、いわゆる「コールバック地獄」になります。
現在の標準 — fetch API
const response = await fetch('/api/users');
const data = await response.json();
console.log(data);3行です。fetchはPromiseを返すため、async/awaitと自然に組み合わされます。
GET — データの取得
async function getUsers() {
const res = await fetch('/api/users');
if (!res.ok) {
throw new Error(`HTTP ${res.status}`);
}
const users = await res.json();
return users;
}注意点:fetchは、404や500でもrejectしません。 ネットワークエラー(サーバーへの接続失敗)でのみrejectします。そのため、res.ok(200~299かどうか)を直接確認する必要があります。
POST — データの送信
async function createUser(name, email) {
const res = await fetch('/api/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name, email }),
});
if (!res.ok) {
throw new Error(`HTTP ${res.status}`);
}
return await res.json();
}bodyに入れるデータをJSON.stringifyで文字列に変換し、Content-Typeをapplication/jsonに設定します。このヘッダーがないと、サーバーが本文をJSONとしてパースしません。
実践的なパターン — ローディング/エラー/成功
const resultDiv = document.getElementById('result');
async function loadUsers() {
resultDiv.textContent = 'ローディング中...';
try {
const res = await fetch('/api/users');
if (!res.ok) throw new Error(`サーバーエラー: ${res.status}`);
const users = await res.json();
resultDiv.textContent = users
.map(u => `${u.name} (${u.email})`)
.join('\n');
} catch (err) {
resultDiv.textContent = `エラー: ${err.message}`;
}
}この3つの状態(ローディング/成功/エラー)を管理することは、フロントエンド開発で繰り返されるパターンです。ReactではuseStateで、Vueではrefで同じ構造を作成します。
fetch vs XMLHttpRequest 比較
| XMLHttpRequest | fetch | |
|---|---|---|
| 構文 | コールバックベース、冗長 | Promiseベース、簡潔 |
| JSONパース | JSON.parse(xhr.responseText) 手動 | .json()メソッド提供 |
| エラー処理 | readyState + status 直接確認 | res.ok + try/catch |
| ストリーミング | 不可 | ReadableStreamサポート |
| キャンセル | xhr.abort() | AbortController |
| クッキー送信 | デフォルトで含む | credentials: 'include' 明示的に指定が必要 |
よくある間違い
- Content-Typeの省略 — POSTで
headersを入れないと、サーバーがreq.bodyをパースできません。 .json()の二重呼び出し —res.json()は一度しか呼び出せません。bodyストリームは一度読むと消費されます。- CORSエラー — 異なるドメインにfetchすると、ブラウザがブロックします。サーバーで
Access-Control-Allow-Originヘッダーを設定する必要があります。
核心
Ajaxは、ページのリロードなしでサーバーとデータを送受信する技術です。 現代のウェブでは、
fetchAPI +async/awaitが標準です。fetchはネットワークエラーでのみrejectするため、res.okを必ず確認してください。