タイトル: WebStorage API
SEOタイトル: Web Storage API 完全ガイド(localStorage / sessionStorage / Cookie との違い / 容量と注意点)
| この記事の要点 |
|
Web Storage API とは
Web Storage API はブラウザに用意されたキー/値ストレージです。JavaScript から手軽にデータを読み書きでき、リロードしても残ります。Cookie より大容量で、サーバーに自動送信されないためクライアント側の状態保存に最適です。
2 つのストレージが用意されており、保持期間とスコープが異なります。
| 項目 | localStorage | sessionStorage |
|---|---|---|
| 保持期間 | 永続 (明示削除まで) | タブ / ウィンドウを閉じるまで |
| 共有範囲 | 同一オリジンの全タブ | 同一タブのみ |
| 容量 | 約 5MB | 約 5MB |
Cookie との比較
| 項目 | Web Storage | Cookie |
|---|---|---|
| 容量 | 約 5MB | 約 4KB |
| サーバー送信 | 送信しない | 毎リクエスト送信 |
| 有効期限 | 明示削除まで (local) / タブ閉じまで (session) | Expires / Max-Age で個別指定 |
| JS からの読み書き | 常に可能 | HttpOnly 指定で不可 |
| 主な用途 | UI 状態 / オフラインキャッシュ | ログインセッション |
基本操作 (API)
// 保存 (キー / 値 とも文字列)
localStorage.setItem("theme", "dark");
sessionStorage.setItem("tab", "1");
// 読み出し (なければ null)
const theme = localStorage.getItem("theme");
// 削除
localStorage.removeItem("theme");
// 全削除 (現オリジンのみ)
localStorage.clear();
// 件数とキー列挙
console.log(localStorage.length);
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
console.log(key, localStorage.getItem(key));
}
オブジェクトを保存する
Web Storage の値は文字列のみなので、オブジェクトは JSON 変換します。
const user = { id: 1, name: "Alice", roles: ["admin"] };
// 保存
localStorage.setItem("user", JSON.stringify(user));
// 取得
const raw = localStorage.getItem("user");
const obj = raw ? JSON.parse(raw) : null;
// 失敗に強い読み出し
function safeGet(key) {
try {
return JSON.parse(localStorage.getItem(key) ?? "null");
} catch {
return null;
}
}
storage イベント — 他タブとの同期
同じオリジンの他のタブで localStorage が変更されると storage イベントが発火します (自タブには通知されません)。
window.addEventListener("storage", (e) => {
console.log(e.key, e.oldValue, "→", e.newValue);
if (e.key === "theme") {
applyTheme(e.newValue);
}
});
容量制限と例外処理
容量を超えると QuotaExceededError が投げられます。シークレットウィンドウや一部 OS の制限でも投げられるので、書き込みはtry / catch が無難です。
try {
localStorage.setItem("big", giantString);
} catch (e) {
if (e.name === "QuotaExceededError") {
// 古いキャッシュを掃除して再試行など
}
}
セキュリティ上の注意
- XSS で簡単に盗まれる: localStorage は JS から無制限アクセス可能
- JWT / アクセストークンは HttpOnly + Secure Cookie の方が安全な場合が多い
- 個人情報・支払い情報を平文で置かない
- オリジンが異なるサブドメインとは共有されない (例:
a.example.comとb.example.com) - サードパーティ Cookie 規制と同様、第三者コンテキストでは制限される傾向
FAQ
Q: localStorage と IndexedDB の使い分け
A: 小さいキー値は localStorage、構造化された大量データは IndexedDB。後者は非同期で容量も数百 MB 〜 GB クラス。
Q: 暗号化して保存すれば安全?
A: 鍵自体が JS から見える限り、本質的なセキュリティ向上は限定的。機密データはサーバー / HttpOnly Cookie が原則です。
Q: シークレットウィンドウでも使える?
A: 使えますが、ウィンドウを閉じると消える挙動。永続性に依存しないでください。
Q: 動作確認はどこで?
A: ブラウザの開発者ツール > Application > Storage セクションでオリジン別に閲覧・編集・削除が可能です。
Q: SSR (サーバーサイドレンダリング) で参照したい
A: Web Storage はブラウザ専用。Next.js などでは useEffect 内などクライアント実行時のみアクセスする必要があります。SSR 側では window is not defined エラーになるので注意。
典型的なユースケース
| 用途 | 適切なストレージ |
|---|---|
| テーマ (dark / light) | localStorage |
| サイドバー開閉状態 | localStorage |
| カート (未ログイン時) | localStorage |
| フォームの一時保存 (タブ固有) | sessionStorage |
| ログイントークン | HttpOnly Cookie (Web Storage 非推奨) |
| 大容量画像キャッシュ | IndexedDB / Cache API |
まとめ
Web Storage API はブラウザに小〜中量のキー値データを残したいときの最も手軽な選択肢です。Cookie より大容量、IndexedDB より単純で、UI 状態の永続化や軽量キャッシュに最適。ただしXSS リスクと容量制限を理解し、機密情報は置かない・try/catch で書き込みエラーに備える・他タブとは storage イベントで同期する、という基本を押さえれば実用上ほぼ困りません。
関連
- Cookie — サーバー送信されるストレージ
- IndexedDB — 構造化データの非同期ストレージ
- Cache API — Service Worker と組み合わせるレスポンスキャッシュ