Web Storage は、ユーザーのローカル環境(ブラウザ)にデータを保存するための仕組みです。データの保存・上書き・削除・全クリアなどの操作は、JavaScript で行うことができます。
Web Storage を利用すると、ユーザーごとにカスタマイズされた情報を提供することが可能となります。この仕組みはクッキー( HTTP cookie )とよく似ていますが、クッキーに比べて保存できる容量が大きいため、例えば、オフラインでもウェブアプリケーションを動作させられるだけの必要十分なデータをユーザーのローカル環境に保存することなどが可能となります。
Web Storage には、sessionStorage と localStorage の2種類のストレージが用意されています。どちらもキー( key )と値( value )をペアにしたデータのリストを ユーザーのローカル環境に保存する key-value 型のデータ保存形式である点は同じですが、データの有効期限などが異なるので目的に応じて使い分けます。
クッキー | ○ |
---|---|
sessionStorage | × |
localStorage | ○ |
クッキー | 指定期限まで有効 |
---|---|
sessionStorage | ウィンドウやタブを閉じるまで有効 |
localStorage | 永続的に有効 |
クッキー | 4KB |
---|---|
sessionStorage | 1オリジン当たり5MB |
localStorage |
クッキー | サーバへアクセスするたびに毎回自動送信 |
---|---|
sessionStorage | 必要時のみスクリプトやフォームなどで送信 |
localStorage |
sessionStorage は、ウィンドウやタブ単位での一回限りのセッションで有効なストレージです。ウィンドウやタブが開いている間のみデータが保存され、閉じるとデータが失われます。 同じドメインのサイトを別々のウィンドウで開いている場合には、それぞれが別の sessionStorage となります。 クッキーとは異なり、ウィンドウ間でデータが共有されることはありません。
sessionStorage を利用する一例を挙げてみます。例えば、2つのウィンドウで同じサイトを開きながら航空券を注文する場合、クッキーでは買い物かご情報が混在してしまって、同じフライトのチケットを気づかずに2枚注文してしまう可能性があります。
sessionStorage では、それぞれが別のセッションとなるため、 別ウィンドウの買い物かご情報が混在してしまうことがありません。
localStorage は、オリジン単位でデータを永続的に保存するストレージです。 オリジンとは、「 http://www.example.com:80 」のような「プロトコル :// ドメイン名 : ポート番号」のことです。オリジンが同じであれば別ウィンドウでもデータを共有でき、ブラウザを終了してもデータは失われません。 データ保存量の上限はブラウザへの推奨値が1オリジン当たり5MBとされており、クッキーの4KBに比べるとより大きなデータを保存できるようになっています。
localStorage を利用する一例を挙げてみます。例えば、ウェブメールにおけるメールの送受信データのような比較的大きなデータの場合、クッキーでは保存できるデータ量に上限があるため、すべてのデータをローカル環境に保存することは困難です。また、クッキーではユーザーがアクセスする度にデータがサーバーに送信されるため、セキュリティの観点からも好ましくありません。
localStorage では、ローカル環境に 5MB までのデータを永続的に保存でき、ユーザーのアクセスの度にデータがサーバーに送信されることがありません。ウェブメールの例で言えば、localStorage なら送受信データをローカル環境に保存でき、オフラインウェブアプリケーションと組み合わせることで、オフラインでのメール閲覧なども可能となるでしょう。
Web Storage で指定できる命令は、データの保存・保存したデータの取得・指定キーの値削除・全クリアのいずれかです。それぞれの命令を指定するメソッドは以下の通りです。メソッド・属性は、sessionStorage と localStorage で共通となります。
例えば、userid というキー( key )と、1111 という値( value )をペアにして保存する場合には、 以下のように指定します。
JavaScript source
// 変数 storage に sessionStorage を格納
var storage = sessionStorage;
// userid というキーに 1111 という値を割り当てて保存
storage.setItem('userid', '1111');
// 後から value を変更してセットし直せば上書き保存される
storage.setItem('userid', '2222');
// userid というキーの値を取得する( 2222 が返るはず)
storage.getItem('userid');
// userid というキーの値を削除する
storage.removeItem('userid');
// ストレージに保存されているデータをすべてクリアする
storage.clear();
尚、上のサンプルでは sessionStorage としてデータを保存していますが、「sessionStorage」の部分を「localStorage」に変えれば localStorage としてデータが保存されます。
sessionStorage と localStorage にデータの追加・上書き・削除・全クリアなどの 何らかの更新をすると storage というイベントが発生します。 storageイベントには、以下の属性が用意されています
Web Storage には、以下のメソッド・属性が用意されています。
HTML source
<!-- ストレージに保存したい内容を入力 -->
<p>
キー:<input id="k" type="text">
値:<input id="v" type="text">
</p>
<p>
<input type="button" value="ストレージに保存" onClick="set()">
</p>
<!-- ここに保存された内容を表示 -->
<div id="show_result"></div>
<p>
<!-- ストレージを空にするボタンを設置 -->
<input type="button" value="ストレージをクリア" onClick="cle()">
</p>
JavaScript source
<script>
// 変数 storage に sessionStorage を格納
var storage = sessionStorage;
// データを保存する関数
function set() {
// 変数 k に「キー」に入力された値をセットする
var k = document.getElementById("k").value;
// 変数 v に「値」に入力された値をセットする
var v = document.getElementById("v").value;
// ストレージに保存する
storage.setItem(k, v);
// 画面にリストを表示するための関数を呼び出す
show_result();
}
// データをクリアする
function cle() {
storage.clear();
show_result();
}
// 保存されているデータをリスト表示する
function show_result() {
var result = "";
// 保存されているデータの数だけループ
for(var i=0; i<storage.length; i++){
// i 番目のキーを取得
var k = storage.key(i);
// キーと値をコロン(:)区切りのテキストにする
result += k + ":" + storage.getItem(k) + "<br>";
}
// 上のループで作成されたテキストを表示する
document.getElementById("show_result").innerHTML = result;
}
</script>
キー:
値:
キーが押されるタイミングで、Web Storageに保存されます。
テキストボックスに適当な文字を入力した後で、ブラウザをリロードしてみたり、新規ウインドウなどで同じ URLを表示してみて下さい。Web Storageに保存されたテキストが復元されます。
HTML source
<textarea id="tbox" rows="5" cols="30"></textarea>
JavaScript
// textareaのオブジェクトを取得
const tbox = document.getElementById('tbox')
// すでにテキストが保存されていれば復元
if (localStorage['tbox']) {
tbox.value = localStorage['tbox']
}
// キーが押された時にテキストを保存
tbox.onkeydown = function (e) {
localStorage['tbox'] = tbox.value
}