HTML5 の Web Storage を使用してオフラインで作業する

Web Storage を使用してオフライン機能を追加する

HTML の新しい標準である HTML5 は、多種多様な新しい機能やレイアウト手法をサポートしています。HTML5 で完全にサポートしているものとしては、マルチメディアや CSS3 の他に、キャンバスと SVG (Scalable Vector Graphics) を使用した描画機能もあります。新しいセマンティック要素を提供している HTML5 には、アプリケーション・キャッシュ、JavaScript ワーカー、新しいバージョンの XMLHttpRequest、そして Web Storage と呼ばれるものを使用して、HTML による正当な Web アプリケーションを作成する方法も用意されています。この記事では、Web Storage の強力さと、なぜ Web Storage の方がクッキーよりも優れたストレージ手段なのかを説明します。この記事を読んで、Web Storage の基本概念、ブラウザーによるサポート、HTML5 の Web Storage オブジェクトについて学びましょう。

Kris Hadlock, Web Developer/Designer, Studio Sedition

Photo of Kris HadlockKris Hadlock は、1996年から契約 Web 開発者および設計者として、SPIN Magazine、IKEA、United Airlines、JP Morgan Chase、Le Cordon Bleu、Canon などの企業のプロジェクトを手掛けてきました。著書には『Query Mobile: Develop and Design』、『Ajax for Web Application Developers』(Sams)、『The ActionScript Migration Guide』(New Riders) があります。また、コラムニストおよびライターとしても、Peachpit.com、InformIT.com、Practical Web Design magazine などの数々の Web サイトや設計関連の雑誌で活躍しています。彼は、フォームと関数の融合を専門とする Web 設計およびソフトウェア開発会社、www.studiosedition.com の創設者でもあります。



2012年 11月 01日

概要

クッキーは JavaScript が登場したときからずっと使用されてきました。従って、Web 上にデータを格納することそれ自体は新しい概念ではありませんが、Web Storage はクッキーよりもはるかに強力なデータ・ストレージであり、例えばセキュリティー、速度、使いやすさなどはクッキーより優れています。また、Web Storage には大量のデータを格納することができます。その正確なデータ量は Web ブラウザーによって異なりますが、多くの場合は 5MB から 10MB の間であり、HTML アプリケーションにとっては十分な量です。さらにもう 1 つのメリットは、これらのデータはサーバーへのリクエストのたびにロードされるわけではないことです。唯一の制約は、ブラウザー間で Web Storage を共有できないことです。例えば Safari にデータを格納すると、Mozilla Firefox ではそのデータにアクセスすることはできません。

HTML5 には以下の 2 つのタイプの Web Storage オブジェクトが組み込まれています。

  • sessionStorage オブジェクト: 1 つのセッションのデータを格納します。ユーザーが Web ページまたはブラウザーを閉じると、そのデータは破棄されます。
  • localStorage オブジェクト: データを無期限に格納します。ユーザーが Web ページまたはブラウザーを閉じても、ブラウザーに設定されたストレージ量に応じてデータは格納されたまま保持されます。

頻繁に使用される略語

  • API: Application Programming Interface
  • CSS: Cascading Style Sheets
  • HTML: HyperText Markup Language
  • JSON: JavaScript Serialized Object Notation

どちらのストレージ・オブジェクトにも同じメソッドとプロパティーがあるので、この記事では一貫してすべての例で localStorage オブジェクトを使用することにします。

この記事では、Web Storage の強力さと、なぜ Web Storage の方がクッキーよりも優れたストレージ手段なのかを説明します。Web Storage の基本的な概念、HTML5 の Web Storage のメソッド、ブラウザーによるサポートについて詳しく探りましょう。

この記事で使用する例については、ソース・コードをダウンロードすることができます。


ブラウザーによるサポート

