Mach3.laBlog

“Offline” – Alphabetical Advent Calendar 2013

この記事は賞味期限切れです。(更新から1年が経過しています)

“O” は Offline の “O”。

O

オフラインWebアプリケーション

旧来のいわゆる「Webアプリケーション」は、Webと繋がっていること、 つまりネットワークがオンラインになっている状態で利用する事が前提でしたが、 昨今では applicationCacheWeb Storage などを使用してオフラインでも動作する オフラインWebアプリケーションの構築も可能になってきています。

オフライン / オンラインの判定

まずはオンライン状態なのかオフライン状態なのかの確認ですが、 モダンな環境ならば navigator.onLine をチェックする事で出来る様です。

if(navigator.onLine){
    // online
} else {
    // offline
}

ただ、この onLine は実装されていない環境があったり、 元々このプロパティはブラウザの「オフライン作業」のチェックを確認する物だったようで、 いくつかの環境では期待する挙動をしません。

そこで、実際にネットワークにつながっていて目的の場所にアクセスできるかどうかを確認する為に 次のようなコードを書いてみます。

var checkOnline = function(){
    var xhr, online = true;
    xhr = new XMLHttpRequest();
    xhr.open("HEAD", "/", false);
    try { xhr.send(); }
    catch(e){ online = false; }
    return online;
};

checkOnline(); // ネットワークに繋がっていれば true 

XMLHttpRequest でWebサイトのルートのヘッダを取得して、失敗した場合に「オフラインである」とみなしています。

期待する navigator.onLine をサポートしているかどうかを判別するのが難しかった為、 polyfill ではなく別名の関数として定義してみました。 (上のコードでは XMLHttpRequest を素のまま使っていますが、 古いIE等のXHRをサポートしない環境にはその為の対応が必要です。)

また、online イベントのようにオンライン状態が変更された時に処理を行いたい場合は、 これを定期的に監視してみます。

var onOnlineStateChange = function(callback, interval){
    interval = interval || 8000;
    return setInterval(function(){
        var online = checkOnline();
        if(window.isOnline !== online){
            callback(online);
        }
        window.isOnline = online;
    }, interval);
};

var timer = onOnlineStateChange(function(online){
    console.log( online ? "オンラインです" : "オフラインです" );
});

8秒毎にチェックを行い、変更された場合に callback を実行します。 window を使ってグローバルを汚していますので注意が必要です。 また、きちんとイベントを発火させたい場合はもう少し長いコードになるでしょう。

オフラインWebアプリケーションをサポートする技術

applicationCache

applicationCache は、Webコンテンツのローカルキャッシュをコントロールする事が出来る機能で、 キャッシュマニフェストファイル(*.appcache)を用意して、HTML要素の manifest 属性に記載する事で使えるようになります。

<html manifest="myapp.appcache">

大まかな処理の流れとしては、ブラウザが myapp.appcache を読み込み、その中で指定されているファイルをローカルに保持し、 それらのファイルについてはネットワークにアクセスせずにローカルのキャッシュを使用するようになります。 つまりオフラインの状態でWebコンテンツが利用出来る様になるわけです。

ファイルの更新については少し注意が必要で、 キャッシュされたあとでリモートのファイルを更新しても、どこふく風でローカルのファイルを見続けてしまいます。

更新した事を通知する為には、 myapp.appcache の内容を更新する必要があります。 コメントで日付やバージョン等を記述しておくと更新を通知出来て都合がよさそうです。

CACHE MANIFEST
# version 2013-12-14 12:34
index.html
js/main.js
css/style.css

NETWORK:
*

マニフェストファイルの記法や注意事項などはこちらで。

Web Storage

Web Storage はブラウザから使用できるローカルのデータ保存領域で、 sessionStorage / localStorage として実装されています。 Cookie の様な物ですが利用可能な容量ははるかに大きく、モダンなデスクトップブラウザなら概ね 5M 程使う事ができます。 オフラインの場合にローカルに編集内容を保持しておいてオンラインになったらサーバに送って保存する、 といった使い方が期待されます。

sessionStorgae と localStorage はデータを保持する期間が異なる以外、使い方などはほぼ一緒です。

  • sessionStorage : タブ(あるいはウィンドウ)内のみで有効
  • localStorage : 永続的に有効

オフラインWebアプリケーションとしては localStorage が便利そうですね。 データの保存・取り出しは setItem / getItem を呼び出すだけの簡単設計です。

localStorage.setItem("foo", "bar");
localStorage.getItem("foo"); // "bar"

使い方・仕様などの詳細はこちらから。

参考資料

コメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*