【JavaScript】localStorageとsessionStorageの違いと使い分け|保存期間・スコープ・storageイベント・Cookie比較まで

【JavaScript】localStorageとsessionStorageの違いと使い分け JavaScript

ブラウザにデータを保存する localStoragesessionStorage は、どちらも同じ Web Storage API で操作方法もほぼ同じです。違いは保存期間とスコープ(どこまでデータが共有されるか)、そしてstorage イベントの挙動にあります。この記事では両者の違いと、何をどちらに保存すべきかの判断基準を整理します。

この記事でわかること

  • 共通のAPIと、文字列しか保存できない点(JSON)
  • 保存期間・スコープの違いと比較表
  • storage イベントの発火差(タブ間同期の可否)
  • Cookie・IndexedDB を含めた保存先の使い分け
  • どちらに何を保存すべきかの判断ガイド
結論:閉じても残したいデータ(設定・テーマ・状態)は localStorageそのタブ・その訪問だけでよいデータ(入力途中・確認画面)は sessionStorage。タブ間で同期したいなら localStoragestorage イベント、サーバーにも送りたいなら Cookie を選びます。
スポンサーリンク

共通点:操作方法は同じ(Web Storage API)

どちらも setItem / getItem / removeItem / clear の同じメソッドで操作します。getItem はキーが無ければ null を返します。

JavaScript:共通の操作(localStorage / sessionStorage 共通)
// localStorage の例
localStorage.setItem("theme", "dark");
const theme = localStorage.getItem("theme"); // 無ければ null
localStorage.removeItem("theme");
localStorage.clear(); // 全削除

// sessionStorage もまったく同じメソッド
sessionStorage.setItem("draft", "入力中の内容");
const draft = sessionStorage.getItem("draft");
保存できるのは「文字列」だけ
どちらも値は文字列のみです。オブジェクトや配列をそのまま渡すと "[object Object]" のような文字列に変換されてしまいます。JSON.stringify で保存し、JSON.parse で戻します。
JavaScript:オブジェクトは JSON にして保存
const user = { name: "佐藤", theme: "dark" };

// 保存:文字列化する
localStorage.setItem("user", JSON.stringify(user));

// 取得:パースして戻す(無ければ {} にフォールバック)
const saved = JSON.parse(localStorage.getItem("user") || "{}");

localStorage:閉じても残る(永続)

localStorage はブラウザを閉じても残り、明示的に削除するまで保持されます。同一オリジンなら、別タブからも同じデータを参照できます。ユーザー設定・テーマカラー・「次回から表示しない」状態などの保存に向いています。

sessionStorage:タブを閉じるまで(一時的)

sessionStorage はそのタブを閉じると消えます。新しいタブやウィンドウは別セッションとみなされ、データは共有されません。リロードでは保持され、入力途中の一時保存や確認画面用の値に向いています。

タブ複製・リロードの挙動
sessionStorageリロードでは残りますが、新しいタブには引き継がれません(タブを複製した場合は複製時点の内容がコピーされることがあります)。「このタブのこの訪問だけ」というスコープだと考えると分かりやすいです。

違いの比較表

項目 localStorage sessionStorage
有効期限 明示的に削除するまで永続 タブ/ウィンドウを閉じるまで
スコープ 同一オリジンの全タブで共有 そのタブ内だけ
storage イベント 他タブで発火する 他タブへ伝播しない
容量の目安 約5MB 約5MB
サーバー送信 されない されない
主な用途 設定・テーマ・状態の永続 入力途中・確認画面の一時データ

最大の実用差:storage イベント(タブ間同期)

見落とされがちですが、両者の重要な違いが storage イベントです。localStorage の変更は、同じオリジンの他のタブstorage イベントを発火します。これを使えば、片方のタブでのテーマ変更を他のタブへ即時反映できます。sessionStorage はタブをまたがないため、この方法でのタブ間同期はできません。