Firefox、Google Chrome、Safari、Opera、Microsoft Windows Internet Explorer 8 またはそれ以降のバージョンなど、最新のブラウザーでは新しいバージョンのすべてにおいて Web Storage 機能がサポートされています。残念ながら、Internet Explorer 7 とそれ以前のバージョンでは Web Storage をサポートしていません。表 1 に HTML5 の Web Storage をサポートする各デスクトップ・ブラウザーのバージョンを示します。

表 1. HTML5 の Web Storage をサポートするデスクトップ・ブラウザー
ChromeFirefoxSafariOperaInternet Explorer
ChromeFirefoxSafariOperaInternet Explorer
4 またはそれ以降4 またはそれ以降4 またはそれ以降11 またはそれ以降8 またはそれ以降

Opera Mini を除き、モバイル・ブラウザーも HTML5 の Web Storage をサポートしています。表 2 に HTML5 の Web Storage をサポートする各モバイル・ブラウザーのバージョンを示します。

表 2. HTML5 の Web Storage をサポートするモバイル・ブラウザー
iOSAndroidOpera MiniOpera Mobile
iOSAndroidOpera MiniOpera Mobile
5 またはそれ以降3 またはそれ以降サポートせず11 またはそれ以降

HTML5 の Web Storage に対するブラウザーのサポート状況は極めて素晴らしいものがあります。しかし古いブラウザーの場合には、Web Storage をサポートするかどうかを何らかの形で確認してから使用する必要があります。ブラウザーが Web Storage をサポートしているかどうかの確認は簡単です。簡単な条件文を使用して、HTML5 のストレージ・オブジェクトが定義されているかどうかを確認すればよいのです。定義されている場合には、Web Storage を使用するスクリプトを作成しても問題ありません。定義されていない場合には、別の方法を使用する必要があります (例えばデータ・ストレージが必要な場合は JavaScript でクッキーを使用するなど)。ブラウザーに Storage オブジェクトが定義されているかどうかを確認するための簡単な方法をリスト 1 に示します。

リスト 1. ブラウザーが Web Storage をサポートしているかどうかを確認する方法
if(typeof(Storage)!== "undefined") {
  // Web storage is supported
}
else {
  // Web storage is NOT supported
}

ブラウザーが Web Storage をサポートしていない場合には、JavaScript でクッキーを使用するか、AmplifyJS などの既存のライブラリーを使用してカスタムの Web Storage オブジェクトを作成することができます。AmplifyJS は、極めて単純な API を使用して Web アプリケーションの一般的な問題を解決するために設計されたコンポーネント・セットであり、特定のブラウザーにおいて Web Storage がサポートされていない問題に対して、クライアント・サイドの永続ストレージを扱うための amplify.store ラッパーを使用して対応します。これによってサポートされるのは、Internet Explorer 5 またはそれ以降、Firefox 2 またはそれ以降、Safari 4 またはそれ以降、Chrome、Opera 10.5 またはそれ以降、iOS 2 またはそれ以降、Android 2 またはそれ以降のバージョンです。また AmplifyJS ライブラリーが提供する API を使用すれば、ブラウザーの種類によらず 1 つの API でストレージを扱うことができるため、対象とするブラウザーごとに異なるコードを作成する必要はありません。ブラウザーが HTML5 の Web Storage をサポートしている場合には、AmplifyJS はその最新ストレージ手法を使用します。ブラウザーが HTML5 の Web Storage をサポートしていない場合には、AmplifyJS は HTML5 の Web Storage 機能を使用せずにストレージをサポートするようにデグレードします。AmplifyJS とそのストレージ・ラッパーの API については「参考文献」を参照してください。


HTML5 の Web Storage を使用する

いくつかの使いやすいメソッドにより、HTML5 の Web Storage 機能を提供することができます。これらのメソッドを使用すると、キーと値のペアの設定、キーを基に値を取得する 2 つの方法、キーと値のペアの一括削除、そして特定のキーと値のペアの削除をサポートすることができます。表 3 は HTML5 の Web Storage に使用できるメソッドを示しています。

