<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Offline &#8211; Mach3.laBlog</title>
	<atom:link href="https://blog.mach3.jp/tag/offline/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.mach3.jp</link>
	<description></description>
	<lastBuildDate>Sat, 14 Dec 2013 01:39:21 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>
	<item>
		<title>&#034;Offline&#034; &#8211; Alphabetical Advent Calendar 2013</title>
		<link>https://blog.mach3.jp/2013/12/14/jaac2013-o-offline.html</link>
		
		<dc:creator><![CDATA[mach3]]></dc:creator>
		<pubDate>Sat, 14 Dec 2013 01:39:21 +0000</pubDate>
				<category><![CDATA[Laboratory]]></category>
		<category><![CDATA[Advent Calendar 2013]]></category>
		<category><![CDATA[applicationCache]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Offline]]></category>
		<category><![CDATA[Web Storage]]></category>
		<guid isPermaLink="false">http://blog.mach3.jp/?p=3732</guid>

					<description><![CDATA[&#8220;O&#8221; は Offline の &#8220;O&#8221;。 オフラインWebアプリケーション 旧来のいわゆる「Webアプリケーション」は、Webと繋がっていること、 つまりネットワークがオン [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>&#8220;O&#8221; は Offline の &#8220;O&#8221;。</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh5.googleusercontent.com/-zOrs4xHvFEA/UqR4jppiyGI/AAAAAAAACYg/lZZfJorxJ-I/s400/ac2013-o.png" alt="O"/></figure>



<p></p>



<span id="more-3732"></span>



<h2 class="wp-block-heading">オフラインWebアプリケーション</h2>



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



<h2 class="wp-block-heading">オフライン / オンラインの判定</h2>



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


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">if</span>(navigator.onLine){
    <span class="hljs-comment">// online</span>
} <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// offline</span>
}
</code></span></pre>


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



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


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">var</span> checkOnline = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
    <span class="hljs-keyword">var</span> xhr, online = <span class="hljs-literal">true</span>;
    xhr = <span class="hljs-keyword">new</span> XMLHttpRequest();
    xhr.open(<span class="hljs-string">"HEAD"</span>, <span class="hljs-string">"/"</span>, <span class="hljs-literal">false</span>);
    <span class="hljs-keyword">try</span> { xhr.send(); }
    <span class="hljs-keyword">catch</span>(e){ online = <span class="hljs-literal">false</span>; }
    <span class="hljs-keyword">return</span> online;
};

checkOnline(); <span class="hljs-comment">// ネットワークに繋がっていれば true</span>
</code></span></pre>


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



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



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


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">var</span> onOnlineStateChange = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">callback, interval</span>)</span>{
    interval = interval || <span class="hljs-number">8000</span>;
    <span class="hljs-keyword">return</span> setInterval(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
        <span class="hljs-keyword">var</span> online = checkOnline();
        <span class="hljs-keyword">if</span>(<span class="hljs-built_in">window</span>.isOnline !== online){
            callback(online);
        }
        <span class="hljs-built_in">window</span>.isOnline = online;
    }, interval);
};

<span class="hljs-keyword">var</span> timer = onOnlineStateChange(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">online</span>)</span>{
    <span class="hljs-built_in">console</span>.log( online ? <span class="hljs-string">"オンラインです"</span> : <span class="hljs-string">"オフラインです"</span> );
});
</code></span></pre>


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



<h2 class="wp-block-heading">オフラインWebアプリケーションをサポートする技術</h2>



<h3 class="wp-block-heading">applicationCache</h3>



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


<pre class="wp-block-code"><span><code class="hljs language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">manifest</span>=<span class="hljs-string">"myapp.appcache"</span>&gt;</span>
</code></span></pre>


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



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



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


<pre class="wp-block-code"><span><code class="hljs language-php">CACHE MANIFEST
<span class="hljs-comment"># version 2013-12-14 12:34</span>
index.html
js/main.js
css/style.css

NETWORK:
*
</code></span></pre>


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



<ul class="wp-block-list">
<li><a href="https://developer.mozilla.org/ja/docs/Web/HTML/Using_the_application_cache">アプリケーションキャッシュの使用 &#8211; HTML | MDN</a></li>
</ul>



<h3 class="wp-block-heading">Web Storage</h3>



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



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



<ul class="wp-block-list">
<li><strong>sessionStorage</strong> : タブ（あるいはウィンドウ）内のみで有効</li>



<li><strong>localStorage</strong> : 永続的に有効</li>
</ul>



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


<pre class="wp-block-code"><span><code class="hljs language-javascript">localStorage.setItem(<span class="hljs-string">"foo"</span>, <span class="hljs-string">"bar"</span>);
localStorage.getItem(<span class="hljs-string">"foo"</span>); <span class="hljs-comment">// "bar"</span>
</code></span></pre>


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



<ul class="wp-block-list">
<li><a href="https://developer.mozilla.org/ja/docs/DOM/Storage">DOM Storage &#8211; DOM | MDN</a></li>



<li><a href="http://dev.w3.org/html5/webstorage/">Web Storage</a></li>
</ul>



<h2 class="wp-block-heading">参考資料</h2>



<ul class="wp-block-list">
<li><a href="https://developer.mozilla.org/ja/docs/Online_and_offline_events">Online and offline events | MDN</a></li>



<li><a href="https://developer.mozilla.org/ja/docs/Web/HTML/Using_the_application_cache">アプリケーションキャッシュの使用 &#8211; HTML | MDN</a></li>



<li><a href="https://developer.mozilla.org/ja/docs/DOM/Storage">DOM Storage &#8211; DOM | MDN</a></li>



<li><a href="http://dev.w3.org/html5/webstorage/">Web Storage</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
