「移動」オフライン:Webストレージ、アプリケーションキャッシュ、WebSQL

完全にオフラインで動作できるアプリケーションを作成するには、HTML5アプリケーションキャッシュ、Webストレージ、およびWebSQLの技術に精通する必要があります。
Web StorageHTML5 Application Cacheに関する紹介記事をすでに公開しています。 基本的な概念に精通していない場合は、それらを読むことをお勧めします。 この記事では、WebSQLを含むこれらのテクノロジーを改訂し、それらの共同効果的な使用のためのオプションについて説明します。 これらすべてのテクノロジーは、デスクトップバージョンのブラウザーOpera 11.10、Opera Mobile 11、WebKitエンジンに基づくブラウザー(iOSおよびGoogle Android)でサポートされています。

注:以下で説明するすべての例は、 このアーカイブで利用できます 。 記事を読んでいる間(当然ながら、オフラインで)アーカイブをダウンロードして例を見ることができます。

なぜ「オフラインモード」が必要なのですか?


Webページは単なるテキストではありません。 インターネットはますます普及しており、Webアプリケーションもそれぞれより複雑で洗練されています。 そして、それらへの依存度は高まっています。 Webアプリケーションが従来のデスクトップアプリケーションに代わって成功している例が増えてきています。その主な利点は、常にオフラインで平和に作業できることです。 Webアプリケーションに同じ機会を与えることは、必要な技術とツールの不足を許しませんでした。
しかし、彼らが来るとすべてが変わります...
しかし、今ではこれは問題ではありません! HTML5アプリケーションキャッシュ、Webストレージ、WebSQLなどの技術の出現により、Webアプリケーションをオフラインで動作させる方法がついに得られました。

ネットワーク接続が失われる理由は数多くあります。停電、ネットワーク機器の問題、携帯電話使用時の信号の欠落(または弱い)です。 開発者として、このような状況でも、Webアプリケーションが(少なくとも合理的な制限内で)正しく動作することを確認したいと考えています。

キャッシュ:ブートし、ネットワークがない場合


一般に、オンラインでない場合、サイトのページをロードまたはリロードするときにエラーが発生します。 最初に行うことは、ユーザーが接続なしでもページを表示してWebアプリケーションを操作できるようにすることです。 このモードでは、すべての画像、CSS、JavaScript、およびHTMLページ自体が正しく読み込まれます。
これは、アプリケーションキャッシュテクノロジー(AppCacheとも呼ばれます)を使用して実現されます。 これを使用するには、まずアプリケーションがオフラインで作業する必要があるファイルの名前を示すマニフェストファイルを宣言する必要があります。
demo.manifestファイルの例:
CACHE MANIFEST CACHE: logo.png style.css script.js jquery.js index.htm 

このマニフェストファイルに含まれるリンクが何であれ、対応するコンテンツはキャッシュされ、その後、このコンテンツへのアクセスは既に利用可能になります。 マニフェストファイルの宣言は非常に簡単です- <html>要素のmanifest属性を使用する必要があります。
 <html manifest="demo.manifest"> 

このファイルで宣言されたすべてのファイルはブラウザにキャッシュされます。 ユーザーがオフラインでページをロードしようとしても、このファイルに示されているすべてのリソースはブラウザーによってダウンロードされます。
HTML5 Application Cacheに関する記事で、より詳細な情報を見つけることができます。

データはどうですか?


AppCacheは、サイトの一部の要素のオフラインでのアクセシビリティの問題を解決しますが、ある程度のユーザーデータや、たとえば最新の検索を保存したい場合があります。 別のケースでは、より構造化されたデータを保存したい場合があります。 いずれにしても、Web StorageとWebSQLが最適なソリューションになります。

Web Storageを使用する