表 3. HTML5 の Web Storage に使用できるメソッド
メソッド説明
setItem(key, value)後で使用できるように、キーと値のペアを Web Storage オブジェクトに追加します。値のデータ型は任意です (文字列型、数値型、配列型など)。
getItem(key)最初に値を格納するために使用したキーを基に値を取得します。
clear()Web Storage オブジェクトからキーと値のペアをすべて削除します。
removeItem(key)キーを基に、Web Storage オブジェクトから特定のキーと値のペアを削除します。
key(n)キー (n) の値を取得します。

キーと値のペアを作成して Web Storage オブジェクトに追加する場合、そのペアの値には任意のデータ型を使用することができます (文字列型、数値型、配列型、オブジェクト型など)。配列またはオブジェクトを格納する場合には、JSON オブジェクトと JSON.stringify メソッドを使用してデータを文字列に変換する必要があります。データを取得する場合には、そのデータを JSON.parse を使用して構文解析すると、そのオブジェクトまたは配列が最初の状態で返されます。Web Storage オブジェクトにキーと値のペアを追加する方法には、2 通りの方法があります。第 1 の方法は setItem メソッドを使用する方法です (リスト 2)。

リスト 2. setItem を使用して Web Storage オブジェクトにキーと値のペアを追加する
localStorage.setItem('myKey', 'myValue');

Web Storage オブジェクトにキーと値のペアを追加するための第 2 の方法は、Web Storage オブジェクトとドット構文を使用してキーの値を直接設定する方法です (リスト 3)。

リスト 3. Web Storage オブジェクトにキーと値のペアを直接追加する
localStorage.myKey = 'myValue';

格納された値を取得する方法も同じように簡単です。この場合にも 2 通りの方法があります。第 1 の方法は getItem メソッドを使用する方法です。このメソッドはキーを引数に取り、キーに対応する値がある場合にはその値を返します。リスト 4 はその例を示しています。

リスト 4. getItem を使用して Web Storage オブジェクトからキーと値のペアを取得する
localStorage.getItem('myKey');

Web Storage オブジェクトからキーと値のペアを取得するための第 2 の方法は、ドット構文を使用してキーと値のペアに直接アクセスする方法です (リスト 5)。この例では、これまでの例で設定した「'myValue'」という文字列値が返されます。

リスト 5. Web Storage オブジェクトからキーと値のペアを直接取得する
localStorage.myKey;

格納されたデータを削除する方法も 2 通りあります。すべての項目を一度に削除することも、個々の項目を 1 つずつ削除することもできます。すべての項目を Web Storage から一度に削除するには、リスト 6 のように clear メソッドを使用します。

リスト 6. Web Storage オブジェクトからキーと値のペアをすべて削除する
localStorage.clear();

Web Storage オブジェクトからキーと値のペアを 1 つ削除するには、removeItem メソッドを使用する必要があります。リスト 7 は removeItem メソッドの例を示しています。この例では、どのキーと値のペアをストレージ・オブジェクトから削除するのかを特定するための引数としてキーを受け取っています。

リスト 7. Web Storage オブジェクトからキーと値のペアを 1 つ削除する
localStorage.removeItem('myKey');

リスト 8 は、JSON オブジェクトと JSON.stringify を使用して配列を文字列として格納する方法の例を示しています。オブジェクトの扱い方は同じです。

リスト 8. 配列を文字列として HTML5 の Web Storage に格納する
var myArray = new Array('First Name', 'Last Name', 'Email Address');
localStorage.formData = JSON.stringify(myArray);

文字列として格納された配列を Web Storage から取得し、使用可能なJavaScript の配列に逆変換するには、単純に JSON.parse メソッドを使用します (リスト 9)。

リスト 9. 文字列として格納された配列を HTML5 の Web Storage から取得し、使用可能な JavaScript の配列に変換する
var myArray = JSON.parse(localStorage.formData);

