テストページに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
を別の場所に移動する必要がありますか?もしそうなら、どこ?
サービスワーカーは基本的にWebアプリケーションとインターネット間のプロキシであるため、必要に応じてネットワークへの呼び出しをインターセプトできます。
このインスタンスのスコープは、サービスワーカーがネットワーク呼び出しをインターセプトできるパスを指します。 scope
プロパティを使用して、カバーするスコープを明示的に定義できます。しかしながら:
Service Workerは、Service Workerスクリプトが置かれている現在のディレクトリとそのサブディレクトリのスコープから発信されたリクエストのみをインターセプトできます。 またはMDNの状態として :
Service Workerは、Service Workerのスコープ内のクライアントからのリクエストのみをキャッチします。
サービスワーカーの最大スコープは、ワーカーの場所です。
サービスワーカーは/static/mod/practice/
にあるため、スコープを/practice/foopage/
に設定することはできません。他のホストへのリクエスト、例えばhttps://stackoverflow.com/foo
は、どのような場合でも傍受できます。
サービスワーカーが必要なすべての呼び出しをインターセプトできるようにする最も簡単な方法は、Webアプリのルートディレクトリ(/
)に配置することです。また、httpヘッダーを使用してデフォルトの制限をオーバーライドし、スコープを手動で設定することもできます(Ashraf Sabryの回答を参照)。
プロジェクト構造によって課されたディレクトリに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 の例を参照してください
Nginxを使用している人にとっては、これ以上簡単なことはありません。
# Given that /static is your route to assets
location /static {
# using / as root scope
add_header Service-Worker-Allowed /;
....