Подтвердить что ты не робот

Как я могу удалить багги-сервисного работника или реализовать "kill switch"?

Я играю с API-интерфейсом службы на своем компьютере, поэтому я могу понять, как я могу извлечь выгоду из этого в своих реальных приложениях.

Я столкнулся с странной ситуацией, когда я зарегистрировал сервис-работника, который перехватывает событие fetch, чтобы он мог проверить свой кеш для запрошенного содержимого перед отправкой запроса в начало. Проблема в том, что этот код имеет ошибку, которая мешала функции делать запрос, поэтому моя страница оставлена ​​пустой; Ничего не произошло. Когда рабочий был зарегистрирован, второй раз, когда я загружаю страницу, он перехватывает самый первый запрос (тот, который загружает HTML). Поскольку у меня есть эта ошибка, это событие fetch не удается, оно никогда не запрашивает HTML и все, что я вижу на пустой странице.

В этой ситуации единственным способом, который я знаю, чтобы удалить плохую службу службы script через консоль chrome://serviceworker-internals/. Если эта ошибка попадает на веб-сайт в прямом эфире, это лучший способ его решить?

Спасибо!

4b9b3361

Ответ 1

Я хотел бы остановиться на некоторых других ответах здесь и подойти к нему с точки зрения "каких стратегий я могу использовать при развертывании сервисного работника в производство, чтобы обеспечить возможность внесения любых необходимых изменений"? Эти изменения могут включать исправление любых незначительных ошибок, которые вы обнаружите в производственном процессе, или это может (но надеюсь, что не так) включать нейтрализацию работника сервиса из-за непреодолимой ошибки - так называемого "переключателя уничтожения".

Для целей этого ответа предположим, что вы звоните

navigator.serviceWorker.register('service-worker.js');

на ваших страницах, что означает, что ресурс JavaScript вашего работника службы - service-worker.js. (См. ниже, если вы не уверены в том, какой именно URL-адрес работника службы использовался, возможно, потому, что вы добавили хеш или информацию о версии в сценарий работника службы.)

Вопрос сводится к тому, как вы решаете начальную проблему в вашем коде service-worker.js. Если это небольшая ошибка, то вы, очевидно, можете просто внести изменения и повторно развернуть service-worker.js в своей среде хостинга. Если нет очевидного исправления ошибки, и вы не хотите, чтобы ваши пользователи выполняли работающий с ошибками код работника сервиса, пока вы находите время для разработки решения, было бы неплохо оставить простое, нет -op service-worker.js удобно, например:

// A simple, no-op service worker that takes immediate control.

self.addEventListener('install', () => {
  // Skip over the "waiting" lifecycle state, to ensure that our
  // new service worker is activated immediately, even if there's
  // another tab open controlled by our older service worker code.
  self.skipWaiting();
});

/*
self.addEventListener('activate', () => {
  // Optional: Get a list of all the current open windows/tabs under
  // our service worker control, and force them to reload.
  // This can "unbreak" any open windows/tabs as soon as the new
  // service worker activates, rather than users having to manually reload.
  self.clients.matchAll({type: 'window'}).then(windowClients => {
    windowClients.forEach(windowClient => {
      windowClient.navigate(windowClient.url);
    });
  });
});
*/

Это должно быть все, что нужно вашему неоперационнику service-worker.js. Поскольку обработчик fetch не зарегистрирован, все запросы навигации и ресурсов с контролируемых страниц в конечном итоге будут направлены непосредственно в сеть, что фактически даст вам то же поведение, с которым вы не столкнулись бы, если бы вообще не было работника сервиса.

Дополнительные шаги

Можно пойти дальше и принудительно удалить все, что хранится, используя Cache Storage API, или явно отменить регистрацию работника службы полностью. В большинстве распространенных случаев это, вероятно, будет излишним, и следования приведенным выше рекомендациям должно быть достаточно, чтобы вы оказались в состоянии, когда ваши текущие пользователи получают ожидаемое поведение, и вы готовы повторно развертывать обновления, как только исправили ошибки, Существуют некоторые накладные расходы, связанные с запуском даже неработающего работника сервиса, поэтому вы можете пойти по пути отмены регистрации работника сервиса, если у вас нет планов по повторному развертыванию значимого кода работника сервиса.