Internet Explorer 8 またはそれ以降、Opera 10.5 またはそれ以降、Firefox 3.5 またはそれ以降、Safari 4 またはそれ以降、そして Chrome には、これまでの例のコードをサポートするネイティブ JSON オブジェクトが含まれています。これらよりも前のバージョンのブラウザーを使用する場合には、json2.js ファイルをダウンロードして使用します (「参考文献」を参照)。

ここまでに示したように、Web Storage の使い方は簡単です。ただし、Web Storage を使い始める前に、マシンが共有されている場合にはセキュリティーの懸念があることを認識する必要があります。Web Storage は決してクッキーよりもセキュアなわけではありません。パスワードやクレジットカード番号といった扱いに注意が必要な情報をクライアント・サイドに格納してはなりません。


Web Storage の実際

基本事項を説明したので、今度は HTML5 の Web Storage を実際に使用してみましょう。ここで仮に、Web サイト上に Web フォームがあるとし、このフォームをオフラインでサポートしたいとします。ユーザーがそのフォームを送信すると、その Web サイトに再度接続された時に、フォームがサーバーと同期されると非常に便利です。それが HTML5 では可能になります。

リスト 10 のように、苗字 (last-name) と名前 (first-name)、そして e-メール・アドレス (email-address)、送信ボタン (Submit) を含む単純な Web フォームを作成します。

リスト 10. HTML5 の Web Storage を使用してデータを格納する単純な Web フォーム
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>HTML5 Web Storage</title>
<style type="text/css">
label, 
input {
  display: block;
}
input {
  margin-bottom: 10px;
}
</style>
</head>

<body>

<form action="post.php" method="post" id="web-storage-form">
  <label for="first-name">First name:</label>
  <input type="text" name="first-name" id="first-name">

  <label for="last-name">Last name:</label>
  <input type="text" name="last-name" id="last-name">

  <label for="email-address">Email Address:</label>
  <input type="text" name="email-address" id="email-address">

  <input type="submit" value="Submit">
</form>

</body>
</html>

このフォームには、ポスト送信されたフォームと値を JavaScript を使用して取得するための ID が含まれています。また、フォーム要素によって基本的なレイアウトを作成するための CSS も含まれています。label と input の display:block プロパティーにより、各要素は新しい行に配置されます。margin-bottom プロパティーはページが乱雑に見えないように、項目間の間隔を空けます。

ユーザーがこのフォームを送信すると、このコードはまず、jQuery を使用して “web-storage-form” という ID でポスト送信されたフォームを捕捉することで、デフォルトのポスト送信が行われないようにします。フォームのポスト送信が行われる際には、フォームの値とフォームのアクションの URL を収集して変数に格納することができます。Web フォームの値を Ajax (Asynchronous JavaScript + XML) でポスト送信する場合や Web Storage に格納する場合には、それらの値をシリアライズする必要があります。フォームを送信する前に、navigator.onLine プロパティーを使用してユーザーが現在オンラインであるかどうかを確認します。

ユーザーがオンラインの場合には、簡略形式の Ajax 関数である jQuery.post 関数を使用してサーバーとの間でデータを送受信します。この関数は引数を 4 つ取ります (データの送信先となる url、送信対象の data (フォームの値をシリアライズしたデータ)、リクエストが成功した場合に実行される callback 関数、そして dataType)。この例では dataType が含まれていないため、デフォルトのデータ型を使用します。

ユーザーがオンラインではない場合には、Web Storage を活用します。まず、ブラウザーが Web Storage をサポートするかどうか、リスト 1 で作成した条件文を使用して確認することが重要です。ブラウザーが実際に Web Storage をサポートしている場合には、カスタム・キーを使用してフォームの値を localStorage オブジェクトに直接格納することができます。この例では formValues というカスタム・キーを使用しています。これで localStorage に値を格納できたので、ユーザーがオンラインに復帰したときにそれらの値が存在するかどうかを確認しましょう。そのためには if 文を追加し、localStorage.formValues に値があるかどうかを確認します。値がある場合には、このフォームはそれ以前に localStorage に送信されているということであり、そのフォームのデータを、先ほど設定した jQuery.post メソッドを使用してサーバーに送信しても安全です。値を送信した後は、それらの値が誤って 2 度送信されないように、それらの値を Web Storage から削除する必要があります。リスト 11 は実際のコードを示しており、Ajax を使用したフォームのポスト送信から localStorage を扱うところまでを抜粋してあります。

