ユーザのウェブブラウザに大量のデータを保存するには、現在、いくつかの既存の標準に準拠する必要があり、それぞれに長所、短所、独自の W3C 標準化ステータス、ブラウザサポートのレベルがあります。しかし、それらに関係なく、これらの標準は広く利用可能なクッキーのメカニズムよりも実際に優れています。
今日のWebアプリケーションは、クライアント内で多くのデータ処理を行うようになってきており、オフラインでタスクを完了する必要がある場合もあります。クライアントサイドのデータストレージは、次世代ウェブアプリケーションの開発において重要な役割を果たすと言えます。
しかしこれまでは、クッキーはユーザのブラウザにデータを保存するための最も一般的なメカニズムでした。ウェブ・アプリケーションがあるデータに繰り返しアクセスする必要がある場合、それを実行する方法は2つしかありません。
クッキー・メカニズムが提供できる記憶領域は限られており、最大4Kまたは4096バイトです。したがって、より大きなデータは4Kサイズのチャンクに分割され、明示的かつ直接的に管理されます。
しかし、このアプローチは、ストレージのコラボレーションと管理には明らかに実現不可能であり、新しい選択肢を考え出す必要があります。
クッキーは弱すぎる
ウェブブラウザは当初、アプリケーションがドキュメントコンテンツをロードできるように、単にHTTPを渡し、MLを解析していました。しかしその後まもなく、最初のNetscapeブラウザが登場し、多くの実用的なユーザニーズを満たしましたが、本質的にステートレスなTPプロトコルを使って状態追跡を可能にする何らかのメカニズムが必要でした。この問題に直面したMontulliは、1994年にブラウザクッキーを作成し、Mosiac Netscapeブラウザバージョン0.9bでデビューしました。
コモン・ゲートウェイ・インターフェイスとクッキーによって提供されたサーバーサイドのスクリプト・アクセスに助けられ、初期のウェブ・アプリケーションはついに現実のものとなりました。やがて、ブラウザをユニバーサル・アプリケーション・プラットフォームへと変貌させる足跡がたどり始めました。
しかし、クッキーのメカニズムには重大な欠点があります。前述したように、ごく少量のデータしか保存できず、さまざまな種類の攻撃を受けやすいため、個人情報や機密データの保存には使いにくく、利用範囲が大きく制限されます。
クッキーは、ブラウザからサーバに送信されるすべてのHTTPリクエストに関与しています。あるウェブページに4つのイメージ、外部のSS文書、pt文書があるとします。システムはドメインに対してクッキーを設定し、ブラウザはそのクッキーを4回サーバに転送します-MLページに対して1回、各イメージに対して1回、SS文書に対して1回、pt文書に対して1回です。
ほとんどのユーザは非同期のインターネット接続、すなわちアップロード速度はダウンロード速度より低いので、HTTPレスポンスヘッダでクッキーデータを転送することは、望ましくない帯域幅の使用につながります。
上記の制約により、ほとんどのクッキーは4Kよりはるかに小さくなっています。googleは、最適なパフォーマンスを実現するために、各クッキーの実際のサイズは400バイトを超えないようにすることを推奨しています。また、イメージ、CSS、JavaScriptのような独自のドメインからの静的ファイルに対しては、クッキーの仕組みを無効にすることを推奨しています。
ローカルストレージ空間におけるクッキーのメカニズムには問題があるため、物事を正しく設定し、仕事を成し遂げることを目的とした、数多くの新しいソリューションがあります。ここ数カ月で、2つのソリューションが最前線に登場し、W3Cによって強く推奨されています。
クライアントサイドのデータストレージには、主にWeb SQL、IndexedDB、Web Storage、Application Cacheの4つのメカニズムがあります。
Web SQL: データベースの作成と実行に特化
Web SQL は、データの保存にデータベースを使用し、検索タスクに SQL を使用する API で、最近では Safari、Chrome、Opera などの主要なブラウザが IndexedDB よりも Web SQL を選択しています。しかし 2010 年、SQLite は Web SQL で動作する唯一のデータベースでしたが、W3C はインストールベースの少なさを理由にこのソリューションのサポートを停止しました。
Web SQLの仕組みはとても新しいので、サンプルコードを一緒に見てみましょう。
Web SQLデータベースは、リレーショナル・データベースやSQLと非常によく似た操作感を持っています。このデータベースを使うための最初のステップは、データベースを作成して開くことです。データベースの追加セットを作成したくない場合は、すぐに使い始めることができ、API自体が自動的に作業を行います。
データベースの作成に使用されているコードの一部を見てみましょう:
var db = openDatabase('cats', '1.0',
'a catalog of my cats', 2 *1024 * 1024);
openDatabaseに続くパラメータは、左から順に、データベース名、バージョン番号、テキストの説明、予想されるデータベース・サイズを表します。
データベースが作成されたら、それを使い始めることができます。WebSQL データベース上で SQL を実行するのは、トランザクションオブジェクトを作成し、それを実行するのと同じくらい簡単です:
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE cats (id unique, name)');
tx.executeSql('INSERT INTO cats (id,name) VALUES (1,"Mr. Jones")');
});
Safari、Chrome、Opera、Mobile SafariはすべてこのAPIをサポートしていますが、Web SQLは2010年から変わっていないため、ローカルストレージの新しい標準になる可能性は低いでしょう。
ウェブストレージ:クッキーの最良のものを取り、最悪のものを取り除きます。
ウェブ・ストレージは、キーと値のペアをユーザーのブラウザに保存するという単純な方法を利用します。しかし、クッキーとの類似点はそこまでです。
- Web Storageは永続化スキームです。一度保存された値は、アプリケーションまたはユーザーによって明示的に削除されない限り、消えたり終了したりすることはありません。
- ウェブストレージは大容量のデータを扱うことができます。現在、ブラウザ全体のストレージ領域サイズは最大5MBです。
- Web Storageはサーバーに依存せず、データをサーバーに送信する必要がありません。もちろん、ローカライズされたデータストレージを実装し、好きなように非同期でサーバーと同期させることもできますが、Web Storageは常に優れたパフォーマンスを発揮し、オフラインでもオンラインでも機能します。
SessionStorage の目的は、現在のブラウザウィンドウに保存されたデータが、そのウィンドウでのみ利用できるようにすることです。例えば、電子商取引アプリケーションを使用する場合、SessionStorageを使用してユーザーのショッピングカート情報を記録することで、誤用による2回目の購入という事態を避けることができます。
次に、LocalStorageについて説明します。LocalStorageは、同じブラウザ内のウィンドウやタブ間で使用できるデータを保存する役割を担っています。Chromeで同じウェブサイトについて3つのウィンドウを開いた場合、3つとも同じLocalStorageコンテナを共有できます。一方、別々のコンテンツを持つWebサイトで3つのウィンドウを開くと、それぞれが別のコンテナを使用します。同様に、全員が同じウェブサイトを異なるブラウザで開いた場合、各ブラウザは独自のコンテナを使用する必要があるため、同じ共通の動作環境を共有することはできません。
新しいキーと値のペアを設定し、それらを取得するには、次のJavaScriptコマンドを使用できます:
//first set firstname equal to Sparky.
localStorage.setItem( "firstname", "Sparky" );
//next, get the value of firstname (hint, it will be Sparky).
localStorage.getItem( "firstname" );
この夏、Web Storage APIは正式にW3C Recommended Standardという栄誉を得ました。今後、Web Storageが、Cookieがその役割を果たすあらゆる分野の新しい処理ソリューションになる可能性は十分にあります。
しかし、Web Storageはそれ以上のことができます。データセットがそれほど大きくないのであれば、Web Storageは、ブラウザでキーと値のペアを設定したり取得したりする、おそらくクッキーよりも簡単な別の方法を提供します。
#p#
IndexedDB:検索可能でファイルサイズの制限がありません。
インデックス付きデータベースは、インデックス付きトランザクションデータベースを使用して、ユーザーのコンピュータにデータを保存し、インデックスを作成するためのAPIです。indexedDBは、単純なキーと値のペアのストレージメカニズムを使用するクッキーやWeb Storageが、より少なく解決しなければならないのに対し、より高速で繊細なデータの保存と検索をもたらします。
Web Storageと同様、IndexedDB APIはこの夏、W3Cの勧告候補リストの一員となり、Web標準に向けて大きな一歩を踏み出しました。
Web Storage と比較して、IndexedDB は 4 つの強化点をもたらします:
- インデックスされたデータを効率的に検索する機能。
- データベースは複数の値を1つのキーとして格納することができますが、キー・バリューのメカニズムでは、各キーは一意でなければなりません。
- トランザクションデータベースは、システムやアプリケーションの障害に対していくつかの保護を提供します。トランザクション処理が正しく完了しなかった場合、ロールバックによって回復されます。
- IndexedDB データベースは、データ内容のサイズに制限がありません。Firefox では、IndexedDB の実際のデータ保存制限はボリュームやディスクドライブ自体の容量制限に直接依存するのに対し、ブラウザはデータベースのサイズを 50MB 以上に増やす許可を求めます。
Safariを除く主要なブラウザはすでにIndexedDBをサポートしていますが、SafariはWeb SQLをサポートしているため、IndexedDBメザニンを使用してWeb SQLを通じてIndexedDBの機能と構文を実装することが可能です。
IndexedDB を使用するには、まずデータベースのセットを開きます。
var request = indexedDB.open("myDatabase");
データベースが作成されたら、ストレージ・オブジェクトを作成してデータを追加します。次のようなデータを追加する必要があるとします:
const petData = [
{ id: "00-01", firstname: "Butters", age: 2, type: "dog" },
{ id: "00-02", firstname: "Sammy", age: 2, type: "dog" }
];
次に、以下のコードでデータ保存機構を作成し、使用することができます。onupgradeneededの処理に注意してください。このメソッドはデータベースの構造を変更するときに必要です。
request.onupgradeneeded = function(event) {
var db = event.target.result;
var objectStore = db.createObjectStore("customers", {keyPath: "id"});
for (var i in customerData) {
objectStore.add(customerData[i]);
}
}
IndexedDB は大規模なデータベースの検索を専門としており、構造化データをクライアントに移動することでウェブアプリケーションのパフォーマンスを向上させることができます。IndexedDBは現在、W3Cの勧告レベルに非常に近く、すべてのブラウザプラットフォームで使用することができます。
アプリケーション・キャッシュ:オフライン・クライアント・ストレージの実現
Application Cache はキャッシュリストのセットを使用します。リストは非常にシンプルなテキスト文書で、キャッシュメカニズムによって処理されるべき、または処理されるべきではないすべてのリソースエントリをリストし、ブラウザに特定のファイルをダウンロードし、保存し、必要に応じて使用するように指示します。アプリケーションキャッシュ機構は現在、すべての主要なウェブブラウザでサポートされています。
Application Cache を使用するには、まず、キャッシュされたオブジェクトファイルを含む Web サイトに拡張子 .appcache のテキストファイルを保存する必要があります。使用する Web サーバーの種類によっては、.appcache ファイルがブラウザで正しく動作し、アプリケーション キャッシュ ファイルとして読み取れるように、カスタム MIME タイプを作成する必要があります。
キャッシュリストファイルの例を以下に示します:
CACHE MANIFEST
CACHE:
/css/styles.css
/js/javascript.css
/img/logo.gif
FALLBACK:
/img/weathertoday.png /img/weathernotavailable.png
NETWORK:
では、その内容を詳しく説明しましょう:
- CACHEセクションは、オフライン表示のためにどのリソースをキャッシュに置く必要があるかをブラウザに伝えるために使用されます。これらのファイルはキャッシュリストが変更されるまでキャッシュに残ります。この条件を覚えておくことが重要です。
- FALLBACKセクションは、どのファイルを表示すればキャッシュされていないリソースが置き換えられるかをブラウザに伝えるために使われます。例えば、上記の FALLBACK セクションでは、latestweather.png イメージが正しくダウンロードされなかった場合、現在の天候ではイメージをオフラインで表示できないことが推測できます。
- NETWORKセクションは、オンラインモードでのみ利用可能なリソースをブラウザに伝えるために使用します。末尾のアスタリスクは、どのネットワークリソースも現在キャッシュにないことを示します。
アプリケーションキャッシュは、正しく使えば欠点の少ない優れたツールです。正しく使用することで学ぶべき教訓があります:単純にあなたのサイトのすべてをキャッシュに追加した場合、訪問者はすぐにコンテンツが変更されないことに気づくでしょう。頻繁に変更されないコンテンツだけをキャッシュに残しておくか、キャッシュのリストを最新の状態に保ち、ファイルをアップロードした後にリストの新しいバージョンをリリースする努力をすれば、Application Cacheはオンラインモードと同じようにオフラインでもほとんど問題なく動作します。
ネイティブ・ブラウザ・ストレージはここ数年で大きな変貌を遂げました。さまざまなAPIやリファーラルで使用される名前が多様で類似しているため、何が使用可能で、何がそのうち廃止されるべきかを把握するのが難しくなっています。全体として、ブラウザのデータストレージにはさまざまなアプローチがあり、それぞれが確固たる地位を築いています。
いずれにせよ、開発者が単純な小さな名前と値のペアをクッキー経由でサーバに送るのに苦労する時代は終わりました。今日では、より多くの優れたソリューションがあります。