Web Storage API は、Cookie を使用するよりも直感的な方法で、ブラウザーがキーと値のペアを安全に保存できる仕組みを提供します。本記事は、このシンプルな技術の使い方を示すウォークスルーです。

基本的な概念

Storage オブジェクトはシンプルなキーと値の組み合わせを保存しており、オブジェクトに似ていますが、これらはページを読み込んでいる間じゅう、そのまま存在し続けます。キーは常に文字列です(整数のキーは、オブジェクトがそうであるように、自動的に文字列に変換されます)。オブジェクトのようにして、あるいは Storage.getItem()Storage.setItem() メソッドを使用して、これらの値にアクセスできます。以下の 3 行はすべて、同じ方法で colorSetting という項目をセットします:

localStorage.colorSetting = '#a4509b';
localStorage['colorSetting'] = '#a4509b';
localStorage.setItem('colorSetting', '#a4509b');

: Web Storage API (setItem, getItem, removeItem, key, length) の使用が推奨されていて、その理由はプレーンオブジェクトをキーバリューストアとして使うことによる落とし穴を防ぐためです。

Web Storage には、以下の 2 種類の仕組みがあります:

  • sessionStorage は、ページのセッション中 (ページの再読み込みや復元を含む、ブラウザーを開いている間) に使用可能な、生成元ごとに区切られた保存領域を管理します。
  • localStorage も同様ですが、こちらはブラウザーを閉じたり再び開いたりしても持続します。

これらの仕組みは Window.sessionStorage および Window.localStorage プロパティ (正確には、サポートするブラウザーは Window オブジェクトが WindowLocalStorage および WindowSessionStorage オブジェクトを実装しており、これらに localStorage および sessionStorage プロパティがあります) を通して使用でき、いずれかのプロパティを使用すると Storage オブジェクトのインスタンスを生成して、データアイテムの保存、取り出し、削除ができます。同じ生成元に対して sessionStoragelocalStorage は、別の Storage オブジェクトを使用します。これらは別々に制御されて機能します。

よって例えば、始めにドキュメントで localStorage を呼び出すと Storage が返ります。その後にドキュメントで sessionStorage を呼び出すと、別の Storage オブジェクトが返ります。どちらも同じ方法で操作することができますが、操作は個別に行われます。

localStorage の機能検出

localStorage を使用可能にするため、始めに現在のブラウザーセッションでサポート済みかつ使用可能であるかを確かめるべきです。

サポート状況と有効性を検証する

localStorage をサポートするブラウザーは、window オブジェクトに localStorage という名称のプロパティを持っています。しかしさまざまな理由で、プロパティが存在すると主張するだけで例外が発生する可能性があります。さまざまなブラウザーが localStorage を無効化する設定を設けていますので、このプロパティが存在しなければ、localStorage は実際に使用できないことが保証されます。よってブラウザーが localStorage をサポートしていても、ページ上のスクリプトでは試用できる状態ではない場合があります。例えば Safari はプライベートブラウジングモードで、内容がなくクォータが 0 の localStorage を提供しますので、事実上使用できません。機能を検出する際は、使い方のシナリオを考慮すべきです。 しかし、それでも合法的な QuotaExceededError 、これは単に利用できるストレージスペースを使い切ったことを意味する、を得ます。機能検出にてこのシナリオを考慮に入れるべきです。

localStorage がサポート済みかつ使用可能であるかを検出する関数を、以下に示します:

function storageAvailable(type) {
	try {
		var storage = window[type],
			x = '__storage_test__';
		storage.setItem(x, x);
		storage.removeItem(x);
		return true;
	}
    catch(e) {
        return e instanceof DOMException && (
            // everything except Firefox
            e.code === 22 ||
            // Firefox
            e.code === 1014 ||
            // test name field too, because code might not be present
            // everything except Firefox
            e.name === 'QuotaExceededError' ||
            // Firefox
            e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
            // acknowledge QuotaExceededError only if there's something already stored
            storage.length !== 0;
    }
}

また、この関数の使い方は以下のとおりです:

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 オブジェクトが変更されるたびに発火します (sessionStorage の変更では発火しません) 。これは、変更を行ったページ上では効用がないでしょう。実際は、ストレージを使用するドメイン上の別のページで、ストレージの変更に同期するための手段です。別のドメイン上のページは、前述のストレージオブジェクトにアクセスできません。

イベントページ (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 = JSON.stringify(e.storageArea);
});

ここでは window オブジェクトに、現在の生成元に関連付けられた Storage オブジェクトが変更されたときに発生するイベントリスナを追加しています。上記の例でわかるとおり、このイベントに関連付けられたイベントオブジェクトは、変更されたデータのキー、変更前の古い値、変更後の新しい値、ストレージを変更したドキュメントの URL、ストレージオブジェクト自体 (その中身を見えるように文字化しています) といった、役に立つ情報を含んでいるいくつものプロパティを持っています。

データレコードを削除する

Web Storage には、データを削除するためのシンプルなメソッドが 2 つあります。このデモでは使用していませんが、プロジェクトへとても簡単に追加できます:

  • Storage.removeItem() は引数が 1 つあり、削除したいデータアイテムのキーです。これは、当該ドメインのストレージオブジェクトからデータアイテムを削除します。
  • Storage.clear() は引数がなく、当該ドメインのストレージオブジェクト全体を空にします。

仕様

仕様書 策定状況 コメント
HTML Living Standard 現行の標準  

ブラウザー実装状況

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!

機能 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 の要求により、時々クリーンアップを受けます。

関連情報

ドキュメントのタグと貢献者

このページの貢献者: Uemmra3, yyss
最終更新者: Uemmra3,