リスト 11. オフライン時にフォームのデータを localStorage に格納し、オンライン時にそのデータをサーバーに送信する
<script type="text/javascript" 
src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js">
</script>
<script type="text/javascript">
$(document).ready(function() {
  // Check for web storage values from a previous offline session
  if(localStorage.formValues) {
    console.log("localStorage.formValues: "+ localStorage.formValues);
    postForm($("#web-storage-form").attr('action'), localStorage.formValues);
    localStorage.removeItem("formValues");
  }

  $("#web-storage-form").submit(function(event) {
    // Prevent the form from posting
    event.preventDefault(); 

    // Gather values
    var formValues = $(this).serialize();
    var url = $(this).attr('action');
    postForm(url, formValues);
  });
 });

function postForm(url, formValues) {
  // Post to server or post to web storage
  if(navigator.onLine) {
    console.log("Online");
    $.post(url, formValues, function(data) {
      console.log("Success: "+ data);
    });
  }
  else {
    console.log("Offline");
    if(typeof(Storage) !== "undefined") {
      console.log("Storage supported");
      localStorage.formValues = formValues;
    }
  }
}
</script>

完全な例とするために、post.php ファイルはフォーム送信のエンドポイントとして動作し、フォーム・リクエストを受け取ってそれに応答します。このファイルは単にフォームの送信を受け取って、キーと値のペアの配列を出力することで応答します (リスト 12)。jQuery.post がレスポンスを受信すると、そのレスポンスに含まれるデータがコンソールに出力されます。

リスト 12. フォーム・リクエストに応答する PHP ファイル
<?php print_r($_POST); ?>

もちろん、この例をさらに堅牢にすることもできます。例えばサーバー・サイドにデータベース・ストレージを含め、ユーザーのコンピューターがオンラインに復帰してフォームのデータを送信できるかどうかをモニターするために一定間隔で localStorage を確認する、ということもできます。


まとめ

HTML5 には強力で新しい一連の機能が用意されており、それらは主要な Web ブラウザーの最新バージョンで次々とサポートされるようになっています。Web Storage は HTML5 の魅力的な機能の 1 つです。ただし Web Storage を使用する場合には、賢明な使い方をする必要があります。クッキーの場合と同じように、ユーザーは Web Storage 機能を無効にすることができます。また、この新しい機能を許可したくない人のために、必ずフォールバック機能を用意しておく必要があります。


ダウンロード

内容ファイル名サイズ
Work offline with web storagehtml5-web-storage.zip2KB

参考文献

学ぶために

製品や技術を入手するために

  • AmplifyJS: AmplifyJS をダウンロードしてください。
  • json2.js: json2.js をダウンロードし、JSON について学んでください。
  • CDN バージョンの jQuery ライブラリー: Google の開発者向け Web サイトで CDN (Content Delivery Network) にアクセスしてください。
  • IBM 製品の評価版: IBM 製品の評価版をダウンロードするか、あるいは IBM SOA Sandbox のオンライン試用版で、DB2、Lotus、Rational、Tivoli、WebSphere などが提供するアプリケーション開発ツールやミドルウェア製品を試してみてください。

議論するために

  • developerWorks コミュニティー: ここでは他の developerWorks ユーザーとのつながりを持てる他、開発者によるブログ、フォーラム、グループ、ウィキを調べることができます。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development
ArticleID=843254
ArticleTitle=HTML5 の Web Storage を使用してオフラインで作業する
publish-date=11012012