Понимание сферы услуг

Я пытаюсь реализовать 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, я пробовал все, но безуспешно.