web-dev-qa-db-ja.com

同じServiceWorkerが複数のページに登録されないようにするにはどうすればよいですか?

複数のサイトレベルで繰り返し登録しているServiceWorkerスクリプトがあります。

つまり、同じサービスワーカーがwww.site.ca/、www.site.ca/text-text、www.site.ca/example-exampleなどに登録されています。

このサイトはphp上に構築されており、コンテンツに応じて異なるURLが生成されるため、APIのようなものです。サービスワーカーの登録がこれらのページにある理由は、サイトトラフィックのほとんどがホームページではなくこれらのページに到達するためです。その結果、同じサービスワーカーが、異なるページで異なるIDで登録されます。

複数のサブレベルで同じスクリプトが複数登録されるのを防ぐ方法はありますか?

編集:

Service Workerの目的は、ユーザーがサイトにいない場合でも通知を設定することです。また、私が抱えている問題は、更新するコピーが複数あるため、将来のServiceWorkerの更新の試みに悪影響を及ぼします。その結果、ユーザーが特定のページに再びアクセスしたときに、更新されるコピーは1つだけになります。そのServiceWorkerファイルのすべてのコピーが更新されるという保証はありません。また、複数のコピーの結果、ユーザーはサイトから通知のスタックを受け取ることになり、問題が発生します。

編集:

以下は私がこれまでに持っているものであり、私の理解の範囲はそれが登録される場所を定義します。ただし、問題は、人がサイトに入る場所ならどこでも登録できる必要があるため、スコープが「/」に設定されていることです。

私が解決したい問題は、同じServiceWorkerファイルの後続のレジスタを防ぐことです。

Localhostは、実際のサイトのプレースホルダーです。

navigator.serviceWorker.register('localhost/service-worker.js', {scope: './'})
.then(initialiseState);

デバッグ用のChrome開発ツール)では、結果のサービスワーカーは次のような形式になります。

スコープ:localhost/url/stuff /
登録ID:110
アクティブワーカー:
インストールステータス:ACTIVATED
実行ステータス:STOPPED
スクリプト:localhost/service-worker.js
.。

スコープ:localhost /
登録ID:111
アクティブワーカー:
インストールステータス:ACTIVATED
実行ステータス:STOPPED
スクリプト:localhost/service-worker.js
.。

スコープ:localhost/url
登録ID:112
アクティブワーカー:
インストールステータス:ACTIVATED
実行ステータス:STOPPED
スクリプト:localhost/service-worker.js
.。

理想的には、どういうわけかそれを1つのエントリに保持したいだけです。

14
KROrb

[〜#〜] mdn [〜#〜] によると、_ServiceWorkerContainer.register_メソッドはオプションの2番目のパラメーターを取ります。

現在利用可能なオプションは次のとおりです。

  • スコープ:サービスワーカーの登録スコープを定義するURLを表すUSVString。 ServiceWorkerが制御できるURLの範囲。これは通常相対URLであり、指定されていない場合はデフォルトで「/」になります。

更新された質問については、 W3C Service Workers WD は次のように述べています。

同一のスコープURLがユーザーエージェントにすでに存在する場合にサービスワーカーを登録すると、既存のサービスワーカーの登録が置き換えられます。

したがって、navigator.serviceWorker.register(url, {scope: '/'}).then(doSomething)は機能するはずです。

問題はあなたの例のスコープURLにあります:

_./_は_/_である必要があります

14

すべてのサブページを同じトップレベルのサービスワーカーによって制御する、サブディレクトリのあるサイトのシナリオでは、サービスワーカーのスクリプトの場所に絶対URLを使用し、次に依存することをお勧めします。 _options.scope_が省略された場合に発生するデフォルトの動作。

他の応答で引用されている MDN docs は、デフォルトの動作について正しくないことに注意してください。 Service Worker specification was 2015年1月に更新 デフォルトのスコープをnew URL('./', serviceWorkerScriptUrl).toString()と同等に変更しました。 (MDNドキュメントには 更新されてから あり、正確である必要があります。)

このユースケースで_options.scope_を省略することをお勧めする理由を説明するために、単一の共有Service Worker登録が必要であると想定して、次の代替案を検討してください。

  • navigator.serviceWorker.register('/sw.js')は、スコープが_/_の登録を提供します。これは、必要なものです。
  • navigator.serviceWorker.register('/sw.js', {scope: '/'})は、スコープが_/_の登録を提供します。これも必要なものですが、デフォルトの動作で得られるものに勝る利点はありません。
  • navigator.serviceWorker.register('/subsite/sw.js', {scope: '/'})は、_/_のスコープが_/subsite/sw.js_にあるService Workerスクリプトには広すぎるため、登録に失敗します。
  • navigator.serviceWorker.register('/subsite/sw.js')は、_/subsite_のスコープで登録を行います。これはあなたが望むものです。
  • navigator.serviceWorker.register('/subsite/sw.js', {scope: '/subsite'})は機能しますが、繰り返しになりますが、デフォルトの動作に勝る利点はありません。

_options.scope_の値を明示的に設定することをお勧めするのは、ServiceWorkerのスコープをデフォルトのスコープよりも狭く制限する必要がある場合のみです。

_options.scope_に値を指定することにし、その値が_'./'_のような相対URLである場合、URLはregister()。 _{scope: './'}_はnotであり、ServiceWorkerスクリプトURLの場所に関連していると解釈されます。この点でしばらく混乱していたので、少し時間を取ってその意味を完全に理解してください。それが、最初の質問で複数の登録に終わった理由を説明しています。

16
Jeff Posnick