💾

ブラウザのデータストレージについてまとめ

2024/01/20に公開

はじめに

Cookie/WebStorage(SessionStorage、LocalStorage)/IndexedDBは、ユーザーの端末(ブラウザ)にデータを保持するためのストレージです。今回はこれらの特徴や用途について改めて理解を深めるべくまとめてみました。
※間違いがあればご指摘ください。

特徴まとめ

Cookie SessionStorage LocalStorage IndexedDB
1.保持できるデータサイズ 約4KB 5MB(ブラウザで異なる) 約5~10MB(ブラウザで異なる) 数十MB〜数百MB以上(ブラウザで異なる)
2.保持できるデータ形式 文字列 文字列 文字列 オブジェクト
3.データの有効期限 設定可能 タブ・ウインドウを閉じるまで 永続的(意図的に消すまで有効) 永続的(意図的に消すまで有効)
4.サーバーへのデータ送信 アクセスするたび自動送信 必要であれば送信可能 必要であれば送信可能 必要であれば送信可能
5.処理の実行方法 同期 同期 同期 非同期
6.用途 セッション管理、トラッキングなど フォームの入力値保持など一時的なデータ保存 ユーザー設定の保存 大容量データや複雑な構造のデータ保持
7.セキュリティ上の脅威 XSS、CSRF XSS XSS XSS

1. 保持できるデータサイズ

ブラウザによって異なりますが、どのブラウザも最低でも1ドメインあたり50個、一つのCookieあたり約4kBまで保持可能です。

2. 保持できるデータ形式

文字列形式(Key=valueの形式)でデータを保持することができます。

document.cookie = 'key1=val1; key2=val2; key3=val3;'

3. データの有効期限

主に Expires 属性と Max-Age 属性を使用して期限を設定し、設定された期間が経過すれば削除されます。なお、両方設定されている場合は Max-Age が優先されます。
どちらの設定もない場合、基本はブラウザを閉じると削除されますが、例外的にブラウザによっては再起動時にセッションの復元を使用することができるため、結果的にCookieが無期限に持続する場合があります。

  • Expires属性
    日時を指定します。設定した日時までCookieが有効になります。
Set-Cookie: name=value; Expires=Thu, 31 Oct 2021 07:28:00 GMT
  • Max-Age属性
    秒数を指定します。保存されてからその秒数経過までCookieが有効になります。
Set-Cookie: name=value; Max-Age=3600

4. サーバーへのデータ送信

サーバーにリクエストするたびにCookieの送信が行われます。ただし、属性の設定内容によって挙動が異なります。

  • SameSite属性
    • Strict
        同一オリジン[1]のみ、リクエストにCookieが付与されて送信されます。
    • Lax
      同一オリジン、別オリジンへのリクエストでもCookieが付与され送信されます。
      ただし、別オリジンへのリクエストの場合、トップレベルナビゲーション[2]かつ、メソッドがGET、HEAD、OPTIONS、TRACEのリクエストのみCookieは付与されます。
      なお、属性が指定されなかった場合、デフォルトでLaxが設定されます。
    • None
      同一オリジン、別オリジンどちらへのリクエストでもCookieが付与され送信されます。ただし、同時にSecure属性を設定しないとCookieは付与されません。
  • Domain属性
    Cookieを受信することができるドメインを指定します。主に複数のサブドメインでCookieを共有したい場合に設定します。
    特に設定しなければデフォルトで現在のドメインのみCookieの受信が可能です(サブドメインは含まない)。
  • Path属性
    特定のパス以下のみでCookieを利用したい場合にそのパスを指定します。

5. 処理の実行方法

Cookieの保存や取得、削除は同期的に実行されます。

6. 用途

セッションIDなどの識別子をCookieに保存して、ユーザーがサイトを訪れるたびに同じセッションにアクセスできるようにします。これにより、ユーザーがログイン状態を維持したり、カートの中の商品を保存したりすることが可能になります。
また、ユーザ行動分析のために、閲覧履歴や滞在時間などの情報の保存にも使用されます。

7. セキュリティ上の脅威

XSSとCSRFの脅威があります。ただし、XSSに関してはスクリプトからcookieにアクセスできないようにするHttp-Only属性を設定することで対策可能です。
また、CSRFについてもSameSite属性をLax以上に設定したり、CSRFトークンを生成してリクエストに含めることで対策が可能です。

