Как загрузить работника сервиса перед всеми другими запросами? - PullRequest
2 голосов
/ 25 апреля 2020

Я пытаюсь загрузить работника сервиса перед всеми запросами субресурсов на странице, чтобы я мог применить некоторые оптимизации к способу загрузки субресурсов (например, отложенная загрузка, загрузка минимизированных версий ресурсов вместо полных активов). Тем не менее, я не могу найти способ загрузить мое ПО до того, как начнутся другие запросы к подресурсу.

Я создал простое доказательство того, что я пытаюсь сделать, для 401 любых запросов, обрабатываемых моим сервисным работником (просто чтобы легче было найти, когда мое ПО начинает обрабатывать запросы).

Вот мой HTML:

<!doctype html>
<head>
    <script>
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('/dl-wps-sw.js', { scope: '/' }).then(function (registration) {
                console.log('Service Worker registration successful with scope: ', registration.scope);
            }, function (err) {
                console.error(err);
            });
        }
    </script>
    ...

, а вот мой работник службы:

self.addEventListener('install', function (event) {
    self.skipWaiting();
});

self.addEventListener('activate', () => {
    self.clients.claim();
});

self.addEventListener('fetch', (event) => {
    const init = {status: 401, statusText: 'Blocked!'};
    event.respondWith(new Response(null, init));
});

Вот что происходит в моем браузере: enter image description here

Как вы можете видеть на скриншоте, хотя мой код для регистрации Service Service Worker находится в самой верхней части страницы, он не активирует и не начинает обрабатывать запросы, пока немного позже, и к тому времени большое количество критических запросов, которые мне нужно перехватить, уже сработало.

Я нашел кого-то еще, кто, кажется, пытался сделать то, что я ' я пытаюсь выполнить sh (2 года назад) в выпуске Github для Service Worker spe c: https://github.com/w3c/ServiceWorker/issues/1282

Кажется, они предложили использовать тег <link rel="serviceworker"... чтобы сделать это, но, похоже, этот тип ссылки имеет с б По какой-то причине он был удален из Chrome: https://www.chromestatus.com/feature/5682681044008960

Я попытался несколько других попыток загрузить свою ОС первым:

  • Предварительная загрузка мое ПО с тегом <link rel="preload"...
  • Предварительная загрузка моего ПО с помощью fetch / XMLHttpRequest
  • , встраивающего работника сервиса в HTML (по-видимому, невозможно)
  • Задержка выполнения страницы, запустив некоторое время l oop на несколько секунд (это вроде работает, но это ужасный непредсказуемый взлом)

Какие идеи или стратегии мне не хватает? Мой Google-фу не помог мне найти решение.

1 Ответ

3 голосов
/ 26 апреля 2020

Сначала вам нужно будет установить только ПО, а затем обновить страницу sh. Затем ПО может обслуживать контент для страницы с поддержкой ПО и перехватывать все другие запросы. Пример: fetch-progress.anthum.com

index. html

<p>Installing Service Worker, please wait...</p>

<script>
  navigator.serviceWorker.register('sw.js')
  .then(reg => {
    if (reg.installing) {
      const sw = reg.installing || reg.waiting;
      sw.onstatechange = function() {
        if (sw.state === 'installed') {
          // SW installed.  Refresh page so SW can respond with SW-enabled page.
          window.location.reload();
        }
      };
    } else if (reg.active) {
      // something's not right or SW is bypassed.  previously-installed SW should have redirected this request to different page
      handleError(new Error('Service Worker is installed and not redirecting.'))
    }
  })
  .catch(handleError)

  function handleError(error) {}
</script>

sw. js

self.addEventListener('fetch', event => {
  const url = event.request.url;
  const scope = self.registration.scope;

  // serve index.html with service-worker-enabled page
  if (url === scope || url === scope+'index.html') {
    const newUrl = scope+'index-sw-enabled.html';
    event.respondWith(fetch(newUrl))
  } else {
    // process other files here
  }
});

index-sw-enable. html

<!-- 
  This page shows after SW installs.
  Put your main app content on this page.
-->
...