ローカルにデータを保存する仕組み。
成果物
Web Storage API
Web Storage APIとは、データを保存する仕組みである。
Web Storage APIってなに? という人のために説明しよう。Web Storage APIとは、ブラウザにサイトのデータを保存する仕組みである。JavaScript(ECMAScript)の言語仕様にあるAPIだ。
Web Storage APIは2種類ある。データを保存する期間に応じて、異なる別のオブジェクトとして用意されている。
Web Storage API | ライフタイム |
---|---|
localStorage | 永続 |
sessionStorage | 画面遷移するまで(更新も含む) |
Cookieとの共通点は以下。
- キーバリューである
- 値の型は文字列のみ
- ドメイン単位で保存される
Cookieとなにが違うの? 3つある。Web Storage APIは……。
- サーバに送信されない
- 暗号化されない
- データ上限が多い
Web Storage APIはサーバに送信されない。Cookieはサーバに自動送信される。CookieはHTTPヘッダに付与され、自動的に送信される。
Web Storage APIは暗号化されない。Cookieはサーバとの間で送受信するとき、HTTPプロトコルを用いる。これをHTTPSプロトコルに限定することで暗号化できる。
Web Storage APIはデータ上限が多い。
方法 | サイズ |
---|---|
Web Storage API | 5MB |
Cookie | 4KB |
以下のように使い分けるといいだろう。
方法 | 使い分け |
---|---|
Web Storage API | ユーザだけが知っていればいい情報 |
Cookie | サーバがユーザを識別するための情報(HTTPSでセキュアにすべき) |
方法 | 期間 | 保存するデータ内容 | セキュリティ |
---|---|---|---|
sessionStorage | 画面遷移するまで | ユーザだけが知っていればいい情報 | なし |
localStorage | 永久 | ユーザだけが知っていればいい情報 | なし |
Cookie | 指定期間 | サーバがユーザを識別するための情報 | HTTPS限定で暗号化 |
API
localStorage.length localStorage.key(INDEX); localStorage.getItem(KEY); localStorage.setItem(KEY, VALUE); localStorage.removeItem(KEY); localStorage.clear();
localStorage.length
数を取得する。
ストレージはドメインごとに保存される。なのでドメインごとに異なる数になりうる。
localStorage.key(INDEX)
指定した位置にあるキーを取得する。
length
と組み合わせることで全キーを取得できる。
function Keys() { for (let i=0; i<localStorage.length; i++) { yield localStorage.key(i); } } for (let key in Keys()) { console.log(`${key}`); }
全キーとその値を取得する。
for (let i=0; i<localStorage.length; i++) { let key = localStorage.key(i); let val = localStorage.getItem(key); console.log(`${key}=${val}`); }
localStorage.getItem(KEY)
指定したキーの値を返す。値の型は文字列である。
let value = localStorage.getItem(KEY);
localStorage.setItem(KEY, VALUE)
指定したキーの値を設定する。キーと値の型は文字列である。
localStorage.setItem(KEY, VALUE);
localStorage.removeItem(KEY)
指定したキーの値を削除する。
localStorage.removeItem(KEY);
localStorage.clear()
このドメインに保存されたすべてのストレージを削除する。
localStorage.clear();
storage
イベント
Storage
オブジェクトが変更されるたびに発火する。
window.addEventListener('storage', function(e) { e.key; e.oldValue; e.newValue; e.url; // ストレージを変更した文書のURL JSON.stringify(e.storageArea); // ストレージオブジェクト自体 });
注意
Web Storage APIはCookieと比べて細かい配慮がなされていない。
問題
同一ドメイン内で名前重複しうる。同じドメインのうち、異なるページで独立した同じ名前のキーを持ちたいときがある。しかし、同一ドメイン内の同一キーは、ひとつしか持てない。全ページ共通データとなってしまう。
解決
キー名を一意に保つ。ドメイン内において全ページ間にまたいで全キー名を一意に保つ。
キー名をdomain.pageID.key
のような構成にする。キー名を一意にするときの階層化には以下のような項目が考えられる。
キー名の部位 | 内容目的 |
---|---|
domain |
URLのドメイン名|同一ドメインに他プラグインで作成されたキーがあっても重複回避できる |
pageID |
ページの識別子|他のページに同名のキーがあっても重複回避できる |
partsID |
部品の識別子|同一ページ内における部品ごとに分ける。異なる部品間で同一キーがあっても重複回避できる |
key |
ストレージのキー|値のキー。これだけだと上記パターンで重複してしまいうる |
キーが長くなってしまう。タイポが増えてバグになりうる。防ぐためのクラスを作成するほうが安全だろう。要検討。
問題
動作が遅くなる。同一ドメインの全ページで全ストレージをロードするため。
解決
使用量を減らす。ストレージは最大5MBだが、使う量を減らす。
解決にならない。本末転倒である。Web Storage APIはCookieの4KBと違い、5MBも使えることがメリットだった。それが嬉しくて使っている。なのに、そのメリットがそのまま動作遅延というデメリットになってしまう。
遅延ロードするか否かについては要調査。もしストレージを遅延ロードしてくれているなら動作速度はいくらかマシになるはず。使うときになってはじめてロードすれば、初期ロード時にすべてロードするときに比べて速い。実際、Web Storage APIが遅延ロードするかどうかはわからなかった。
localStorageは保存期間が指定できない。そのため一度保存したら永久に保存されたままになる。保存期間が指定できない
問題
ファイル残量がなくなる。PCのディスクスペースが圧迫されて何も保存できなくなってしまう。localStorageは一度保存したら削除されないため。
解決
以下のいずれかの方法をとる。
localStorageを削除する
localStorage.clear(); localStorage.remove(KEY);
問題
localStorageは使わなくなったデータを削除できない。ストレージの削除は、それを作成したのと同じドメインに遷移せねばならない。だが、そんなことは起こらない。なにせ削除したいのは、もう使わなくなったドメインのデータである。なのに削除するには、その使わなくなったドメインに遷移せねばならない。使っていないのだから遷移するはずがない。したがって、永久に削除できない。
解決
ブラウザの設定から全データ削除する。たとえばChromiumならメニュー→設定
→閲覧履歴データの削除
で行える。
sessionStorageを使う
sessionStorageはそのページを閉じたり更新すれば自動削除される。削除し忘れで蓄積することはない。
問題
セッションをまたいで保存できない。それがしたいからlocalStorageやCookieを使っている。なのにそれをやめたら本末転倒。
解決
なし。sessionStorageはそういうもの。代わりにほかの方法をとるしかない。
Cookieを使うを使う
Cookieは同一ドメイン内で4KBまでしか使えない。データは厳選されるため、名前重複が起こりにくい。
問題
同一ドメイン内で4KBまでしか使えない。最も重要なデータのみ保存する。たとえばサーバ側がユーザを特定する情報など。それより優先度がさがるデータは保存できないかもしれない。4KBが上限だから。
解決
なし。Cookieはそういうもの。代わりにほかの方法をとるしかない。
ブラウザの設定から全データ削除する
Chromiumならメニュー→設定
→閲覧履歴データの削除
で行える。
問題
どのドメインのデータを削除するか選べない。削除範囲は期間と項目である。たとえばChromiumなら、現在日時から1時間以内のキャッシュのみを削除するなど。以下でいえばストレージはCookieと他のサイトデータ
に含まれていると思われる。ただしドメインを選んで削除することはできない。
- 期間
- 1時間
- 1日
- 1週間
- 1ヶ月
- 全期間
- 項目
- 閲覧履歴
- ダウンロード履歴
- Cookieと他のサイトデータ
- キャッシュされた画像とファイル
- パスワードとその他のログインデータ
- 自動入力フォームのデータ
- サイトの設定
- ホストされているアプリデータ
【Google Chrome】特定のサイト(ドメイン)のCookieだけ削除する方法もある。だが、そもそもユーザは無数にあるドメインからどれを削除するかひとつずつ探しださねばならない。そんな面倒なことをやる人は少ないだろう。
「私はもう使わない」を自動的に判定するしくみがない。なので楽してデータ削除することができない。
最悪なワークフロー。しばしば起こりうる。
- ブラウザが重くなった
- そうだ、履歴データを全削除しよう
- localStorageも全削除されてしまう!
解決
大容量のHDDを使う。
- 大容量のディスクを使う
- ディスクの種類はHDDにする(書込上限が多い順:HDD,SSD,eMMC,FlashMemory(USB,SD))
それでもいずれ寿命はくる。
- 買い換える
- 楽にOSや環境作成できるよう準備する
所感
Web Storage APIを使ってみた。とても簡単だった。しかし運用するときに注意すべきことが多い。
諸悪の根源は、ブラウザのデータ管理方法だと思う。サイトごとのデータを削除する操作になじみがない。もしアプリなら、アプリまるごと削除するという単純な操作で済む。これと同じようにやりたい。アイコンを見て「あ、これ使ってないから消しちゃお」ってしたい。URLなんて覚えていないんだよ。それをキーにサイト検索なんてできるかボケ。
対象環境
- Raspbierry pi 4 Model B
- Raspberry Pi OS buster 10.0 2020-08-20 ※
- bash 5.0.3(1)-release
$ uname -a Linux raspberrypi 5.4.72-v7l+ #1356 SMP Thu Oct 22 13:57:51 BST 2020 armv7l GNU/Linux