Web Storage API は、Cookie を使用するよりも直感的な方法で、ブラウザがキーと値のペアを安全に保存できる仕組みを提供します。本記事は、このシンプルな技術の使い方を示すウォークスルーです。
基本的な概念
Storage オブジェクトはシンプルなキーと値の組み合わせを保存しており、オブジェクトに似ていますが、これらはページを読み込んでいる間じゅう、そのまま存在し続けます。キーは文字列か整数を使用できますが、値は文字列しか使用できません。オブジェクトのようにして、あるいは getItem() および setItem() メソッドを使用して、これらの値にアクセスできます。以下の 3 行はすべて、同じ方法で colorSetting という項目をセットします:
localStorage.colorSetting = '#a4509b'; localStorage['colorSetting'] = '#a4509b'; localStorage.setItem('colorSetting', '#a4509b');
Web Storage には、以下の 2 種類の仕組みがあります:
sessionStorage
は、ページのセッション中 (ページの再読み込みや復元を含む、ブラウザを開いている間) に使用可能な、生成元ごとに区切られた保存領域を管理します。localStorage
も同様ですが、こちらはブラウザを閉じたり再び開いたりしても持続します。
これらの仕組みは Window.sessionStorage
および Window.localStorage
プロパティ (正確には、サポートするブラウザは Window
オブジェクトが WindowLocalStorage
および WindowSessionStorage
オブジェクトを実装しており、これらに localStorage
および sessionStorage
プロパティがあります) を通して使用でき、いずれかのプロパティを使用すると Storage
オブジェクトのインスタンスを生成して、データアイテムの保存、取り出し、削除ができます。同じ生成元に対して sessionStorage
と localStorage
は、別の Storage オブジェクトを使用します。これらは別々に制御されて機能します。
よって例えば、始めにドキュメントで localStorage
を呼び出すと Storage
が返ります。その後にドキュメントで sessionStorage
を呼び出すと、別の Storage
オブジェクトが返ります。どちらも同じ方法で操作することができますが、操作は個別に行われます。
localStorage の機能検出
localStorage を使用可能にするため、始めに現在のブラウザセッションでサポート済みかつ使用可能であるかを確かめるべきです。
サポート状況と有効性を検証する
localStorage をサポートするブラウザは、window オブジェクトに localStorage という名称のプロパティを持っています。しかしさまざまな理由で、プロパティが存在すると主張するだけで例外が発生する可能性があります。さまざまなブラウザが localStorage を無効化する設定を設けていますので、このプロパティが存在しなければ、localStorage は実際に使用できないことが保証されます。よってブラウザが localStorage をサポートしていても、ページ上のスクリプトでは試用できる状態ではない場合があります。例えば Safari はプライベートブラウジングモードで、内容がなくクォータが 0 の localStorage を提供しますので、事実上使用できません。機能を検出する際は、使い方のシナリオを考慮すべきです。
localStorage がサポート済みかつ使用可能であるかを検出する関数を、以下に示します:
function storageAvailable(type) { try { var storage = window[type], x = '__storage_test__'; storage.setItem(x, x); storage.removeItem(x); return true; } catch(e) { return false; } }
また、この関数の使い方は以下のとおりです:
if (storageAvailable('localStorage')) { // わあい! localStorage をちゃんと使用できます } else { // 残念ながら localStorage は使用できません }
storageAvailable('sessionStorage')
を呼び出すと、代わりに sessionStorage を確認できます。
localStorage の機能を検出する方法のおおまかな歴史をご覧ください。
シンプルな例
Web Storage の典型的な使用法を示すため、想像力豊かに Web Storage Demo と名づけたシンプルな例を作成しました。ランディングページには、色、フォント、装飾画像をカスタマイズするためのコントロールがあります:
別の選択肢を選ぶと、即座にページが更新されます。さらに、選択内容を localStorage
に保存しますので、別のページに移動した後に再びこのページを読み込むと、選択内容が維持されています。
また、event output ページも提供します。このページを別のタブで開くと、ランディングページで選択肢を変更したときに StorageEvent
が発生するのに応じて、更新されたストレージの情報が出力されるのを確認できます。
注記: 上記のリンクから実際のページを参照することができます。また、ソースコードも確認できます。
ストレージが存在しているかを確認する
始めに main.js で、ストレージオブジェクトがすでに存在しているか (すなわち、過去にページへアクセスしていたか) を確認します:
if(!localStorage.getItem('bgcolor')) { populateStorage(); } else { setStyles(); }
Storage.getItem()
メソッドは、ストレージからデータアイテムを取得するために使用します。この例では、bgcolor
アイテムが存在するかを確認しています。アイテムが存在しなければ、既存のカスタマイズ値をストレージへ追加するために populateStorage()
を実行します。すでに値が存在する場合は、ページのスタイルを保存済みの値で更新するために setStyles()
を実行します。
注記: Storage.length
を使用して、ストレージオブジェクトが空であるかを確認することもできます。
ストレージから値を取得する
前述のとおり Storage.getItem()
を使用して、ストレージから値を取り出すことができます。これはデータアイテムのキーが引数であり、またデータの値を返します。例えば:
function setStyles() { var currentColor = localStorage.getItem('bgcolor'); var currentFont = localStorage.getItem('font'); var currentImage = localStorage.getItem('image'); document.getElementById('bgcolor').value = currentColor; document.getElementById('font').value = currentFont; document.getElementById('image').value = currentImage; htmlElem.style.backgroundColor = '#' + currentColor; pElem.style.fontFamily = currentFont; imgElem.setAttribute('src', currentImage); }
この例で、最初の 3 行は local storage から値を取得しています。次に、フォーム要素で表示する値をこれらの値に更新して、ページを再読み込みしたときに同期するようにします。最後に、ページのスタイルや装飾画像を更新して、再読み込み時にカスタマイズ設定を復元します。
ストレージに値を設定する
Storage.setItem()
は新たなデータアイテムを作成するため、および (データアイテムがすでに存在していれば) 既存の値を更新するために使用します。これは引数が 2 つあり、ひとつは作成または変更するデータアイテムのキー、もうひとつはデータアイテムに保存する値です。
function populateStorage() { localStorage.setItem('bgcolor', document.getElementById('bgcolor').value); localStorage.setItem('font', document.getElementById('font').value); localStorage.setItem('image', document.getElementById('image').value); setStyles(); }
populateStorage()
関数は、背景色、フォント、画像のパスの 3 つのアイテムを local storage に保存します。そして、ページのスタイルなどを更新するために setStyles()
関数を実行します。
また、それぞれのフォーム要素に onchange
ハンドラを含めておき、フォームの値が変更されるたびにデータやスタイルを更新します:
bgcolorForm.onchange = populateStorage; fontForm.onchange = populateStorage; imageForm.onchange = populateStorage;
StorageEvent を使用してストレージの変更に反応する
StorageEvent
は、Storage
オブジェクトが変更されるたびに発生します。これは、変更を行ったページ上では効用がないでしょう。実際は、ストレージを使用するドメイン上の別のページで、ストレージの変更に同期するための手段です。別のドメイン上のページは、前述のストレージオブジェクトにアクセスできません。
イベントページ (events.js をご覧ください) には、以下の JavaScript しかありません:
window.addEventListener('storage', function(e) { document.querySelector('.my-key').textContent = e.key; document.querySelector('.my-old').textContent = e.oldValue; document.querySelector('.my-new').textContent = e.newValue; document.querySelector('.my-url').textContent = e.url; document.querySelector('.my-storage').textContent = e.storageArea; });
ここでは window
オブジェクトに、現在の生成元に関連付けられた Storage
オブジェクトが変更されたときに発生するイベントリスナを追加しています。上記の例でわかるとおり、このイベントに関連付けられたイベントオブジェクトは、変更されたデータのキー、変更前の古い値、変更後の新しい値、ストレージを変更したドキュメントの URL、ストレージオブジェクト自体といった、役に立つ情報を含んでいるいくつものプロパティを持っています。
データレコードを削除する
Web Storage には、データを削除するためのシンプルなメソッドが 2 つあります。このデモでは使用していませんが、プロジェクトへとても簡単に追加できます:
Storage.removeItem()
は引数が 1 つあり、削除したいデータアイテムのキーです。これは、当該ドメインのストレージオブジェクトからデータアイテムを削除します。Storage.clear()
は引数がなく、当該ドメインのストレージオブジェクト全体を空にします。
仕様
仕様書 | 策定状況 | コメント |
---|---|---|
Web Storage (Second edition) | 勧告 |
ブラウザ実装状況
機能 | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
---|---|---|---|---|---|
localStorage | 4 | 3.5 | 8 | 10.50 | 4 |
sessionStorage | 5 | 2 | 8 | 10.50 | 4 |
機能 | Android | Firefox Mobile (Gecko) | IE Phone | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
基本サポート | 2.1 | ? | 8 | 11 | iOS 3.2 |
すべてのブラウザで、localStorage および sessionStorage が受け入れる容量は異なります。さまざまなブラウザのストレージ容量を報告しているページがあります。
注記: iOS 5.1 より Safari Mobile は localStorage データを cache フォルダに保存しており、概して空き容量が少ない場合に OS の要求により、時々クリーンアップを受けます。