web-dev-qa-db-ja.com

ServiceWorkerのフェッチイベントは発生しません

質問のタイトルがすべてを物語っています。

_if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/react-redux/sw.js').then(() => {
        console.log('registered');
    }, err => console.log(err));
}
_

編集

問題の根本はパスにあるようです

_navigator.serviceWorker.register('/react-redux/sw.js')
_

swコードを移動すると、

_navigator.serviceWorker.register('swRoot.js').then(() => {
_

その後、すべてが正しく動作します。/react-reduxの先頭のスラッシュを削除することから、_{scope:_、_'./'_、_'/'_の_'/react-redux'_を追加することまで、上記で考えられるすべてのことを試しました。何も機能しませんでした(いくつかの原因となるエラーがあります)。

ドメインのルート以外の場所からServiceWorkerをロードできるようにするために必要な構成マジックを知っている人はいますか?


そして私のsw.js全体

_self.addEventListener('install', function(event) {
    console.log('hello');
    try {
        console.log('typeof System in install', typeof System);
    } catch(e){}

    console.log('caching');
    event.waitUntil(
        caches.open('v1').then(function(cache) {
            console.log('caching - getting');
            return cache.addAll([
                '/react-redux/a.js'
            ]);
        }).catch(function(error){ console.log('error', error) })
    );
});

console.log('ADDING FETCH')
self.addEventListener('fetch', function(event) {
    console.log('fetching ->', event.request);
    event.respondWith(
        caches.match(event.request)
                .then(function(response) {
                    // Cache hit - return response
                    if (response) {
                        return response;
                    }
                    return fetch(event.request);
                })
    );
});
_

console.log('fetching ->', event.request);メッセージが表示されることはありません。私はこの愚かさを追加して、問題を強制しようとしました。

_setTimeout(() => fetch('/react-redux/foo.css').then(r => console.log(r)), 1000);
setInterval(() => fetch('/react-redux/foo.css').then(r => console.log(r)), 5000);
_

フェッチイベントが実行されているのがわかりますが、サービスワーカーは、それらのイベントハンドラーにヒットしているとは決して言いません。

さらに、私はdo SWが登録されているという通知を受け取り、sw.jsを更新して閉じて再度開くと、すべてのログステートメントが正しくインストールされていることを示しています。

11
Adam Rackis

あなたは正しい方向に進んでいます、それはスコーピングの問題のようです。

Service Workerのスコープを変更するには、登録時に次のように行う必要があります。

navigator.serviceWorker.register('scripts/sw.js', { scope: '/' })

次に、サーバーは、このスコープの変更を確認するために、応答で次のヘッダーを返す必要があります。

Service-Worker-Allowed: /

この回答を参照

4
Derek

フェッチインターセプトを機能させるには、登録されたサービスワーカーが、ワーカーを登録しているHTMLファイルを含むツリーのレベル以上である必要があるようです。以下は失敗します。

Chromeでは、必ず「アプリケーション」の下の「ServiceWorker」を確認してください。以下で登録しても、Service Workerがアクティブ化されて実行されますが、場所がHTMLページ以上の場合は、[クライアント]の下にエントリが表示されます。これの存在は、フェッチがインターセプトされるタイミングに正確に対応しているようです。

3
Andy Valencia

fetchイベントハンドラー内にinstallイベントリスナーをアタッチします

self.addEventListener('install', function(event) {
  console.log("install");
  try {
    console.log('typeof System in install', typeof System);
  } catch (e) {}

  console.log('caching');
  event.waitUntil(
    caches.open('v1').then(function(cache) {
      console.log('caching - getting');
      return cache.addAll([
        'a.js'
      ]);
    }).catch(function(error) {
      console.log('error', error)
    })
  );

  self.addEventListener('fetch', function(event) {
    console.log('fetching ->', event.request);
    event.respondWith(
      caches.match(event.request)
      .then(function(response) {
        // Cache hit - return response
        if (response) {
          return response;
        }
        return fetch(event.request);
      })
    );
  });
});

plnkr https://plnkr.co/edit/WuJCZSD0V4idG1Ra7VMb?p=preview

3
guest271314