Если вы уже находитесь в ситуации, когда вы обслуживаете service-worker.js с помощью директив кэширования HTTP, что дает ему время, превышающее время ожидания ваших пользователей, имейте в виду, что Shift + Reload на рабочем столе браузеры заставят страницу перезагрузиться вне контроля сервисного работника. Не каждый пользователь будет знать, как это сделать, и это невозможно на мобильных устройствах. Поэтому не полагайтесь на Shift + Reload в качестве жизнеспособного плана отката.

Что если вы не знаете URL-адрес работника службы?

Приведенная выше информация предполагает, что вы знаете, что такое URL-адрес работника службы - service-worker.js, sw.js или что-то еще, что является фактически постоянным. Но что, если вы включили какую-либо версию или хеш-информацию в свой скрипт сервисного работника, например service-worker.abcd1234.js?

Прежде всего, постарайтесь избежать этого в будущем - это против лучших практик. Но если вы уже развернули несколько версионных URL-адресов рабочих служб, и вам нужно отключить вещи для всех пользователей, независимо от того, какой URL-адрес они могли зарегистрировать, есть выход.

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

Предполагая, что у вас есть полный контроль над вашим внутренним HTTP-сервером, вы можете проверять входящие запросы на наличие этого заголовка Service-Worker: и всегда отвечать своим сценарием ответа неактивного работника сервиса, независимо от того, какой URL-адрес запроса.

Специфика настройки вашего веб-сервера для этого зависит от сервера.

Clear-Site-Data: заголовок ответа

Последнее замечание: некоторые браузеры автоматически удаляют определенные данные и, возможно, отменяют регистрацию работников службы, когда специальный заголовок ответа HTTP возвращается как часть любого ответа: Clear-Site-Data:.

Установка этого заголовка может быть полезна при попытке восстановления после неудачного развертывания сервисного работника, и сценарии kill-switch включены в функцию спецификации в качестве примера использования.

Важно проверить историю поддержки браузера для Clear-Site-Data:, прежде чем полагаться исключительно на нее как на переключатель убийства. По состоянию на июль 2019 года, он не поддерживается в 100% браузеров, которые поддерживают сервисных работников, поэтому на данный момент наиболее безопасно использовать Clear-Site-Data: вместе с методами, упомянутыми выше, если вы беспокоитесь о восстановлении после неисправного сервисного работника в все браузеры.

Ответ 2

Это действительно неприятная ситуация, которая, надеюсь, не случится с вами в производстве.

В этом случае, если вы не хотите использовать инструменты разработчика для разных браузеров, chrome://serviceworker-internals/ для браузеров на основе blink или about:serviceworkers (about:debugging#workers в будущем) в Firefox, есть два что приходит мне на ум:

  • Используйте механизм обновления serviceworker. Ваш пользовательский агент проверяет, есть ли какие-либо изменения в зарегистрированном работнике, выберет его и снова пройдет фазу activate. Поэтому потенциально вы можете изменить serviceworker script, исправить (очистить кеши и т.д.) Любую странную ситуацию и продолжить работу. Единственный недостаток - вам нужно подождать, пока браузер не обновит рабочего, который может быть 1 день.
  • Добавьте своего рабочего переключателя. Наличие специального URL-адреса, куда вы можете указать пользователей, которые могут восстановить статус ваших кэшей и т.д.

Я не уверен, что очистка данных браузера приведет к удалению рабочего, так что это может быть другой вариант.

Ответ 3

Вы можете "отменить регистрацию" рабочего, используя javascript. Вот пример:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.getRegistrations().then(function (registrations) {
    //returns installed service workers
    if (registrations.length) {
      for(let registration of registrations) {
        registration.unregister();
      }
    }
  });
}

Ответ 4

Для живых ситуаций вам нужно изменить обслуживающего работника на уровне байта (например, поставить комментарий к первой строке) и он будет обновлен в следующие 24 часа. Вы можете эмулировать это с помощью chrome://serviceworker-internals/в Chrome, нажав кнопку "Обновить".

Это должно работать даже в ситуациях, когда сам сервисный сервис кэшировался, поскольку шаг 9 алгоритма обновления установил флаг для обхода рабочего.

Ответ 5

Я не тестировал это, но есть unregister() и update() в объекте ServiceWorkerRegistration. вы можете получить это из navigator.serviceWorker.

navigator.serviceWorker.getRegistration('/').then(function(registration) {
  registration.update();
});
Обновление

должно немедленно проверить, есть ли новый serviceworker и если он его установит. Это обходит 24-часовой период ожидания и будет загружать serviceworker.js каждый раз, когда этот javascript встречается.