JavaScript:他タブの変更を受け取る(localStorage)
// 別タブで localStorage が変わると発火(変更した自分のタブでは発火しない)
window.addEventListener("storage", (e) => {
  if (e.key === "theme") {
    console.log("他タブでテーマが変更されました:", e.newValue);
    applyTheme(e.newValue);
  }
});
localStorageの実装を深掘りするなら
JSON保存・有効期限付きキャッシュ・容量例外処理・storage イベントでのタブ間通信の実装例はlocalStorageの使い方完全ガイドに詳しくまとめています。入力内容の一時保存・復元(sessionStorage 的な用途)はフォーム入力内容をローカルストレージに保存する方法も参考になります。

Cookie・IndexedDB との使い分け

ブラウザの保存先は Web Storage だけではありません。サーバーにも送りたいなら Cookie、大量・構造化データやオフライン対応なら IndexedDB が向きます。

保存先 容量の目安 期限 サーバー送信 向く用途
localStorage 約5MB 永続 されない 設定・状態の永続
sessionStorage 約5MB タブを閉じるまで されない 一時データ
Cookie 約4KB 期限を指定 毎回される 認証トークン・サーバー連携
IndexedDB 大容量 永続 されない 大量/構造化データ・オフライン

Cookieは毎回のリクエストに自動で付くため、サーバー側で読みたい値(ログイン状態など)に向きます。ただし容量が小さく、送信のたびに通信量が増える点に注意します。Cookieの具体的な操作はCookie の取得・設定・削除の方法を参照してください。

どちらに保存すべきか:判断ガイド

  • 閉じても残したい(テーマ・設定・既読状態)→ localStorage
  • このタブの今だけ(入力途中・ウィザードの一時値)→ sessionStorage
  • 複数タブで同期したいlocalStoragestorage イベント
  • サーバーでも読みたい(認証)→ Cookie
  • 大量・構造化データ/オフライン → IndexedDB

セキュリティと容量の注意

機密情報は保存しない
localStorage / sessionStorage は暗号化されておらず、JavaScriptから誰でも読めます。XSSの脆弱性があるとトークンや個人情報を盗まれるため、パスワード・認証トークン・個人情報は保存しないでください。また容量(約5MB)を超えると QuotaExceededError が発生するため、大きなデータを扱うときは try / catch で例外を処理します。

よくある質問(FAQ)

QlocalStorageとsessionStorageの主な違いは?
A保存期間とスコープです。localStorage はブラウザを閉じても永続し、同一オリジンの全タブで共有されます。sessionStorage はそのタブを閉じると消え、他のタブとは共有されません。
Qオブジェクトや配列は保存できますか?
Aそのままでは保存できません。値は文字列のみのため、JSON.stringify で文字列化して保存し、取り出すときに JSON.parse で戻します。
Q複数タブでデータを同期するには?
AlocalStorage を使い、window.addEventListener("storage", ...) で他タブの変更を受け取ります。sessionStorage はタブをまたがないため、この方法では同期できません。
QCookieとはどう使い分けますか?
ACookieは毎回のリクエストでサーバーに自動送信されるため、認証トークンなどサーバー側で読みたい値に向きます。容量は約4KBと小さめです。サーバーに送る必要がないクライアント専用データは Web Storage が適しています。
Q安全に使うための注意点は?
A暗号化されないため機密情報・パスワードは保存しないでください(XSSで読まれる恐れがあります)。容量超過時は QuotaExceededError が発生するので try / catch で処理します。

まとめ

  • 操作は共通setItem/getItem。値は文字列のみ(オブジェクトはJSON)
  • localStorage:永続・全タブ共有・storage イベントが他タブで発火
  • sessionStorage:タブを閉じるまで・そのタブ限定
  • Cookie:サーバー送信あり・約4KB。IndexedDB:大容量・構造化
  • 機密情報は保存しない。容量超過は QuotaExceededError を処理

保存期間・スコープ・タブ間同期の必要性で選べば、用途に合った安全な保存先を選択できます。