サービスワーカーの基本知識


前書き:service workerを説明する文章を見ましたが、基本的にはいいです.だから、転じて自分の参考にします.
Service Workカーは何ですか?
service workerは、現在のページから独立してブラウザのバックグラウンドプロセスで実行されるスクリプトです.その特性は、プッシュメッセージ、バックグラウンド同期、geoffecng(地理的なフェンス位置)、ブロッキング、およびネットワーク要求を処理することを含むだろう.
このAPIが人を興奮させる原因は、あなたのアプリケーションを先にローカルキャッシュリソースにアクセスさせることができるので、オフラインの状態においては、ネットワークを通じてより多くのデータを受信する前に、基本的な機能を提供することができるからです.
サービスワーカーの前にAPP Cacheという別のアプリもオフライン体験ができます.APP Cacheの主な問題はピットが比較的多いことであり、それは単にページのwebアプリケーションに適合するように設計されています.伝統的な複数ページのウェブサイトには不向きです.service workerのデザインはこれらの痛みを避けました.
サービスワーカーに関するいくつかの注意点:
  • serviceワーカーはJavaScriptワーカーですので、直接DOMにアクセスできません.しかし、service workerは、必要なときにDOMを操作するように、postMessageインターフェースを介して関連するページと通信し、メッセージを送信することができる.
  • Service workerはプログラム可能なネットワークエージェントであり、どのようにページのネットワーク要求を処理するかを制御し、fetch要求を処理することができます.
  • Service workerは使用しないと終了され、必要な時に再起動されますので、Onfetchとonmessageイベントをグローバル依存処理プログラムとして使用することはできません.もし長い時間が必要なら、いくつかの情報を再起動してService workerを使って、IndexedDB API、service workerを使ってもいいです.
  • Service Workカーのキャッシュメカニズムは、Cache APIに依存して実現されるService workerがpromiseを広く使用している.
  • ServiceワーカーはHTML 5 fetch API
  • に依存しています.
  • Service Workersは、HTTPSの下でなければ
  • を実行できないと要求しています.
    Service Workerライフサイクル
  • service workerを登録して、ウェブページの上で効力を発揮します.
  • インストールに成功しました.アクティブまたはインストールに失敗しました.
  • がアクティブになったら、swの役割領域ですべてのページをアクティブにします.最初の制御swは有効になりません.次のページを読み込むと有効になります.
  • swアクティブページの後、fetch(ネットワーク要求)とメッセージ(ページメッセージ)イベントを処理したり、メモリを節約したりします.
  • 事前に把握する必要があるAPI
  • Cache APIは基本的に
  • を使用します.
  • (1)appiが存在するかどうかを検出する
  • if('caches' in window) {
            // Has support!
        }
  • (2)caches.openは、キャッシュの合計オブジェクトを作成する.test-cacheというキャッシュを次のように作成します.
  • caches.open('test-cache').then(function(cache) {
            // Cache is created and accessible
        });
  • (3)cache.addとcache.addAllは、キャッシュ内容を追加する.cache.addは一つだけ追加し、cache.addAllは複数を追加することができる.
  • caches.open('test-cache').then(function(cache) { 
            cache.addAll(['/', '/images/logo.png'])
            .then(function() { 
            // Cached!
            
            // or use cache.add
            cache.add('/page/1');  // "/page/1" URL will be fetched and cached!
         });
        });
  • (4)cache.keys()は、キャッシュされたデータ
  • を確認する.
    caches.open('test-cache').then(function(cache) {
            cache.keys().then(function(cachedRequests) {
                console.log(cachedRequests); // [Request, Request]
            });
        });
  • (5)cache.matchとcache.match Allはキャッシュファイルパス
  • と一致する.
    caches.open('test-cache').then(function(cache) {
            cache.match('/page/1').then(function(matchedResponse) {
                console.log(matchedResponse);
            });
        });
    (6)cache.delete、キャッシュを削除します.
    caches.open('test-cache').then(function(cache) {
           cache.delete('/page/1');
       });
  • Fetch APIは基本的に
  • を使用します.
    // url (required), options (optional)
    fetch('https://davidwalsh.name/some/url', {
        method: 'get'
    }).then(function(response) {
         
    }).catch(function(err) {
        // Error :(
    });
    ここでoptionsオブジェクトには以下の属性があります.
  • method-GET,POST,PUT,DELETE,HEAD
  • url-要求のリンク
  • headers−要求されたheaderオブジェクト
  • referrer−要求されたreferrerオブジェクト
  • mode-cos、no-cords、same-orign
  • credentials-設定要求は、cookie
  • を携帯することができますか?
  • redirect-follow,error,manaual
  • integrity-サブリソース完全値
  • cache-キャッシュモード(default、reload、no-cache)
  • Requestオブジェクトの例は、fetchにおいて伝えられ得る.
    var request = new Request('https://davidwalsh.name/users.json', {
        method: 'POST',
        mode: 'cors',
        redirect: 'follow',
        headers: new Headers({
            'Content-Type': 'text/plain'
        })
    });
     
    // Now use it!
    fetch(request).then(function() { /* handle response */ });
    指定されたResponseオブジェクトの例で、ここでのoptionsには次のようなものがあります.
  • type-baic,cos
  • url
  • use Final URL-上のurlパラメータは最終URL
  • ですか?
  • status-状態コード(ex:200,404,etc.)
  • ok-成功したかどうか(範囲は200-239)
  • status Text-ステータスコード(ex:OK)
  • headers応答のheadersオブジェクト
  • また、Resonseの例は、以下の方法を備える.
  • clone()-Resonseオブジェクトのクローンを作成します.
  • error()-ネットワークエラーに関連した新しいResonseオブジェクトを返す.
  • redirect()−異なるURLを用いて新しい応答を作成する.
  • arrayBuffer()-ArayBufferを用いて解析されたpromiseを返す.
  • blob()-Blob解析を用いたプロミスを返す.
  • formData()-FormDataオブジェクトを用いて解析したプロミスを返します.
  • json()-JSONオブジェクト解析を用いたプロミセを返す.
  • text()-USVstingを用いて解析されたプロミセを返す.
  • // Create your own response for service worker testing
    // new Response(BODY, OPTIONS)
    var response = new Response('.....', {
        ok: false,
        status: 404,
        url: '/'
    });
     
    // The fetch's `then` gets a Response instance back
    fetch('https://davidwalsh.name/')
        .then(function(responseObj) {
            console.log('status: ', responseObj.status);
        });
    Service Workカーの使用
  • 互換性の低いバージョン、Cache APIに注入されたpolyfill、Service WorkカーはCache APIに依存する必要がある:
  • self.importScripts('./serviceworker-cache-polyfill.js');
  • 登録サービスワーカー:
  • if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/sw.js').then(function(registration) {
        // Registration was successful
        console.log('ServiceWorker registration successful with scope: ',    registration.scope);
      }).catch(function(err) {
        // registration failed :(
        console.log('ServiceWorker registration failed: ', err);
      });
    }
    上のコードはservice worker APIが利用可能かどうかを確認します.もし利用可能であれば、このファイルはservice workerとして登録されます.
    このservice workerが登録されていると、ブラウザは上のコードを自動的に無視します.
    特に注意したいのはサービスワーカーファイルのパスです.この例では、service workerファイルはこのドメインのルートディレクトリに置かれています.これはservice workerがウェブサイトと同じソースであることを意味します.言い換えれば、このservice workerはこのドメインのすべてのfetchイベントを取得します.service workerファイルが/example/sw.jsに登録されている場合、service workerは/example/経路下のfetchイベントしか受信できません.
  • Service workerをインストールする:
  • var CACHE_NAME = 'my-site-cache-v1';
    var urlsToCache = [
      '/',
      '/styles/main.css',
      '/script/main.js'
    ];
     
    self.addEventListener('install', function(event) {
      // Perform install steps
      event.waitUntil(
        caches.open(CACHE_NAME)
          .then(function(cache) {
            console.log('Opened cache');
            return cache.addAll(urlsToCache);
          })
      );
    });
    上のコードはキャッシュが必要な内容を宣言しました.すべてのファイルがキャッシュされたら、サービスワーカーはインストールに成功しました.いずれのファイルのダウンロードに失敗した場合、インストール手順は失敗します.この方法はあなたの指定したリソースに依存しますが、これはどのファイルがキャッシュされる必要があるかを非常に詳細に確認する必要があります.多すぎるファイルを指定すると失敗率が増加します.
  • によるキャッシュと返却要求の処理
  • self.addEventListener('fetch', function(event) {
      event.respondWith(
        caches.match(event.request)
          .then(function(response) {
            // Cache hit - return response
            if (response) {
              return response;
            }
     
        // IMPORTANT: Clone the request. A request is a stream and
        // can only be consumed once. Since we are consuming this
        // once by cache and once by the browser for fetch, we need
        // to clone the response
        var fetchRequest = event.request.clone();
     
        return fetch(fetchRequest).then(
          function(response) {
            // Check if we received a valid response
            if(!response || response.status !== 200 || response.type !== 'basic') {
              return response;
            }
     
            // IMPORTANT: Clone the response. A response is a stream
            // and because we want the browser to consume the response
            // as well as the cache consuming the response, we need
            // to clone it so we have 2 stream.
            var responseToCache = response.clone();
     
            caches.open(CACHE_NAME)
              .then(function(cache) {
                cache.put(event.request, responseToCache);
              });
     
            return response;
          }
        );
      })
    );
    キャッシュに新しい要求キャッシュを追加したいなら、fetch要求のレスポンスを処理してキャッシュに追加すればいいです.コードの中で私達は以下のことをしました.
    fetchにcalbackを追加します.then方法で.一旦私たちはレスリングを取得したら、次のような検査を行います.
    1.レスポンスの有効性を確保する2.レスポンスの状態を確認するのは2003.レスポンスの種類を確保するのはバックタイプであり、これは要求が同源であり、第三者の要求がキャッシュされないことを意味する.
    検査が通ればcloneという要請があります.その理由は、レスポンスがStreamであれば、そのbodyは一回しか消費されないからです.ですから、ブラウザとキャッシュをこのbodyを使うためには、このbodyをクローンしてブラウザに送り、キャッシュに入れます.
    再起動
    あなたのservice workerはいつか更新します.その時、以下の手順で更新する必要があります.
  • あなたのservice workerのJavaScriptファイルを更新します.ユーザがあなたのウェブサイトをブラウズする時、ブラウザはバックグラウンドでservice workerのスクリプトファイルを再ダウンロードしようと試みます.比較してみると、サーバー上のファイルとローカルファイルのバイトが違っている限り、このファイルは新しいと思います.
  • 以降に更新されたサービスワーカーが起動し、installイベントをトリガする.この時、現在のページで有効になっているのは依然として古いバージョンのサービスワーカーです.新しいサービスワーカーは「waiting」状態に入ります.
  • ページが閉じると、古いservice workerが消され、新しいservicer workerがページを引き継ぎ、新しいservice workerが有効になるとactivateイベントが発生します.通常、activateのcalbackでcache管理を行い、古いcacheを整理する必要があります.私たちがactivateでinstallではない時に行う原因は、installの時に整理すれば、古いservice workerはまだコントロールページにあります.彼らが依存しているキャッシュは失効して、突然停止されます.
  • 以前使っていたキャッシュはmy-site-cache-v 1といいます.これを複数のキャッシュに封をして、ページに使います.ブログの文章に使います.これは、installのステップで、私たちは二つのキャッシュを作成します.pages-cache-v 1とblog-posts-cache-v 1.activite手順では、古いmy-site-cache-v 1を削除します.
    下のコードはキャッシュを巡回して、cacheWhitelist配列にないキャッシュを削除します.
    self.addEventListener('activate', function(event) {
     
      var cacheWhitelist = ['pages-cache-v1', 'blog-posts-cache-v1'];
     
      event.waitUntil(
        caches.keys().then(function(cacheNames) {
          return Promise.all(
            cacheNames.map(function(cacheName) {
              if (cacheWhitelist.indexOf(cacheName) === -1) {
                return caches.delete(cacheName);
              }
            })
          );
        })
      );
    });