4.

Web Storage API入門|localStorage・sessionStorage・Cookieの違い

編集
この記事の要点
  • Web Storage API はブラウザにキー/値形式でデータを保存する仕組み。localStoragesessionStorage の 2 種類
  • localStorage永続sessionStorage はタブを閉じると消える
  • 保存容量はオリジン単位で約 5MB — Cookie (4KB) より圧倒的に大きい
  • 値は文字列のみ。オブジェクトは JSON.stringify / JSON.parse で扱う
  • 機密情報は保存しない: XSS で簡単に窃取される。JWT 等は Cookie + HttpOnly か Secure Storage 検討

Web Storage API とは

Web Storage API はブラウザに用意されたキー/値ストレージです。JavaScript から手軽にデータを読み書きでき、リロードしても残ります。Cookie より大容量で、サーバーに自動送信されないためクライアント側の状態保存に最適です。

2 つのストレージが用意されており、保持期間とスコープが異なります。

項目localStoragesessionStorage
保持期間永続 (明示削除まで)タブ / ウィンドウを閉じるまで
共有範囲同一オリジンの全タブ同一タブのみ
容量約 5MB約 5MB

Cookie との比較

項目Web StorageCookie
容量約 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.comb.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 と組み合わせるレスポンスキャッシュ
編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. Canvas API
  2. Drag and Drop API
  3. History API
  4. WebStorage API
  5. File API
  6. System Information API

最近更新/作成されたページ