Web Storageは、巨大なデータテーブルよりも少量の情報を保存するのに最適です。これについては、この記事で簡単に説明し、例を検討します。 詳細については、 Web Storageに関する別の記事を参照してください。
頻繁な停電が頻繁に発生する場所はたくさんあります(翻訳者からの "Chubais、hello!:)")。 ユーザーは、電源を入れるまでインターネットで作業を続けることができるまで座って待つ必要があります。 そして、誰かが似たような状況にあり、どのサイトでも複数ページのフォームに記入し、ブログや重要なメールの大きな記事を入力していると想像してください。 停電中(またはバッテリー切れ)に、ユーザーはこのデータをすべて失います。 ネットワークに入った後、彼が保存していないすべてのレコードにアクセスし、それを使用して作業を続けることができたらいいと思いませんか?
プレーンな<textarea>テキストフィールドを含むページで何ができるか見てみましょう。 ページは、数秒ごとにローカルストレージに入力したすべてを保存する必要があります。ページがリロードまたは閉じると、ページはフィールドに保存されている最後のテキストをロードする必要があります。
ページにid "draft"の<textarea>フィールドが含まれているとしましょう:
 ... <textarea id="draft" rows="10" cols="30"></textarea> ... 

ローカルストレージに<textarea>の内容を保存する単純な関数を作成します。
 function saveMessage(){ var message = document.getElementById("draft"); localStorage.setItem("message", message.value) } 

保存間隔を0.5秒に設定します。
 setInterval(saveMessage, 500); 

注:ここでは、簡単にするためにsetInterval()を使用して、メッセージを0.5秒ごとにローカルストレージに保存しました。 (たとえば、ユーザーが何かを入力した場合にのみテキストフィールドの内容を保存するなど、この手順を改善できます)。

また、ページを開くかリロードするたびに、ローカルストレージ( localStorage )から最後に保存されたコンテンツがテキストボックスにロードされることを確認する必要があります。
 window.addEventListener("DOMContentLoaded", loadMessage, false); function loadMessage() { var textbox = document.getElementById("draft"); var message = localStorage.getItem("message"); if (!message) { textbox.value = ""; }else { textbox.value = message; } } 

Web Storage使用例をご覧ください。 これは一般的にシックです
実際には、ローカルに小さな情報を保存する必要がある場合です。

オフラインで作業しています


オフラインにするには、それを有効にする必要があります(Operaブラウザで:「メニュー」→「設定」→「オフラインで作業」または「ファイル」→「オフラインで作業」)。 ブラウザーがオフラインの場合、 navigator.onLineプロパティはfalse です 。それ以外の場合はtrueです。 ただし、多くの場合、イベントを使用することをお勧めします。 ユーザーがオフラインモードに切り替えると、 オフラインイベントがトリガーされます 。 これを使用して、オフラインになることに関する小さなメッセージを表示できます。
次のようなものが得られます。
 ... window.addEventListener( "offline", function(){showWarningDiv("on")}, false); window.addEventListener( "online", function(){showWarningDiv("off")}, false); ... function showWarningDiv(status){ var warningdiv = document.getElementById("warning"); if (status == "on"){ warningdiv.innerHTML = "<p style=\"padding:3px;\">Right now you are in offline mode. This message is saved and will be sent to the server the next time you are online.</p>"; } else { warningdiv.innerHTML = ""; } } 

注:現在、オフラインサポートはOperaとFirefoxでのみ利用可能です。

ユーザーがオフラインで作業しているときにフォームがデータを送信しようとしていないことを確認することは理にかなっています。 これを確認するには、次のようにします。
 ... window.addEventListener( "submit", submitForm, false); ... function submitForm(){ saveMessage(); if (!navigator.onLine){ return false; } } 

フォームデータを送信すると、 submitForm()関数を呼び出す送信イベントが発生します。 この関数は、最初にメッセージをローカルストレージに保存し、ユーザーがオフラインで作業している場合、データはどこにも送信されません。
この例を改良して、数秒ごとにサーバーにコピーを保存し、ユーザーが自分から誤ってデータを削除した場合に使用できるようにすることができます。 これは、仕事の場合、たとえば機密情報を扱う場合に特に重要です。たとえば、クレジットカード情報を自分の場所(ローカルストレージ)にのみ保存した​​い場合。
sessionStorageが情報を保存するために使用するより高度な例を参照してください。 (リロードしても)ページを閉じない場合、テキストボックスに入力したテキストはそのまま残ります。 また、ページはこのフィールドの内容を数秒ごとにサーバーに送信し、それに応じて、最後の保存の時刻を更新します。 このアプローチは、ブログエンジンとメールサービスで「ドラフト」を定期的に保存するために使用できます。これにより、接続の問題が発生しても作業を続けることができます。

