Web開発をしているとよく出てくるクッキー(Cookie)、ローカルストレージ(LocalStorage)、キャッシュ(Cache)など、 色々なストレージが出てきます。
どれも「ブラウザに何かを保存する仕組み」ですが、役割や使いどころは大きく異なります。
この記事ではそれぞれの特徴と、具体的な使い分けのポイントを整理します。


クッキー(Cookie)

Cookieとは、主にサーバーとの通信に必要な情報を保存する格納先です。
具体的には、セッションID、ログイン状態、言語設定などが挙げられます。

こうした情報が保存され、ページを移動するたびに自動でサーバーへ送信されます。
そのおかげで、毎回IDやパスワードを入力しなくてもサービスを使い続けられるわけです。


容量はとても小さい

Cookieのサイズはとても小さく、およそ4KB程度が上限です。
例えばChromeではドメインごとに最大180個まで保存できますが、それを超えると古いものから消されます。

なぜそんなに小さいのかというと、 実はCookieはリクエストのたびにヘッダーにまとめて送信されるからです。

GET /page HTTP/1.1
Host: example.com
Cookie: sessionid=abcd1234; theme=dark; lang=ja

画像やCSS、JSファイルのリクエストにも毎回Cookieが付くため、 容量が大きいと無駄な通信が増えてページ表示が遅くなります。
これを「Cookie肥大化問題」と呼び、4KB制限はその対策として生まれた歴史的な妥協点だそうです。


セキュリティ上のポイント

Cookieは便利ですが、設定を誤ると攻撃の入り口になります。
そのため次の3つの属性をセットすることが推奨されます。

  • HttpOnly: JavaScriptから読めなくする(XSS対策)
  • Secure: HTTPS通信のときだけ送信(盗聴防止)
  • SameSite: 他サイトからのリクエストでは送らない(CSRF対策)

これらを組み合わせることで「盗まれない・盗聴されない・勝手に使われない」Cookieにできます。
※XSS, HTTPS, CSRFについてはこの記事では説明を割愛します。


手動への変更方法

テストなどでCookieの値を自分で変えたいときは、ブラウザの開発者ツールから可能です。
Chrome/Edgeなら以下の手順です。

  1. F12キーで開発者ツールを開く
  2. Applicationタブをクリック
  3. 左メニューから Storage → Cookies を選択
  4. Value列を直接編集

ここでDomain属性やPath属性を見ると、Cookieが送られる条件もわかります。

  • DomainとPathが一致するリクエストだけに送られる
  • Secure属性があればHTTPS通信限定
  • HttpOnlyがあればJavaScriptからアクセス不可

ローカルストレージ(LocalStorage)

LocalStorageは、ブラウザの中にあるちょっと大きいストレージです。
サーバーに送る必要のないデータを、ユーザーのPCやスマホにそのまま保存しておけます。

具体的には、入力フォームの下書き、ダークモードやライトモードの設定、サイトの表示状態などです。


容量は大きめ

Cookieが数KBしか保存できないのに対し、LocalStorageは数MBまで保存できます。
一度保存したデータは、ブラウザを閉じても残り続けます。

「消えるのはユーザーが手動で消したときか、ブラウザをリセットしたとき」だけです。


通信は一切なし

Cookieと違って、LocalStorageはサーバーに自動送信されません。
あくまでブラウザ内にだけ保存されるので、無駄な通信を増やさずに済みます。

そのため

  • 認証情報(セッションIDなど)は入れない
  • サーバーに送る必要があるならAPI通信で明示的に送る

といった使い分けが大切です。


どのタイミングで保存されるのか

ブラウザ自身やサーバからの指示でlocalstorageに値が保存されることはありません。   保存は基本的にwebページ上のJavaScriptのコードが行います。

localStorage.setItem("theme", "dark");

このように Webサイトが「保存して」と指示したとき にだけ LocalStorage に書き込まれます。
つまり、サーバーがレスポンスヘッダーを返して勝手に Cookie を保存させる仕組みとは異なり、LocalStorage は 開発者がフロントエンドで明示的にコードを書く必要があるのです。

