web-dev-qa-db-ja.com

Service Workerスコープについて

テストページにService Workerを実装しようとしています。私の最終目標は、オフラインで動作するアプリケーションです。フォルダ構造は次のとおりです

/myApp
  ...
  /static
    /mod
      /practice
        service-worker.js
        worker-directives.js
        foopage.js
  /templates
    /practice
      foopage.html

以下に示すように(service-worker.js内で)Service Workerを登録しています。

navigator.serviceWorker.register('../static/mod/practice/service-worker.js').then(function(reg) {
    console.log('Registration succeeded. Scope is ' + reg.scope);
    ...
}

そして、私はコンソールで見る

Registration succeeded. Scope is https://example.com/static/mod/practice/

ページがhttps://example.com/practice/foopageにある場合、service workerスコープがhttps://example.com/practice/foopageであることを確認する必要がありますか?

register関数呼び出しでスコープを定義しようとすると

navigator.serviceWorker.register('../static/mod/practice/service-worker.js', { scope: '/practice/foopage/' }).then(function(reg) {
    ...
}

エラーが表示されます

Registration failed with SecurityError: Failed to register a ServiceWorker: The path of the provided scope ('/practice/foopage/') is not under the max scope allowed ('/static/mod/practice/'). Adjust the scope, move the Service Worker script, or use the Service-Worker-Allowed HTTP header to allow the scope.

質問::scopeとは正確に何を指しますか? service workerが最終的に制御するのはURLのコレクションですか? service-workers.jsを別の場所に移動する必要がありますか?もしそうなら、どこ?

28
Brian Leach

サービスワーカーは基本的にWebアプリケーションとインターネット間のプロキシであるため、必要に応じてネットワークへの呼び出しをインターセプトできます。

このインスタンスのスコープは、サービスワーカーがネットワーク呼び出しをインターセプトできるパスを指します。 scopeプロパティを使用して、カバーするスコープを明示的に定義できます。しかしながら:

Service Workerは、Service Workerスクリプトが置かれている現在のディレクトリとそのサブディレクトリのスコープから発信されたリクエストのみをインターセプトできます。 またはMDNの状態として

Service Workerは、Service Workerのスコープ内のクライアントからのリクエストのみをキャッチします。

サービスワーカーの最大スコープは、ワーカーの場所です。

サービスワーカーは/static/mod/practice/にあるため、スコープを/practice/foopage/に設定することはできません。他のホストへのリクエスト、例えばhttps://stackoverflow.com/fooは、どのような場合でも傍受できます。

サービスワーカーが必要なすべての呼び出しをインターセプトできるようにする最も簡単な方法は、Webアプリのルートディレクトリ(/)に配置することです。また、httpヘッダーを使用してデフォルトの制限をオーバーライドし、スコープを手動で設定することもできます(Ashraf Sabryの回答を参照)。

32
nils

プロジェクト構造によって課されたディレクトリにService Workerファイルを残し、scopeオプションを/に設定し、Service-Worker-Allowed HTTPヘッダーをService Workerファイルの応答に追加します。

IISを使用しているので、web.configファイルに次を追加します。

<location path="static/mod/practice/service-worker.js">
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <add name="Service-Worker-Allowed" value="/" />
            </customHeaders>
        </httpProtocol>
    </system.webServer>
</location>

そして、次の方法でワーカーを登録します。

navigator.serviceWorker.register('/static/mod/practice/service-worker.js', { scope: '/' })
        .then(function (registration)
        {
          console.log('Service worker registered successfully');
        }).catch(function (e)
        {
          console.error('Error during service worker registration:', e);
        });

FirefoxおよびChromeでテスト済み。

Service worker specification の例を参照してください

21
Ashraf Sabry

Nginxを使用している人にとっては、これ以上簡単なことはありません。

# Given that /static is your route to assets
location /static {
        # using / as root scope
        add_header Service-Worker-Allowed /;
....
1
shriek