LoginSignup
11
15

More than 5 years have passed since last update.

Service Workerを使ってみた。

Posted at

やりたいこと

とにかくService Workerを使ってみたい。
とりあえずウェブページをオフラインでも見れるようにしたい。

Service Workerについて

Service Workerはクライアントとサーバ間の通信を監視するプロキシの働きをする。
Service Workerのグローバルオブジェクトはwindowではない。
そのため、DOM操作ができないなど一般的なJavaScriptとは若干異なっている(console.logはつかえた)。
初めて見る関数いっぱい。

将来的にPush APIなどクライアント端末の低レイヤの機能も使えるようになるらしい。
(Pushは今も使えるけど使い勝手が悪いらしい。)

まだ先人のノウハウがあまりない。MDNのページも翻訳されてない。
頑張ってちょこちょこ翻訳してるけどどうも日本語がおかしい気がする。

HTTPSかローカルホストでないと動作しない。HTTPはセキュリティ上使えない。
デバッグがめんどくさいのでシークレットウインドウで作業したほうがよい。

コード

// script.js
/* Service Workerの登録 */
if("serviceWorker" in navigator)
{
  navigator.serviceWorker.register("/sw.js");
};
// sw.js
/* Service Workerのグローバルオブジェクトでは外部スクリプト読み込みの関数がデフォルトで存在する。 */
importScripts("https://raw.githubusercontent.com/coonsta/cache-polyfill/master/index.js");

/**
 * Service Workerインストール時の関数
 * ==========
 * オフライン時、キャッシュに登録されていないURLにアクセスした場合に表示するHTMLを取得する。
 * オンライン時にこのファイルにアクセスすることがないため。
 */
addEventListener("install", function(event)
{
  event.waitUntil(
    caches.open("myCache")
      .then(function(cache)
      {
        return cache.addAll(["/nodata.html"]);
      })
  );
});

/**
 * スコープ内でファイル取得のリクエストが飛んだ時の関数
 * スコープはService Workerのjsファイル以下のディレクトリになる。
 * serviceWorker.register()時に明示的に指定することもできる。
 * ==========
 * 1. オンライン時は普通にファイルを取得させ、キャッシュにも保存させる。
 * 2. オフライン時はキャッシュされているファイルを返すようにする。
 * 3. リクエストしたURLに対応するファイルがキャッシュにない場合は、インストール時に登録したnodata.htmlを返す。
 */

addEventListener("fetch", function(event)
{
  var online = navigator.onLine;

  if(online)
  {
    /* 1 */
    event.respondWith(
      fetch(event.request)
        .then(function(response)
        {
          if(!response || response.status != 200) return;

          caches.open("myCache")
            .then(function(cache)
            {
              cache.put(event.request, response);
            });
        })
    );
  }
  else
  {
    event.respondWith(
      caches.match(event.request)
        .then(function(response)
        {
          /* 2 */
          if(response)
          {
            return response;
          }
          /* 3 */
          else if(event.request.context == "internal")
          {
            return caches.match("/nodata.html")
              .then(function(responseNodata)
              {
                return responseNodata;
              });
          }
        })
    );
  }
});
11
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
15