CookieとLocalStorageについて調べて比較した【JavaScript】

# この記事は？
## 主な内容
- Cookieとは何か？
- LocalStorageとは何か？
- CookieとLocalStorageをJavaScriptで操作する方法
- CookieとLocalStorageの違いは何か？

# Cookie
## Cookieとは？
> HTTP Cookie (ウェブ Cookie、ブラウザー Cookie) は、サーバーがユーザーのウェブブラウザーに送信する小さなデータであり、ブラウザーに保存され、その後のリクエストと共に同じサーバーへ返送されます。一般的には、 2 つのリクエストが同じブラウザーから送信されたものであるかを知るために使用されます。例えば、ユーザーのログイン状態を維持することができます。 Cookie は、ステートレスな HTTP プロトコルのためにステートフルな情報を記憶します。

**＜[HTTP Cookie の使用 / MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies)より＞**

主に、サイトのログイン機能やユーザ設定の実現、ユーザの行動の記録および分析等で使用されているようです。

### 特徴
- `key`と`value`のセットでデータを保存
- ブラウザ内に保存される
- 保存できるのは文字列のみ
  - 配列やオブジェクト等を保存・取得したい場合は、変換が必要 
- 有効期限は任意に設定可能
- 保存容量は4KB
- サーバへのデータ通信はリクエスト毎に行われる

## Cookieの確認方法
Cookieに格納されているデータは、下記の手順でブラウザから確認することができます。
**開発者ツールを開く -> `アプリケーション` -> `ストレージ` -> `Cookies`**
※Chromeの場合
![Screenshot 2023-01-31 at 22.43.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2543440/7068a56e-7a4a-a3c5-88a6-558e0d668903.png)

## Cookieの操作方法
JavaScriptでCookieを操作するには、`Document`の`cookie`プロパティを使用します。

### データを書き込む
- `key=value`の形で書き込む
- 更新時も同様
- `key=value`の後ろに`;`（セミコロン）で区切り、オプションを設定することが可能
  |オプション（属性）|例 / 概要|
  |:---|:---|
  |`path=Cookieへアクセス可能なpath;` |https://○○.com/hoge というURLであれば`/hoge`の部分|
  |`domain=Cookie へアクセス可能なドメイン;`|hoge.com、.hoge.com(全てのサブドメインを含む)、subdomain.hoge.com|
  |`max-age=寿命（秒）;`||
  |`expires=日付（GMTタイムゾーン形式）;`| _Mon, 02 Feb 2023 09:15:37 GMT_|
  |`secure;`|HTTPS通信の場合のみCookieを送信する|
  |`httponly;`|JavaScriptでのアクセスができないようにする|
  |`samesite=右記のいずれか;`|`strict` / `lax` / `none`で、Cookieを送信するかどうかのコントロールをする|
  |`sameparty;`|サードパーティクッキーの制限を緩和する|
  |`priority=右記のいずれか;`| `high` / `medium` / `low`で、保持優先度を設定する|

```javascript
 // keyがhogeでvalueがhoge
 document.cookie = "hoge=fuga";

 // hogeのvalueを更新
 document.cookie = "hoge=piyo";

 // オプションで有効期限を3600秒（1時間）後に設定
 document.cookie = "hoge=fuga; max-age=3600";
```
`max-age`や`expires`で有効期限を設定しない場合は、**ブラウザ（セッション）の終了**が期限となります。

### データを読み込む
- `key=value`の文字列で読み込みができる
- 複数のCookieが設定されている場合は、すべてのCookieを各`key=value`が`;`で区切られた状態で取得する
    - 個々の`key`と`value`を取得するためには、`split()`を使用して分割する必要がある
```javascript
 // Cookieが3つ書き込まれている場合
 allCookies = document.cookie;
 allCookies; // 'hoge=fuga; piyo=hogehoge; fugafuga=piyopiyo;'
```

### データを削除する
- Cookieを削除する方法は2つ
    - `max-age（寿命）`を**0**にする
    - `expires（有効期限）`を**過去**にする
```javascript
  // 削除したいCookieのkeyがhoge
  document.cookie = "hoge=; max-age=0";
  document.cookie = "hoge=; expires=過去の日付";
```


