Javascript 了解 Service Worker 范围
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35780397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Understanding Service Worker scope
提问by Brian Leach
I am trying to implement a Service Worker
in a test page. My end goal is an application that operates offline. The folder structure is below
我正在尝试Service Worker
在测试页面中实现一个。我的最终目标是一个离线运行的应用程序。文件夹结构如下
/myApp
...
/static
/mod
/practice
service-worker.js
worker-directives.js
foopage.js
/templates
/practice
foopage.html
I am registering a service worker as shown below (within service-worker.js
):
我正在注册一个服务工作者,如下所示(在 内service-worker.js
):
navigator.serviceWorker.register('../static/mod/practice/service-worker.js').then(function(reg) {
console.log('Registration succeeded. Scope is ' + reg.scope);
...
}
and in the console I see
在控制台中我看到
Registration succeeded. Scope is https://example.com/static/mod/practice/
Registration succeeded. Scope is https://example.com/static/mod/practice/
If my page is located at https://example.com/practice/foopage
, do I need to make sure that my service worker
scope is https://example.com/practice/foopage
?
如果我的页面位于https://example.com/practice/foopage
,我是否需要确保我的service worker
范围是https://example.com/practice/foopage
?
If I try to define the scope in the register
function call like
如果我尝试在register
函数调用中定义范围,例如
navigator.serviceWorker.register('../static/mod/practice/service-worker.js', { scope: '/practice/foopage/' }).then(function(reg) {
...
}
I get the error
我收到错误
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.
Question is:What exactly does scoperefer to? Is it the collection of URLs that the service worker
will eventually control? Do I need to move service-workers.js
somewhere else? If so, where?
问题是:范围究竟指的是什么?它是service worker
最终控制的 URL 集合吗?我需要搬到service-workers.js
别的地方吗?如果有,在哪里?
回答by nils
Service workers are basically a proxy between your web application and the internet, so it can intercept calls to the network if so desired.
Service Worker 基本上是您的 Web 应用程序和 Internet 之间的代理,因此如果需要,它可以拦截对网络的调用。
Scope in this instance refers to the path that the service worker will be able to intercept network calls from. The scope
property can be used explicitly define the scope it will cover. However:
此实例中的范围是指 Service Worker 将能够拦截来自其的网络调用的路径。scope
可以使用该属性明确定义它将涵盖的范围。然而:
Service workers can only intercept requests originating in the scope of the current directory that the service worker script is located in and its subdirectories. Or as MDN states:
Service Worker 只能拦截源自 Service Worker 脚本所在的当前目录及其子目录范围内的请求。或者如 MDN 所述:
The service worker will only catch requests from clients under the service worker's scope.
The max scope for a service worker is the location of the worker.
Service Worker 只会在 Service Worker 的范围内捕获来自客户端的请求。
服务工作者的最大范围是工作者的位置。
As your service worker is located in /static/mod/practice/
, it's not allowed to set its scope to /practice/foopage/
. Requests to other hosts, e.g. https://stackoverflow.com/foo
, can be intercepted in any case.
由于您的服务工作者位于/static/mod/practice/
,因此不允许将其范围设置为/practice/foopage/
。对其他主机的请求,例如https://stackoverflow.com/foo
,在任何情况下都可以被拦截。
The easiest way to ensure that your service worker can intercept all the calls it needs to, would be to place it in the root directory of your web app (/
). You can also override the default restrictions using an http header and manually setting the scope (see Ashraf Sabry's answer).
确保您的 Service Worker 可以拦截它需要的所有调用的最简单方法是将它放在您的 Web 应用程序的根目录中 ( /
)。您还可以使用 http 标头覆盖默认限制并手动设置范围(请参阅 Ashraf Sabry 的回答)。
回答by Ashraf Sabry
Leave the service worker file in whatever directory imposed by your project structure and set the scope
option to /
and add the Service-Worker-Allowed
HTTP header to the response of your service worker file.
将 Service Worker 文件保留在您的项目结构强加的任何目录中,并将scope
选项设置为/
并将Service-Worker-Allowed
HTTP 标头添加到您的 Service Worker 文件的响应中。
I'm using IIS, so I would add the following to web.config file:
我正在使用 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>
And register the worker by:
并通过以下方式注册工人:
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);
});
Tested on Firefox and Chrome.
在 Firefox 和 Chrome 上测试。
Refer to the examples in Service worker specification
请参阅Service Worker 规范中的示例
回答by shriek
For the people who are using nginx it couldn't be any simpler:
对于使用 nginx 的人来说,它再简单不过了:
# Given that /static is your route to assets
location /static {
# using / as root scope
add_header Service-Worker-Allowed /;
....