はじめに:実務でこんな困りごとはありませんか?
Webアプリケーション開発の現場では、こんな問題に直面することがよくあります。
- 「ローカルストレージに保存したはずのデータが消えている…」
- 「Cookieが正しく設定されているか確認したい」
- 「ログアウトしてもユーザーデータが残っている」
- 「テスト用に、手動でストレージのデータを編集したい」
- 「認証トークンのセキュリティ属性を確認したい」
- 「容量制限エラーが出るが、原因が分からない」
これらの問題を解決する鍵が、Chromeデベロッパーツールのアプリケーションタブです。
この記事では、アプリケーションタブの具体的な使い方と、実務でのデバッグ・トラブルシューティング方法を詳しく解説します。
※この記事は実践編です。ストレージの基礎から学びたい方は、まず【基礎編】Chromeデベロッパーツールのアプリケーションタブとは?をご覧ください。
アプリケーションタブの開き方
開く方法
- デベロッパーツールを開く(
F12またはCtrl + Shift + I/Cmd + Option + I) - 上部タブに「アプリケーション」があればクリック
- なければ「>>」をクリックして「アプリケーション」を選択
アプリケーションタブの画面構成
アプリケーションタブを開くと、左側にサイドバーが表示されます。
| セクション | 内容 |
|---|---|
| マニフェスト | PWAのマニフェストファイル |
| Service Workers | 登録されているService Worker |
| ストレージ | ローカルストレージ、セッションストレージ、IndexedDB、Cookie |
| バックグランドサービス | プッシュ通知、バックグラウンド同期など |
| フレーム | iframeの情報 |
ローカルストレージ / セッションストレージの確認・編集・削除
確認方法
- アプリケーションタブを開く
- 左サイドバーの「ストレージ」を展開
- 「ローカルストレージ」または「セッションストレージ」を展開
- ドメイン名をクリック(例:
https://example.com) - 右側にKey-Value形式でデータが表示される
表示内容:
| 列 | 内容 |
|---|---|
| キー | データのキー名 |
| 値 | 保存されているデータ |
データの検索
上部にあるフィルター入力欄に文字列を入力すると、キーまたは値に含まれるデータのみ表示されます。
例:フィルターに「user」と入力
→ user_name、user_email、current_user などが表示される
データの編集
既存データの編集:
- 編集したいデータの値欄をダブルクリック
- 新しい値を入力
Enterキーを押して確定
新規データの追加:
- テーブルの最下部の空白行をダブルクリック
- キー と 値 を入力
Enterキーを押して確定
データの削除
個別削除:
- 削除したいデータを選択
- 右クリック → 「削除」
全削除:
- ドメインを右クリック → 「削除」
- または、上部の🚫(禁止マーク)アイコンをクリック
注意: 「全削除」は元に戻せないので、注意してください。
実践例:ユーザー設定の確認
// JavaScriptでローカルストレージにユーザー設定を保存
localStorage.setItem('theme', 'dark');
localStorage.setItem('language', 'ja');
localStorage.setItem('fontSize', '16');
// アプリケーションタブで確認
// ローカルストレージ → https://example.com
// キー: theme, 値: dark
// キー: language, 値: ja
// キー: fontSize, 値: 16
Cookieの確認・編集・削除
確認方法
- アプリケーションタブを開く
- 左サイドバーの「ストレージ」→「Cookie」を展開
- ドメイン名をクリック
- 右側にCookieの一覧が表示される
表示される列:
| 列 | 内容 | 重要度 |
|---|---|---|
| 名前 | Cookieの名前 | – |
| 値 | Cookieの値 | – |
| Domain | 有効なドメイン | 中 |
| Path | 有効なパス | 中 |
| Expires / Max-Age | 有効期限 | 低 |
| サイズ | サイズ(バイト) | 低 |
| HttpOnly | JavaScriptからアクセス不可 | 非常に高 |
| Secure | HTTPS通信のみ | 非常に高 |
| SameSite | クロスサイトでの送信制御 | 非常に高 |
| Partition Key | パーティション化されたCookie | 中 |
| Priority | 優先度(Low / Medium / High) | 低 |
Cookie属性の見方(セキュリティ重要)
HttpOnly 列:
- ✓(チェックあり) = JavaScriptからアクセス不可(セキュア) ← 認証Cookieは必須!
- 空白 = JavaScriptからアクセス可能(XSS脆弱) ← 危険!
Secure 列:
- ✓(チェックあり) = HTTPS通信のみ(セキュア) ← 本番環境では必須!
- 空白 = HTTP通信でも送信(盗聴リスク) ← 危険!
SameSite 列:
- Strict = クロスサイトリクエストで送信されない(最もセキュア)
- Lax = トップレベルナビゲーションのみ送信(バランス型、推奨)
- None = クロスサイトでも送信(Secure必須、注意が必要)
- 空白 = ブラウザのデフォルト(Lax相当)
Cookieの編集
- 編集したいCookieの値欄をダブルクリック
- 新しい値を入力
Enterキーを押して確定
注意: HttpOnly、Secure、SameSite などの属性は、アプリケーションタブから編集できません。これらはサーバー側で設定する必要があります。
Cookieの削除
個別削除:
- 削除したいCookieを選択
- 右クリック → 「削除」
全削除:
- ドメインを右クリック → 「削除」
- または、上部のフィルターの右側にある3本線と×が書かれているアイコンをクリック
実践例:認証Cookieのセキュリティ確認
// セキュアなCookieの設定例
// Name: sessionId
// Value: abc123...
// HttpOnly: ✓ ← 必ずチェックがあること!
// Secure: ✓ ← 必ずチェックがあること!
// SameSite: Lax または Strict ← 設定されていること!
// ✅ 良い例:上記のようにすべての属性が設定されている
// ❌ 悪い例:HttpOnly や Secure にチェックがない
// → XSS攻撃や盗聴のリスク!
IndexedDBの確認
確認方法
- アプリケーションタブを開く
- 左サイドバーの「ストレージ」→「IndexedDB」を展開
- データベース名を展開
- オブジェクトストア名をクリック
- 右側にデータが表示される
表示内容:
| 列 | 内容 |
|---|---|
| キー | プライマリキー |
| 値 | 保存されているオブジェクト(展開可能) |
データの確認
- データ行をクリック
- 下部に詳細が表示される
- オブジェクトの中身を展開して確認できる
データの削除
個別レコードの削除:
- 削除したいレコードを選択
- 右クリック → 「削除」
オブジェクトストア全体の削除:
- オブジェクトストア名を右クリック
- 「削除」を選択
データベース全体の削除:
- データベース名をクリック
- 「データベースを削除」を選択
Service Workerの確認
確認方法
- アプリケーションタブを開く
- 左サイドバーの「Service Workers」をクリック
- 登録されているService Workerが表示される
表示される情報:
| 項目 | 内容 |
|---|---|
| ソース | Service Workerのファイルパス |
| ステータス | activated、installing、waiting など |
| クライアント | Service Workerを使用しているページ数 |
操作
Unregister(登録解除):
- Service Workerを削除したい時にクリック
Update:
- Service Workerを強制的に更新
Skip waiting:
- 待機中のService Workerをすぐにアクティブ化
Offline(オフラインモード):
- チェックを入れると、ネットワークを切断した状態をシミュレート
- PWAのオフライン動作をテストできる
キャッシュストレージの確認
確認方法
- アプリケーションタブを開く
- 左サイドバーの「キャッシュストレージ」を展開
- キャッシュ名をクリック
- キャッシュされているリソースの一覧が表示される
キャッシュの削除
個別削除:
- 削除したいリソースを選択
- 右クリック → 「削除」
キャッシュ全体の削除:
- キャッシュ名を右クリック
- 「削除」を選択
実務でのデバッグ事例
事例1:ローカルストレージが保存されない
症状:
localStorage.setItem()を実行しても、データが保存されない- コンソールにエラーが出る場合と出ない場合がある
原因1:容量制限オーバー
ローカルストレージの容量制限(約5〜10MB)を超えると、エラーが発生します。
// エラー例
QuotaExceededError: Failed to execute 'setItem' on 'Storage':
Setting the value of 'largeData' exceeded the quota.
確認方法:
- アプリケーションタブ → ローカルストレージ → ドメインを選択
- 保存されているデータの総量を確認
- 不要なデータがないか確認
解決方法:
- 不要なデータを削除:
localStorage.removeItem('key') - データを圧縮して保存
- 大量データの場合は IndexedDB を検討
原因2:プライベートブラウジングモード
シークレットモード(プライベートブラウジング)では、ローカルストレージが使えない、または制限される場合があります。
確認方法:
// ローカルストレージが使えるかチェック
try {
localStorage.setItem('test', 'test');
localStorage.removeItem('test');
console.log('localStorage 使用可能');
} catch (e) {
console.error('localStorage 使用不可:', e);
}
解決方法:
- 通常モードで開く
- または、セッションストレージを使用
- または、Cookie を使用
事例2:Cookieが送信されない
症状:
- ブラウザにはCookieが保存されているのに、サーバーに送信されない
- ネットワークタブで確認すると、リクエストヘッダーに Cookieがない
原因1:SameSite属性の問題
SameSite属性が適切に設定されていないと、クロスサイトリクエストでCookieが送信されません。
確認方法:
- アプリケーションタブ → Cookie → ドメインを選択
- SameSite列を確認
- Network タブで、リクエストがクロスサイトかどうか確認
問題のパターン:
// フロントエンド: http://localhost:3000
// バックエンド: http://localhost:8000
// このような場合、クロスサイトリクエストになる
// SameSite=Strict だと Cookie が送信されない
解決方法:
// サーバー側で SameSite=None; Secure を設定
Set-Cookie: sessionId=abc123; SameSite=None; Secure
// または、Same-Siteにする(推奨)
// フロントエンド・バックエンドを同じドメインに配置
// 例:example.com/app(フロント)と example.com/api(バック)
原因2:Domain属性の問題
Cookie の Domain 属性が正しく設定されていないと、送信されません。
確認方法:
- アプリケーションタブ → Cookie
- Domain列を確認
- 現在のページのドメインと一致しているか確認
例:
// Cookie の Domain: .example.com
// 現在のページ: https://example.com → ✅ 送信される
// 現在のページ: https://sub.example.com → ✅ 送信される
// 現在のページ: https://other.com → ❌ 送信されない
事例3:ログアウトしてもデータが残る
症状:
- ログアウトボタンをクリックしても、ユーザーデータが残っている
- 再ログインすると、前回のデータが表示される
原因:ローカルストレージのクリア漏れ
ログアウト処理で、Cookieは削除しているが、ローカルストレージを削除し忘れているケースがよくあります。
確認方法:
- ログアウト後、アプリケーションタブ → ローカルストレージ を確認
- ユーザーデータが残っていないか確認
解決方法:
// ログアウト処理の改善
function logout() {
// 1. サーバー側のセッションを削除(API呼び出し)
fetch('/api/logout', { method: 'POST' });
// 2. Cookie を削除(サーバー側で削除されるが、念のため)
document.cookie = 'sessionId=; Max-Age=0; path=/';
// 3. ローカルストレージ をすべて削除
localStorage.clear();
// 4. セッションストレージもクリア
sessionStorage.clear();
// 5. ログインページにリダイレクト
window.location.href = '/login';
}
部分的に削除する場合:
// 認証関連のデータだけ削除したい場合
function logout() {
// 特定のキーだけ削除
localStorage.removeItem('authToken');
localStorage.removeItem('userId');
localStorage.removeItem('userEmail');
// テーマ設定などは残したい場合、上記のように個別削除
}
よくあるハマりポイントと対処法
ハマりポイント1:同じドメインでもポートが違うと別扱い
症状:
localhost:3000で保存したデータが、localhost:8080で見えない
原因: ストレージはオリジン(スキーム + ホスト + ポート)ごとに独立している
オリジンの例:
http://localhost:3000 ← 別オリジン
http://localhost:8080 ← 別オリジン
https://example.com ← 別オリジン
https://example.com:443 ← 実質同じ(デフォルトポート)
https://sub.example.com ← 別オリジン
対処法:
- 開発時は、フロントエンドとバックエンドを同じポートで動かす
- または、プロキシを使って同じオリジンに見せかける
// Vite の場合(vite.config.js)
export default {
server: {
port: 3000,
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
}
}
ハマりポイント2:プライベートブラウジングモードでの制限
症状:
- シークレットモード(プライベートブラウジング)で、ローカルストレージが使えない
- または、容量制限が非常に小さい
原因: プライバシー保護のため、ストレージが制限される
対処法:
// ローカルストレージ が使えるかチェックして、使えない場合の代替処理
function saveData(key, value) {
try {
localStorage.setItem(key, value);
return true;
} catch (e) {
console.warn('localStorage使用不可。sessionStorageを使用します。');
try {
sessionStorage.setItem(key, value);
return true;
} catch (e2) {
console.error('ストレージが使えません:', e2);
// メモリ内に保存するなど、代替手段を用意
return false;
}
}
}
ハマりポイント3:容量制限
症状:
- 「QuotaExceededError」が発生
- データが保存されない
各ストレージの容量制限:
| ストレージ | 容量制限(Chrome) |
|---|---|
| Cookie | 約4KB(1つあたり) |
| ローカルストレージ | 約5〜10MB |
| セッションストレージ | 約5〜10MB |
| IndexedDB | 制限なし(ディスク容量の範囲内) |
対処法:
- 不要なデータを削除
- データを圧縮(LZ-stringなどのライブラリ使用)
- 大量データはIndexedDBを使用
// データ圧縮の例(LZ-string使用)
import LZString from 'lz-string';
// 保存時:圧縮
const data = { /* 大きなオブジェクト */ };
const compressed = LZString.compress(JSON.stringify(data));
localStorage.setItem('largeData', compressed);
// 取得時:解凍
const retrieved = localStorage.getItem('largeData');
const decompressed = JSON.parse(LZString.decompress(retrieved));
ハマりポイント4:JSON化を忘れる
症状:
- オブジェクトを保存したのに、取り出すと
[object Object]になる
原因: ローカルストレージ は文字列しか保存できない
// 悪い例
const user = { name: '太郎', age: 28 };
localStorage.setItem('user', user); // [object Object] として保存される
const retrieved = localStorage.getItem('user');
console.log(retrieved); // "[object Object]" という文字列
正しい例:
// 保存時:JSON化
const user = { name: '太郎', age: 28 };
localStorage.setItem('user', JSON.stringify(user));
// 取得時:パース
const retrieved = JSON.parse(localStorage.getItem('user'));
console.log(retrieved.name); // "太郎"
ヘルパー関数を作る(推奨):
// ローカルストレージ のラッパー関数
const storage = {
set(key, value) {
try {
localStorage.setItem(key, JSON.stringify(value));
} catch (e) {
console.error('保存エラー:', e);
}
},
get(key, defaultValue = null) {
try {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : defaultValue;
} catch (e) {
console.error('取得エラー:', e);
return defaultValue;
}
},
remove(key) {
localStorage.removeItem(key);
},
clear() {
localStorage.clear();
}
};
// 使用例
storage.set('user', { name: '太郎', age: 28 });
const user = storage.get('user'); // オブジェクトとして取得
セキュリティチェックポイント
実務で必ず確認すべきセキュリティチェックリストです。
Cookie のセキュリティチェック
| チェック項目 | 確認方法 | 期待値 |
|---|---|---|
| □ 認証Cookieに HttpOnly が設定されているか | アプリケーション → Cookie → HttpOnly列 | ✓(チェックあり) |
| □ 認証Cookieに Secure が設定されているか | アプリケーション → Cookie → Secure列 | ✓(本番環境では必須) |
| □ 認証Cookieに SameSite が設定されているか | アプリケーション → Cookie → SameSite列 | Strict または Lax |
| □ Cookie の有効期限は適切か | アプリケーション → Cookie → Expires列 | 長すぎない(推奨:数時間〜数日) |
| □ 不要な Cookie がないか | アプリケーション → Cookie → 一覧確認 | 使っていないCookieは削除 |
ローカルストレージのセキュリティチェック
| チェック項目 | 確認方法 | 期待値 |
|---|---|---|
| □ 認証トークンを ローカルストレージに保存していないか | アプリケーション → ローカルストレージ | token、jwt、auth などのキーがない |
| □ パスワードをローカルストレージに保存していないか | アプリケーション → ローカルストレージ | password キーがない |
| □ 個人情報(クレカ番号など)を保存していないか | アプリケーション → ローカルストレージ | 機密情報がない |
| □ 平文で保存していないか(必要なら暗号化) | アプリケーション → ローカルストレージ → Value確認 | 機密データは暗号化 |
セキュリティベストプラクティス
| データの種類 | 保存場所 | 設定 |
|---|---|---|
| 認証トークン(JWT) | Cookie | HttpOnly, Secure, SameSite=Strict |
| セッションID | Cookie | HttpOnly, Secure, SameSite=Lax |
| CSRFトークン | Cookie または ローカルストレージ | – |
| ユーザー設定(テーマなど) | ローカルストレージ | – |
| フォームの下書き | ローカルストレージ またはセッションストレージ | 機密情報は含めない |
重要: 認証トークンを ローカルストレージに保存すると、XSS攻撃で簡単に盗まれます。必ず HttpOnly Cookie に保存してください。
便利な機能・Tips
すべてのストレージを一括削除
テスト時に、すべてのストレージをまとめて削除したい場合:
- アプリケーションタブを開く
- 左サイドバーの「ストレージ」セクションをクリック
- 削除する項目にチェックを入れる
- Cookie
- ローカルストレージ と セッションストレージ
- IndexedDB
- キャッシュストレージ
- 「サイトデータを消去」ボタンをクリック
注意: この操作は元に戻せません。本番環境では慎重に使用してください。
ストレージの使用量を確認
- アプリケーションタブを開く
- 左サイドバーの「ストレージ」をクリック
- 右側に円グラフで使用量が表示される
各ストレージがどれだけ容量を使っているか、一目で分かります。
コンソールからストレージを操作
Consoleタブから、JavaScriptでストレージを直接操作できます。
// ローカルストレージ の全キーを表示
Object.keys(localStorage);
// ローカルストレージ の全データを表示
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
console.log(key, localStorage.getItem(key));
}
// Cookie の全データを表示
document.cookie;
// Cookie を設定
document.cookie = 'testCookie=testValue; path=/';
まとめ:アプリケーションタブを使いこなすための重要ポイント
基本操作の復習
- ✅ ローカルストレージ / セッションストレージ: ストレージ → ローカルストレージ/セッションストレージ → ドメイン選択
- ✅ Cookie: ストレージ → Cookie → ドメイン選択
- ✅ IndexedDB: ストレージ → IndexedDB → データベース → オブジェクトストア
- ✅ 編集: 値欄をダブルクリック
- ✅ 削除: 右クリック → 削除
- ✅ 全削除: ドメインを右クリック → 削除
セキュリティチェックの鉄則
- 認証トークンは ローカルストレージ に保存しない → Cookie(HttpOnly、Secure、SameSite)
- Cookie の属性を必ず確認 → HttpOnly、Secure、SameSite
- 機密情報を平文で保存しない → 必要なら暗号化
- 不要なデータは削除 → ログアウト時に localStorage.clear()
- XSS対策 → 入力値のサニタイズ、CSP設定
トラブルシューティングの流れ
1. 症状の確認
↓
アプリケーションタブでストレージの状態を確認
2. 原因の特定
↓
- データが保存されているか?
- Cookie の属性は正しいか?
- 容量制限に達していないか?
- オリジンは正しいか?
3. 修正
↓
適切なストレージと設定を使用
4. 検証
↓
再度 アプリケーションタブで確認
次のステップ
アプリケーションタブを使いこなせるようになったら、次は以下のツールも学んでみましょう:
- ネットワークタブ: Cookieがリクエストに含まれているか確認
- セキュリティタブ: HTTPS、証明書の確認
- Lighthouse: PWA、セキュリティの総合評価
これらを組み合わせることで、より安全で快適なWebアプリケーションを作れます。
参考資料:
- Chrome DevTools – Application panel overview(公式ドキュメント)
- MDN – Web Storage API の使用
- OWASP – Testing Browser Storage
- MDN – HTTP Cookie の使用
この記事が役に立ったら、ぜひ実際の開発で活用してみてください!
アプリケーションタブを使いこなすことで、ストレージ関連のデバッグやセキュリティ確認が劇的に効率化されます。特に、Cookie のセキュリティ属性(HttpOnly、Secure、SameSite)の確認は、本番環境でも必ず行いましょう。
困ったときは、この記事を見返して、チェックリストを順番に確認してみてください。安全で快適なWebアプリケーションを作りましょう!