### ちなみに
[js-cookie](https://github.com/js-cookie/js-cookie)というJavaScriptAPIを使用することで、以下のように記述し、Cookieを操作できます。

```javascript
 // 書き込み
 Cookies.set('hoge', 'fuga');

 // オプションexpires付きで書き込み（この場合、単位は日数）
 Cookies.set('hoge', 'fuga' {expires: 5});

 // 読み込み
 hoge = Cookies.get('hoge');
 hoge; // 'fuga'
 allCookies = Cookies.get();
 allCookies; // {hoge: 'fuga', piyo: 'hogehoge', fugafuga: 'piyopiyo'}

 // 削除
 Cookies.remove('hoge');
```

# LocalStorage
## LocalStorageとは？
> Webページで取り扱うデータをWebブラウザの動作しているコンピュータの記憶装置に永続的に保存する仕組みの一つに「localStorage」がある。Webページ上で動作しているJavaScriptなどのプログラムが扱うデータをコンピュータ上の専用の保存領域に記録することができる。
<中略>
「Web Storage」と呼ばれる規格の一部として定義されており、同様の仕組みとして、一度のセッション（ページを開いてからブラウザやタブ、ウィンドウを閉じるまで）の間だけ有効な「sessionStorage」（セッションストレージ）もある。

**＜[ローカルストレージ【local storage】 / IT用語辞典 e-Words](https://e-words.jp/w/%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B8.html)より＞**

Web StorageというAPIの仕組みのうちの1つです。

### 特徴
- `key`と`value`のセットでデータを保存
- ブラウザ内に保存される
- 保存できるのは文字列のみ
  - 配列やオブジェクト等を保存・取得したい場合は、変換が必要 
- 有効期限は半永久的
- 保存容量は最低でも2MB（ブラウザによる）
- サーバへのデータ通信は行われない

## LocalStorageのデータ確認方法
LocalStorageに格納されているデータは、下記の手順でブラウザから確認することができます。（Chromeの場合）
**開発者ツールを開く -> `アプリケーション` -> `ストレージ` -> `LocalStorage`**
※Chromeの場合
![Screenshot 2023-01-31 at 22.42.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2543440/a7d03b36-e6f8-494e-2a8f-089905d89912.png)


## LocalStorageの操作方法
JavaScriptでLocalStorageを操作するには、Webストレージオブジェクト`localStorage`を使用します。

### データを格納する
```javascript
  // keyがhogeでvalueがhoge 
  localStorage.setItem('hoge', 'fuga');

  // hogeのvalueを更新
  localStorage.setItem('hoge', 'piyo');
```

### データを取得する
取得したいデータの`key`を指定して取り出せます。
```javascript
 localStorage.getItem('hoge'); // 'fuga'
```

### データの数を取得する
`key`, `value`のセットの数を取得できます。
```javascript
  localStorage.length; // 1
```

### n番目の`key`を取得する
`index`は`0`から始まります。
```javascript
  localStorage.key(0); // 'hoge'
```

### データを削除する
```javascript
 // 特定のデータを削除
 localStorage.removeItem('hoge');

 // （ドメイン内の）すべてのデータを削除
 localStorage.clear();
```

### keyが存在するかチェックする
```javascript
  localStorage.hasOwnProperty('hoge'); // true
```


### ちなみに
以下のようにプロパティアクセスメソッドでのアクセスも可能です。
※ブラウザ毎に挙動が違うため推奨されていないようです。
```javascript
  // 格納
  localStorage.hoge = 'fuga';
  localStorage['hoge'] = 'fuga';

  // 取得
  localStorage.hoge; // 'fuga'
  localStorage['hoge']; // 'fuga'
```

# CookieとLocalStorageの違い
明確な違いを下記にまとめました。
||Cookie|LocalStorage|
|:---|:---|:---|
|保存容量|4KB|2MB+|
|サーバへのデータ通信|リクエスト毎|行わない|
|期限|任意で設定可能|半永久的|

### 個人的に感じた違い
- (js-cookieのことを抜きにすると）LocalStorageの方が直感的にデータの操作ができる
- データ操作の際のオプションは、Cookieには豊富だがLocalStorageには無い

# まとめ・所感
CookieとLocalStorageについて調べてみました。
今回はそれぞれについて調べてまとめ、比較するだけになってしまったので、今後はそれぞれのメリットやデメリット等にも着目し、どのような場合にどちらを使うべきなのか自分で判断できるようになりたいと考えています。

# 参考文献まとめ
- [Window.localStorage / MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/API/Window/localStorage)
- [Document.cookie / MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/API/Document/cookie)
- [Web Storage API / MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/API/Web_Storage_API)
- [HTTP Cookie の使用 / MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies)
- [Storage.setItem() / MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/API/Storage/setItem)
- [Cookie / IT用語辞典 e-Words](https://e-words.jp/w/Cookie.html)
- [ローカルストレージ【local storage】 / IT用語辞典 e-Words](https://e-words.jp/w/%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B8.html)
- [LocalStorage, sessionStorage / Javascript.info](https://ja.javascript.info/localstorage)
- [Cookies(クッキー), document.cookie / Javascript.info](https://ja.javascript.info/cookie)
- [【JavaScriptの応用】Cookieの操作 / TCD](https://tcd-theme.com/2021/11/javascript-cookie.html)
- [JavaScriptでCookieのpath属性を設定する方法を現役エンジニアが解説【初心者向け】 / TechAcademy](https://magazine.techacademy.jp/magazine/35729)
- [Cookieで指定可能な属性の種類と設定方法 / JavaDrive](https://www.javadrive.jp/javascript/webpage/index18.html#section3)
- [.cookie / jsSTUDIO](https://js.studio-kingdom.com/javascript/document/cookie)
- [Cookieの新しい属性、SameParty属性について / ASnoKaze blog](https://asnokaze.hatenablog.com/entry/2020/12/14/013442)
- [CookieのPriority属性の仕様 / ASnoKaze blog](https://asnokaze.hatenablog.com/entry/2019/12/19/013022)
- [Cookieに書きこまれたデータを読み込む (JavaScript プログラミング) / iPentec](https://www.ipentec.com/document/javascript-read-cookie)
- [JavaScriptでcookieを削除する方法 / UX MILK](https://uxmilk.jp/24126)
- [js-cookieでクッキーを操作するサンプル / ITSakura](https://itsakura.com/js-cookie)
- [JavaScript クッキー操作できるjs-cookie使ってみた / かもメモ](https://chaika.hatenablog.com/entry/2019/02/05/083000)