SessionStorage

1. 保持できるデータサイズ

最大5MBまで保持できますが、ブラウザやその設定によって異なる場合があります。

2. 保持できるデータ形式

文字列形式(Key=valueの形式)でデータを保持することができます。

3. データの有効期限

ブラウザのタブを閉じたり、ウインドウを閉じるまでデータは保持されます。

4. サーバーへのデータ送信

アクセス時に自動的には送信されないため、送信の要否に開発者が実装する必要があります。

5. 処理の実行方法

データの保存や取得、削除は同期的に実行されます。

6. 用途

一時的な状態の保存などに使われます。
例えば、ページ内で入力されたフォームデータや複数ステップあるページの各ステップの作業状態などほSessionStorageに保持しておけば、ユーザーが誤ってページを離れても復元が可能です。

7. セキュリティ上の脅威

XSSの脅威があるため、保存するデータは適切にエスケープ処理をする必要があります。

LocalStorage

1. 保持できるデータサイズ

5MB~10MB程度まで保持できます。ただし、これもブラウザや設定によって変動する可能性があります。

2. 保持できるデータ形式

文字列形式(Key=valueの形式)でデータを保持することができます。

3. データの有効期限

有効期限はありません。そのため、JavaScriptで意図的に削除するか、ブラウザキャッシュのクリアによってのみ削除されます。

4. サーバーへのデータ送信

アクセス時に自動的には送信されないため、送信の要否に開発者が実装する必要があります。

5. 処理の実行方法

データの保存や取得、削除は同期的に実行されます。

6. 用途

簡単なユーザー設定の保存に利用されます。
例えば、ユーザーが自分好みにページの表示に関する設定(テーマや言語設定など)をした際、サイトを離れても戻ってきた時に設定が反映されるようにLocalStorageに保持したりします。

7. セキュリティ上の脅威

XSSの脅威があるため、保存するデータは適切にエスケープ処理をする必要があります。

IndexedDB

1. 保持できるデータサイズ

数十MB〜数百MB以上のデータを保持できます。ただし、これもブラウザや設定によって変動する可能性があります。

2. 保持できるデータ形式

オブジェクト指向データベースのため、JavaScriptオブジェクトを扱います。オブジェクトで扱えるデータはJavaScriptで扱えるデータと同じです。

const sampleObject = {
  id: 1,
  name: 'John Doe',
  age: 25,
  isStudent: true,
  hobbies: ['reading', 'hiking'],
  birthday: new Date('2000-01-01'),
  binaryData: new Blob(['binary data'], { type: 'text/plain' })
};

データを操作する場合、get(取得)/add(追加)/put(更新)/delete(削除)メソッドを使って行います。

3. データの有効期限

有効期限はありません。そのため、JavaScriptで意図的に削除する必要があります。

4. サーバーへのデータ送信

アクセス時に自動的には送信されないため、送信の要否に開発者が実装する必要があります。

5. 処理の実行方法

データの保存や取得、削除は非同期的に実行されます。なお、Promiseに対応していないため、必要であればライブラリを使って実装します。

6. 用途

大容量のデータや複雑なデータの保持に利用されます。
例えば、オフラインアプリなどクライアントサイドにデータを保持する必要がある場合や、ネストした階層構造のデータを保持したい場合などです。
また、オフライン時の作業内容をオンラインになった時に同期させるなど、リアルタイムにデータを同期させたい場合などにも活用されます。

7. セキュリティ上の脅威

XSSの脅威があるため、保存するデータは適切にエスケープ処理をする必要があります。

参考

https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies
https://developer.mozilla.org/ja/docs/Web/API/Web_Storage_API
https://developer.mozilla.org/ja/docs/Web/API/IndexedDB_API/Using_IndexedDB
https://web.dev/articles/same-site-same-origin?hl=ja
https://hosikiti.hatenadiary.org/entry/20130925/1380098776
https://numb86-tech.hatenablog.com/entry/2020/01/26/112607
https://chancodeblog.com/indexeddb/

脚注
  1. 同じスキーム(https)、ホスト名(aaa.com)、ポート(:431)の組み合わせを持つウェブサイトのこと。 ↩︎

  2. アドレスバーに表示されているURLの変更が伴う遷移 ↩︎

Discussion