読み込み中...
読み込み中...
読み込み中...
読み込み中...
読み込み中...
Fetch API はブラウザ標準のHTTP通信インターフェースです。XMLHttpRequest の後継として設計され、Promise ベースのシンプルなAPIを提供します。
fetch() 関数は URL を引数に取り、Response オブジェクトで解決される Promise を返します。重要な点として、fetch はHTTP エラーステータス(404, 500等)でも reject しません。ネットワークエラーの場合のみ reject されます。
| メソッド | 用途 |
|---|---|
fetch(url) | GET リクエスト |
fetch(url, { method: 'POST', ... }) | POST リクエスト |
response.json() | レスポンスをJSONとしてパース |
response.text() | レスポンスをテキストとして取得 |
response.blob() | レスポンスをBlobとして取得 |
response.ok | ステータスが 200-299 なら true |
response.status | HTTP ステータスコード |
Fetch API の GET/POST リクエストとキャンセル
// GET リクエスト
async function fetchUsers() {
const response = await fetch("https://jsonplaceholder.typicode.com/users");
// HTTP エラーチェック(fetch は 404 でも reject しない)
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const users = await response.json();
return users;
}
// POST リクエスト
async function createPost(title, body) {
const response = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ title, body, userId: 1 })
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
}
// AbortController によるリクエストのキャンセル
async function fetchWithCancel(url) {
const controller = new AbortController();
// 3秒後にキャンセル
setTimeout(() => controller.abort(), 3000);
try {
const response = await fetch(url, { signal: controller.signal });
return await response.json();
} catch (err) {
if (err.name === "AbortError") {
console.log("リクエストがキャンセルされました");
}
throw err;
}
}チャレンジ
関数 safeFetch を実装してください。URL と options を受け取り、fetch を実行します。レスポンスの ok が false の場合はエラーを throw し、成功時は JSON パース結果を返してください。(テストでは模擬関数を使います)
ポイント
Fetch API は Promise ベースの HTTP 通信 API です。response.ok でステータスをチェックし、json() / text() でボディをパースします。AbortController でリクエストのキャンセルが可能です。
Web Storage API はブラウザにデータを保存するための仕組みです。localStorage と sessionStorage の2種類があり、いずれもキーと値のペアで文字列を保存します。
| 種類 | データの寿命 | スコープ | 容量 |
|---|---|---|---|
localStorage | 明示的に削除するまで永続 | 同一オリジン内で共有 | 約5-10MB |
sessionStorage | タブ/ウィンドウを閉じるまで | 同一タブ内のみ | 約5-10MB |
Cookie と比較すると、Web Storage はサーバーに自動送信されない点が異なります。クライアントサイドのみでデータを保持する用途に適しています。
注意: Web Storage は文字列のみ保存できます。オブジェクトや配列を保存する場合は JSON.stringify() / JSON.parse() で変換が必要です。
localStorage の基本操作とオブジェクトの保存
// localStorage の基本操作
localStorage.setItem("username", "田中");
console.log(localStorage.getItem("username")); // "田中"
localStorage.removeItem("username");
localStorage.clear(); // 全データを削除
// オブジェクトの保存(JSON変換が必要)
const settings = {
theme: "dark",
fontSize: 16,
language: "ja"
};
localStorage.setItem("settings", JSON.stringify(settings));
const loaded = JSON.parse(localStorage.getItem("settings"));
console.log(loaded.theme); // "dark"
// ストレージの有無チェック
function storageAvailable(type) {
try {
const storage = window[type];
const test = "__storage_test__";
storage.setItem(test, test);
storage.removeItem(test);
return true;
} catch (e) {
return false;
}
}
console.log(storageAvailable("localStorage")); // true/falselocalStorage の変更は、同一オリジンの他のタブ/ウィンドウで storage イベントとして検知できます。同一タブ内では発火しない点に注意してください。タブ間の通信手段として活用できます。
チャレンジ
localStorage を使ったシンプルなデータ管理クラス Store を実装してください。save(key, value)(オブジェクト対応)、load(key)(デフォルト値対応)、remove(key) メソッドを持ちます。(テスト用にメモリ内 Map で模倣します)
ポイント
localStorage は永続的、sessionStorage はタブ終了まで有効なクライアントサイドストレージです。文字列のみ保存可能なため、オブジェクトは JSON.stringify / JSON.parse で変換が必要です。
URL API は URL を構造的にパース・操作するための API です。URL コンストラクタに URL 文字列を渡すと、各部分(プロトコル、ホスト、パス、クエリパラメータ等)にアクセスできます。
| プロパティ | 例(https://example.com:8080/path?q=test#section) |
|---|---|
protocol | "https:" |
hostname | "example.com" |
port | "8080" |
pathname | "/path" |
search | "?q=test" |
hash | "#section" |
searchParams | URLSearchParams オブジェクト |
URLSearchParams はクエリパラメータを安全に操作するためのインターフェースです。
History API はブラウザの履歴スタックを操作する API です。pushState でページ遷移なしに URL を変更でき、SPA(Single Page Application)のルーティングの基盤になっています。
URL API と URLSearchParams の操作
// URL API
const url = new URL("https://example.com/search?q=javascript&page=1#results");
console.log(url.hostname); // "example.com"
console.log(url.pathname); // "/search"
console.log(url.hash); // "#results"
// URLSearchParams の操作
console.log(url.searchParams.get("q")); // "javascript"
console.log(url.searchParams.get("page")); // "1"
url.searchParams.set("page", "2");
url.searchParams.append("lang", "ja");
console.log(url.toString());
// "https://example.com/search?q=javascript&page=2&lang=ja#results"
// クエリパラメータの反復
for (const [key, value] of url.searchParams) {
console.log(`${key}: ${value}`);
}History API による SPA ルーティングの基礎
// History API の基本
// pushState: 履歴エントリを追加(ページ遷移なし)
history.pushState(
{ page: "about" }, // state オブジェクト
"", // title(多くのブラウザで無視される)
"/about" // URL
);
// replaceState: 現在の履歴エントリを置き換え
history.replaceState({ page: "home" }, "", "/");
// popstate イベント: ブラウザの戻る/進むボタンで発火
window.addEventListener("popstate", (event) => {
console.log("移動先:", event.state);
// event.state は pushState で保存したオブジェクト
});
// 履歴の移動
history.back(); // 戻る
history.forward(); // 進む
history.go(-2); // 2つ前に戻るチャレンジ
関数 buildUrl を実装してください。ベース URL とパラメータオブジェクトを受け取り、クエリパラメータ付きの URL 文字列を返します。
ポイント
URL API は URL の構造的な操作を提供し、URLSearchParams でクエリパラメータを安全に操作できます。History API の pushState はページ遷移なしに URL を変更でき、SPA ルーティングの基盤です。
Observer API はブラウザが提供する監視パターンの実装で、特定の変化を効率的に検知できます。自前でポーリングするよりもパフォーマンスに優れ、ブラウザが最適なタイミングで通知してくれます。
| Observer | 監視対象 | 主な用途 |
|---|---|---|
IntersectionObserver | 要素の可視性(ビューポートとの交差) | 遅延読み込み、無限スクロール |
MutationObserver | DOM の変更 | DOM 監視、動的コンテンツの検知 |
ResizeObserver | 要素のサイズ変更 | レスポンシブ対応、レイアウト調整 |
PerformanceObserver | パフォーマンス計測 | Web Vitals、リソース読み込み監視 |
これらの Observer はすべて似た API パターンを持ちます。コンストラクタにコールバック関数を渡し、observe() で監視を開始、disconnect() で停止します。
IntersectionObserver による画像の遅延読み込み
// IntersectionObserver: 遅延読み込み(Lazy Loading)
const lazyImages = document.querySelectorAll("img[data-src]");
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src; // data-src を src にコピー
img.removeAttribute("data-src");
observer.unobserve(img); // 読み込み後は監視を停止
}
});
}, {
rootMargin: "200px", // ビューポートの200px手前で発火
threshold: 0 // 少しでも見えたら
});
lazyImages.forEach(img => imageObserver.observe(img));MutationObserver による DOM 変更の監視
// MutationObserver: DOM変更の監視
const targetNode = document.getElementById("app");
const mutationObserver = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
if (mutation.type === "childList") {
console.log("子要素が変更されました");
mutation.addedNodes.forEach(node => {
console.log("追加:", node.nodeName);
});
mutation.removedNodes.forEach(node => {
console.log("削除:", node.nodeName);
});
} else if (mutation.type === "attributes") {
console.log(`属性 ${mutation.attributeName} が変更されました`);
}
});
});
mutationObserver.observe(targetNode, {
childList: true, // 子要素の追加・削除を監視
attributes: true, // 属性の変更を監視
subtree: true // 子孫要素も含めて監視
});
// 監視の停止
// mutationObserver.disconnect();チャレンジ
Observer パターンを模倣した createObserver 関数を実装してください。observe(callback) で登録、notify(data) で全コールバックに通知、disconnect() で全登録を解除する機能を持ちます。
ポイント
IntersectionObserver は遅延読み込みや無限スクロールに、MutationObserver は DOM 変更の検知に使います。Observer パターンは「observe → notify → disconnect」の統一的な API で、イベントリスナよりも効率的な監視を実現します。
実務での活用
ブラウザには fetch によるサーバー通信、localStorage によるデータ保存、IntersectionObserver による要素の可視判定など、豊富なAPIが組み込まれています。外部ライブラリを導入する前に「ブラウザの標準APIで実現できないか」を検討する習慣をつけると、依存関係が少なく保守しやすいコードになります。
用語