自作のツールでデータの保存先に使ってみて、はじめて存在を知りました。普段は DB やバッチ処理が中心なので、DB にたとえながら整理しておきます。
localStorage とは
ブラウザの中にある、サイトごとの小さな保存領域です。キーと値(どちらも文字列)だけを保存でき、ブラウザを閉じても消えません。
| 項目 | localStorage | DB にたとえると |
|---|---|---|
| データの形 | キーと値(どちらも文字列)。オブジェクトは JSON の文字列にして入れる | 主キーと値の 2 列だけのテーブル |
| 大きさの上限 | サイトごとに約 5〜10MB | 小さな作業用のテーブル |
| 保存期間 | 消すまでずっと残る | 永続的なテーブル |
| 操作 | setItem / getItem / removeItem くらい | INSERT、SELECT、DELETE だけ。SQL もトランザクションもない |
| どこにあるか | 利用者の PC のブラウザの中 | サーバーではなくクライアント側 |
普通のサイトでも使われている
このブログ(WordPress + AdSense)でも見てみたら、自分では何も書いていないのに、Google AdSense が google_ama_config(自動広告の設定、約 3 万文字)などを保存していました。広告やアクセス解析などの外部のスクリプトが、裏で使っていることも多いです。
オリジンごとに分かれている
localStorage はオリジン(スキーム+ホスト+ポート)ごとに完全に分かれています。
https://example.comとhttps://www.google.comは別々の localStorage- ほかのサイトの localStorage は読めない(同一オリジンポリシー)
DB で言えば、スキーマごとに権限が完全に分かれていて、別のスキーマは一切見えない状態です。
Cookie・sessionStorage・IndexedDB との違い
| 仕組み | 特徴 | よくある使い道 |
|---|---|---|
| Cookie | アクセスのたびにサーバーへ自動で送られる。4KB まで。有効期限を付けられる | ログイン状態の維持、アクセス解析 |
| localStorage | サーバーには送られない。消すまで残る | 画面の設定、入力途中の下書き、設定のキャッシュ |
| sessionStorage | localStorage とほぼ同じだが、タブを閉じると消える | そのタブだけの一時的な状態 |
| IndexedDB | インデックスやトランザクションがあり、大量のデータも扱える | オフラインで使えるアプリ |
ざっくり言うと、IndexedDB が「ブラウザの中の DB」、localStorage は「設定ファイルや小さなキャッシュ」くらいの位置づけです。
有効期限はない(でも消えることはある)
localStorage には有効期限がありません。ただし、次のような場面では消えます。
| 場面 | 説明 |
|---|---|
| 閲覧データの削除 | 「Cookie と他のサイトデータ」を削除すると一緒に消える |
| 閉じるときに自動で削除する設定 | Chrome の「すべてのウィンドウを閉じたときにサイトデータを削除する」、Edge の「閉じるときに閲覧データをクリアする」がオンだと、閉じるたびに消える |
| 掃除ソフト | ブラウザのデータを消すものがある |
| シークレットウィンドウ | ウィンドウを閉じると消える |
| PC の買い替え・プロフィールの削除 | ブラウザの同期機能は localStorage を引き継がない |
DB で言えば「TTL はないけれど、バックアップもレプリケーションもなく、利用者が誤って TRUNCATE できるテーブル」です。大事なデータを置くなら、別の場所にバックアップが必要です。
保存場所と中身の見方
実際のファイルの場所
%LOCALAPPDATA%\Google\Chrome\User Data\Default\Local Storage\leveldb\ %LOCALAPPDATA%\Microsoft\Edge\User Data\Default\Local Storage\leveldb\
中身は LevelDB という形式で、ブラウザが管理しています(直接開いて読むものではありません)。
開発者ツールで見る
- 見たいサイトを開いて F12 →「Application(アプリケーション)」→「Storage」→「Local storage」→ サイトのアドレス
コンソールで中身を一覧表示する
F12 →「Console」に貼り付けて実行します。
console.table(Object.keys(localStorage).map(k => ({
key: k,
length: localStorage.getItem(k).length,
value: localStorage.getItem(k).slice(0, 80)
})));
※ Chrome では初めて貼り付けるときに警告が出るので、案内に従って allow pasting と入力してから貼り付けます。
基本の操作
localStorage.setItem('theme', 'dark'); // 保存
localStorage.getItem('theme'); // 読み込み → "dark"
localStorage.removeItem('theme'); // 1 件削除
localStorage.clear(); // このサイトの分を全部削除(注意)
// オブジェクトは JSON にして保存する
localStorage.setItem('user', JSON.stringify({ id: 1, name: 'test' }));
JSON.parse(localStorage.getItem('user'));
注意点
- 平文で保存される。開発者ツールで誰でも見られる
- 同じオリジンのスクリプトなら何でも読める(XSS で読まれる)。パスワードやトークンなどの秘密は入れない
- 容量は約 5〜10MB。大きなデータは IndexedDB へ
- 読み書きは同期処理。大きなデータを何度も読み書きすると画面が止まる
- 保存する形式を変えるときは、キーに版(
app-data-v1など)を付けておくと移行しやすい。DB のテーブル定義の変更と同じ考え方
