Service Workerの概念と応用紹介

17838 ワード

Service workersは、本質的にはWebアプリケーションとブラウザとの間のプロキシサーバとして機能し、ネットワークが利用可能な場合はブラウザとネットワークとの間のプロキシとして機能してもよい.Service workerは、指定されたソースと経路の下に登録されているイベントドライバである.JavaScriptを用いて、関連ページまたはウェブサイトを制御し、アクセスおよびリソース要求を遮断し、修正し、リソースを細々とキャッシュする.特定のシナリオ(最も一般的な場合はネットワークが利用できない)でのアプリケーションの表現を完全に制御することができます.Service workerは、workerコンテキストで動作し、したがって、DOMにアクセスできない.駆動アプリケーションのメインJavaScriptスレッドに対して、他のスレッドで動作しているので、ブロックが発生しない.完全非同期のAPI(XHRおよびlocalStorageなど)はservice workerでは使用できないように設計されている.
セキュリティ上の観点からService workersHTTPSによってしか積載できません.何しろ、ネット上で要求された能力を修正して中間者に暴露するのは危険です.
service worker手順を使う
  • メインプロセスは、serviceWorker.register.( service work )を介して
  • を取得し、登録する.
    // js       main.js
    navigator.serviceWorker.register('sw.js')
          .then(function(registration) {
            console.log('Registered events at scope: ', registration.scope);
    });
    
  • 登録が成功すればservice workerServiceWorkerGlobalScope環境で実行される.これは、特別なタイプのwokerコンテキスト実行環境であり、メイン実行スレッド(実行スクリプト)とは独立しており、DOMにアクセスする能力もない.
  • service workerは、事件を処理することができます.
  • service workerによって制御されているページは、初めて開いた後にservice workerのインストールを試みる.service workerに最初に送信されたイベントは、インストールイベント(このイベントでパディングIndexDBおよびキャッシュサイトリソースが開始され得る)
  • である.
    // sw.js service worker   
    // self worker   
    self.addEventListener('install', function(event) {
      event.waitUntil( // ExtendableEvent.waitUntil()             。        ,                                   。
        caches.open('v1').then(function(cache) { // caches  service worker       
          return cache.addAll([
            '/sw-test/',
            '/sw-test/index.html',
            '/sw-test/style.css',
            '/sw-test/app.js',
            '/sw-test/image-list.js',
            '/sw-test/star-wars-logo.jpg',
            '/sw-test/gallery/bountyHunters.jpg',
            '/sw-test/gallery/myLittleVader.jpg',
            '/sw-test/gallery/snowTroopers.jpg'
          ]);
        })
      );
    });
    
  • installイベントの処理プログラムが実行された後、ServiceWorkerinstalled状態になり、メインスレッドに戻ってきたregistration.waiting属性はinstalled状態に入ったServiceWorker
  • を表している.
    navigator.serviceWorker.register('./sw.js').then(function(registration) {  
        if (registration.waiting) {
            // Service Worker is Waiting
        }
    })
    
  • 次のステップはアクティブです.service workerのインストールが完了したら、他のservice workerがなかったら、swは次の段階に進みます.もし以前にservice workerがあったら、このswは三つの状況を待っています.
  • は、新しいServiceWorkerスレッドコードにself.skipWaiting()
  • を使用しています.
  • またはユーザが別のウェブページにナビゲーションしているため、古いServiceWorkerが解放されたとき
  • または指定された時間が過ぎたら、以前のServiceWorker
  • が解放されます.
    次の段階に入ると、サブスレッド(例のsw.js)はアクティブイベントを受信する.activating段階の主な用途は、以前のバージョンのservice workerスクリプトで使用されたリソースを整理することである.
    const cacheStorageKey = '       '
    self.addEventListener('activate', function(e) {
      // active                 
      var cacheDeletePromises = caches.keys().then(cacheNames => {
        console.log('cacheNames', cacheNames, cacheNames.map);
        return Promise.all(cacheNames.map(name => {
          if (name !== cacheStorageKey) { //      key        key       
            console.log('caches.delete', caches.delete);
            var deletePromise = caches.delete(name);
            console.log('cache delete result: ', deletePromise);
            return deletePromise;
          } else {
            return Promise.resolve();
          }
        }));
      });
    
      console.log('cacheDeletePromises: ', cacheDeletePromises);
      e.waitUntil(
        Promise.all([cacheDeletePromises]
        )
      )
    })
    
    e.waitUntilが受信したPromiseが成功状態に入ると、ServiceWorkerのライフサイクルはactivated状態になる.このとき、メインスレッド内のregistrationactive属性は、activated状態に入るServiceWorkerの例を表している.
    navigator.serviceWorker.register('./sw.js').then(function(registration) {  
        if (registration.active) {
            // Service Worker is Active
        }
    })
    
  • Service Workカーは現在、ページをコントロールできます.この時、ブロックを要求する操作ができます.
    self.addEventListener('fetch', function(event) {
      event.respondWith(
      //  caches.match()     resolves  ,                  ,      undefined
    
        caches.match(event.request).then(function() {
          return fetch(event.request).then(function(response) {
            return caches.open('v1').then(function(cache) {
              cache.put(event.request, response.clone()); //      
              // clone   :              。                  ,         。            ,          。         。
              return response;
            });  
          });
        }).catch(function() {
          return caches.match('/sw-test/gallery/myLittleVader.jpg');
        })
      );
    });
    
    参照リンク:
    https://developer.mozilla.org/zh-CN/docs/Web/API/Service_ワーカーカーAPI/Using_Service_Worket.
    https://www.cnblogs.com/dojo-lzz/p/8047336.htm