WebSQL:まだ「スタブ」オフライン


Web Storageは少量の情報を保存するのに最適ですが、データベース全体を保存する場合はどうでしょうか? さまざまなデータベースクエリを作成し、検索できるWebアプリケーションはどうでしょうか。
ここでは、Web Storageを使用して展開することはできません-より信頼性の高いものが必要です。 すなわち-WebSQL。 WebSQLは、JavascriptとSQLの組み合わせを使用してデータを保存できるローカルSQLiteデータベースです。

WebSQLデータベースでの作業

まず最初に、ブラウザがWebSQLをサポートしていることを確認しますか? これは、 window.openDatabaseプロパティを使用して実行できます。
 if (window.openDatabase){ //rest of your code } else{ alert("It seems your browser does not have support for WebSQL. Please use a browser which does, otherwise parts of this application may not run as intended."); //or any other similar message } 

データベースを作成して開く

次のように、 openDatabaseコマンドを使用してデータベースを作成して開くことができます。
 var db = openDatabase("food_db", "1.0", "Web SQL Storage Demo Database", 1*1024*1024); // creates a database called 'food_db' with version number 1.0, description as 'Web SQL Demo Database' and a size of 1MB. 

「バージョン」1.0のfood_dbデータベースを作成し、サイズが1 MBの「Web SQL Storage Demo Database」の説明を追加しました。 db変数は、引き続き使用するデータベースオブジェクトへのポインターです。
注:データベースのサイズはバイト単位で設定されます。 したがって、サイズを1 * 1024 * 1024の形式で決定しました。これは1 MBです。 4 MBなどのサイズを設定する必要がある場合は、それぞれ4 * 1024 * 1024の値を指定する必要があります。

データベースを操作する

データベースを作成して開きました。 これで、SQLコマンドを使用してさまざまな操作を実行できます。 データベースオブジェクトのトランザクション()関数を呼び出すことで操作を実行します(この例ではdbです )。 彼女の呼び出しは、 executeSQL()を使用してさまざまなコマンドを実行するポインターとしてオブジェクトを返します。 このコマンドの構文は次のとおりです。
 executeSql(sqlStatement, arguments, callback, errorCallback); 

パラメーターのうち、 sqlStatementのみが必須で、残りはオプションです。
したがって、たとえば、テーブルを作成する場合、次のように記述する必要があります。
 ... db.transaction( function(t){ // This is the callback with "t" as the transaction object t.executeSql("CREATE TABLE IF NOT EXISTS cal_list (food_name TEXT PRIMARY KEY, calories REAL, servings TEXT)"); } ); ... 

このコードは、フィールドfood_namecalories 、およびservingsを持つテーブルcal_list (存在しない場合)を作成します。

テーブルへのレコードの追加

テーブルにレコードを追加するためのクエリの実行は、WebSQLの簡単なタスクです。 例を考えてみましょう:
 var food_name = "pizza"; var amount_of_calories = 320; var serving_size = "one slice"; db.transaction( function(t){ t.executeSql("INSERT INTO cal_list VALUES (?, ?, ?)", [food_name, amount_of_calories, serving_size]); } ); 

最初の疑問符はfood_nameパラメーターによってエスケープされ、2番目はamount_of_caloriesによってエスケープされ、3番目はserve_sizeによってエスケープされます 。 このコードは、値がpizza320および1つのスライスに対応する列を含むエントリをcal_listテーブルに追加します。
別のリクエストを実行してみましょう-データを受信します:
 var min_cal_amount = 300; ... t.executeSql("SELECT * FROM cal_list WHERE calories > ?", [min_cal_amount]); 

このコードはクエリを実行して、 カロリー値が300を超えるすべての行を選択します。疑問符はmin_cal_amount変数をエスケープします。

クエリ結果の処理

さて、ここで、データを記録したテーブルを備えたデータベースを作成しました。次に、結果を照会して表示したいと思います。 通常、1つのSQLクエリに対して多数の結果を取得します。これらの結果を何らかの方法で処理して、テーブルまたは他の構造化されたフォームでページに表示する必要があります。 executeSQL()関数の3番目のパラメーターは、クエリの成功を決定します。 以下は、結果を処理する例です。
 var list = document.getElementById("thelist"); var food; var min_cal_amount = 400; var serving_size; db.transaction( function(t){ t.executeSql("SELECT food_name AS food, calories AS amount_of_calories, servings as serving_size FROM cal_list where calories > ?" ,[min_cal_amount], function(t,r){ for (var i=0; i < r.rows.length; i++){ food = r.rows.item(i).food; amount_of_calories = r.rows.item(i).amount_of_calories; serving_size = r.rows.item(i).serving_size; list.innerHTML +="<li>"+food+" has "+amount_of_calories+" KCAL worth of calories.</li>"; } }, function(t,e) {alert(e.message);}) } ); 

まず、 r.rows.lengthを介してリクエストの結果として要素の数を決定し、0からこの値に進みます。 各アイテムはr.rows.item(i)からアクセスできます。iは行番号です。 列名も同じ方法で取得できます。 food列の値を取得するには、 r.rows.item(i).foodなどを他の列に使用します。

すべてを一度に使用します


Web Storage、Application Cache、およびWebSQLを一緒に使用することもできます。 可能性はありますが、すべて解決する必要のあるタスクに依存します。 たとえば、一部のユーザー設定のみを保存する場合、WebSQLを使用することは不要です。 このような目的には、Webストレージが最適です。
ただし、大量のデータがあり、何らかの方法で処理する必要がある場合は、WebSQLを使用する方が論理的です。
3つのテクノロジーすべてを一緒に使用するカロリーのサンプルページにアクセスしてください。データベースはWeb Storageに格納されているため、ページを閉じたりリロードしたりしても検索できます。AppCacheとWebSQLを使用してオフラインで作業できます。
注: opera:webdatabasesリンクをクリックすると、Operaで使用されているデータベースに関する情報を個別に取得して管理できます。 また、Web Storageを使用してブラウザにデータを保存するドメインに関する情報を取得し、 opera:webstorageリンクをクリックして管理します。

待ってください... WebSQL仕様は承認されていますか?


まだ決まっていない。 ただし、このテクノロジーをブラウザーとデバイスのリストに既に適用できます。 このようなクロスプラットフォームのサポートがないIndexedDBについて言えないこと。 仕様の承認を待つことだけが残りますが、それはすぐに起こります。
FirefoxやInternet Explorerなどの一部のデスクトップバージョンのブラウザーはWebSQLをサポートせず、IndexedDBで動作することに注意することも重要です。 この場合、最初にWebSQLを使用できるのは、スマートフォン用のオフラインデータストレージです。OperaMobile 11ブラウザーとAndroidおよびiOSプラットフォーム用のWebKitブラウザーがサポートされています。
WebSQLの良い点は、ブラウザでスタンドアロンデータベースを作成するための便利なツールを提供することです。 簡単に習得して使用でき、複数のブラウザですぐに動作するスタンドアロンのWebアプリケーションを迅速に開発できます。

おわりに


Webアプリケーションは現在、アプリケーションキャッシュ、Webストレージ、WebSQLデータベースなどのテクノロジーを使用して、完全に自律的なモードで動作する機会を持っています。 ファイルをオフラインで使用するには、ファイルをキャッシュするためのアプリケーションキャッシュが必要です。 Web Storageは少量の情報を保存するためのものですが、WebSQLは大量のデータを操作するための便利なツールになります。 開発者は、ニーズに応じて、これらのテクノロジーのさまざまな組み合わせを使用して、スタンドアロンアプリケーションを作成できます。


この技術は有望です。 そして、いつものように、レースがあります... WebSQLとIndexedDB、それらの言及すでにハブにありました 彼らが世界をより良い場所にできるように:)

psいつものように、翻訳に関するすべてのコメントは午後に受け入れられます。
ppsどこかで、「Webストレージ」から「ローカルストレージ」にスムーズに移動したようです。 何かを残す方が良いですか? ;)

Source: https://habr.com/ru/post/J117123/


All Articles