LocalStorage はブラウザごとに「数MB程度」という上限があります(正確な値はブラウザ依存)。

もし上限を超えて setItem() しようとすると、古いデータが自動で消えることはありませんが、 代わりに例外エラー(QuotaExceededError)が発生します。

try {
  localStorage.setItem("bigdata", "x".repeat(10 * 1024 * 1024)); // 10MB
} catch (e) {
  console.error("保存に失敗しました: ", e);
}

セキュリティ上の注意

LocalStorageはJavaScriptから簡単に読めます。
ということは、もしXSS攻撃(悪意あるスクリプトの埋め込み)を受けると、中身を盗まれる可能性があります。

そのため

  • パスワードやセッションIDは保存しない
  • 保存するのはテーマ設定や一時的なUIデータなど、盗まれても問題ない情報

と割り切ることが大切です。

また、cookieと同じように開発者モードでどの情報が保存されているのかを確認できます。


キャッシュ(Cache)

最後に、キャッシュとは、一度読んだファイルをとっておいて、 次回からわざわざサーバーに行かなくても手元でパッと読めるようにする仕組みです。

具体的には

  • 画像
  • CSS(デザインファイル)
  • JavaScript(動きをつけるプログラム)
  • HTML のコピー

こうしたファイルがキャッシュとして保存され、次に同じページを開いたときに素早く表示できるようになります。

容量はとても大きい

Cookie が数KB、LocalStorage が数MBだったのに対し、Cache は数百MB〜GB 単位で使えます。
動画や大量の画像を含むサイトでも高速に再表示できるのはこの仕組みのおかげです。


有効期限はサーバーが決める

キャッシュは永遠に残るわけではありません。
保存期間はサーバーがレスポンスヘッダーで指定します。

代表的なものは以下のとおりです。

  • Cache-Control: キャッシュしてよい時間や条件
  • ETag: キャッシュ内容が最新かどうかを確認するための目印

また、キャッシュの有効期限はサーバが決めることから、ブラウザを再起動させても基本的に削除されません。 とはいえ、キャッシュの容量も無限ではないので、自動的に古いキャッシュから削除することもあります。


セキュリティ上の注意

キャッシュはあくまで「表示を速くするためのコピー置き場」です。
認証やユーザー固有のデータを保存する場所ではありません。

例えばログイン状態やセッションIDをキャッシュに入れてしまうと、他人に見られるリスクや更新されないまま残る問題が出ます。
そのため、機密性の高い情報はキャッシュさせないようにサーバーで制御します。


開発時の注意

開発中に「変更したのに画面が更新されない」という経験はよくあります。
これは古いファイルがキャッシュに残っているのが原因です。
その場合は以下のように対応します。

  • ブラウザで「キャッシュを無効化」してリロード(Shift + 更新ボタンなど)
  • 開発者ツールの Network タブで「Disable cache」をオンにする
  • ファイル名にバージョン番号を付ける(例: style.css?v=2

まとめ表

項目 クッキー ローカルストレージ キャッシュ
主な用途 サーバーとの認証・設定 ブラウザ内データの保持 ページ高速化
サーバー送信 自動で送信される 送信されない 送信されない
サイズ 数KB 数MB 数百MB〜
有効期限 設定された期限まで 手動で消すまで残る サーバー/ブラウザ依存
セキュリティ性 HttpOnlyで強化可能 JSから読める(脆弱) 認証には使わない

まとめ

クッキー、ローカルストレージ、キャッシュはすべてブラウザにデータを保存する仕組みですが、
それぞれ役割や使いどころは大きく異なります。

  • クッキー: サーバーとの認証や設定
  • ローカルストレージ: ブラウザだけで保持するデータ
  • キャッシュ: ページ表示を速くするためのコピー

3つの違いを正しく理解しておくことで、セキュリティを守りつつ快適なWeb体験を提供できるようになります。