Понимание сферы услуг
Я пытаюсь реализовать Service Worker
на тестовой странице. Моя конечная цель - это приложение, которое работает в автономном режиме. Структура папок ниже
/myApp
...
/static
/mod
/practice
service-worker.js
worker-directives.js
foopage.js
/templates
/practice
foopage.html
Я регистрирую сервисного работника, как показано ниже (в пределах service-worker.js
):
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.
Вопрос:. В чем конкретно относится область? Является ли это набором URL-адресов, которые в конечном итоге будет Service Worker
? Мне нужно переместить service-workers.js
в другое место? Если да, то где?
Ответы
Ответ 1
Сервисные работники - это, по сути, прокси между вашим веб-приложением и Интернетом, поэтому он может перехватывать звонки в сеть, если это необходимо.
В данном случае под областью понимается путь, по которому работник службы сможет перехватывать сетевые вызовы. Свойство scope
может использоваться в явном виде для определения области действия, которую оно будет охватывать. Тем не мение:
Работники службы могут перехватывать только запросы, исходящие из области текущего каталога, в котором находится сценарий работника службы, и его подкаталогов. Или, как утверждает MDN:
Сервисный работник будет перехватывать запросы только от клиентов, находящихся в области обслуживания.
Максимальная область действия для работника службы - это местоположение работника.
Так как ваш сервисный работник находится в /static/mod/practice/
, ему не разрешено устанавливать его область действия /practice/foopage/
. Запросы к другим хостам, например https://stackoverflow.com/foo
, могут быть перехвачены в любом случае.
Самый простой способ убедиться, что ваш сервисный работник может перехватывать все необходимые ему вызовы, - это поместить его в корневой каталог вашего веб-приложения (/
). Вы также можете переопределить ограничения по умолчанию, используя заголовок http и вручную устанавливая область действия (см. Ответ Ашрафа Сабри).
Ответ 2
Оставьте файл сервисного работника в любом каталоге, заданном структурой вашего проекта, и установите параметр scope
в /
и добавьте HTTP-заголовок Service-Worker-Allowed
в ответ вашего сервисного файла.
Я использую 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 Service.
Ответ 3
Для людей, которые используют nginx, это не может быть проще:
# Given that /static is your route to assets
location /static {
# using / as root scope
add_header Service-Worker-Allowed /;
....
Ответ 4
Любой, пожалуйста, дайте мне знать, как и где добавить (Service-Worker-Allowed) в Jboss-5, я пробовал все, но безуспешно.