Ночные Работники Службы | Контекст Клиента

Оглавление

3.1. Интерфейс ServiceWorker
3.1.1 Получение эземпляров ServiceWorker
3.1.2 scriptURL
3.1.3 state
3.1.4 postMessage(message, transfer)
3.1.5 postMessage(message, options)
3.1.6 Обработчик событий ServiceWorker
3.2 Интерфейс ServiceWorkerRegistration
3.2.1 Получение экземпляров ServiceWorkerRegistration
3.2.2 installing
3.2.3 waiting
3.2.4 active
3.2.5 navigationPreload
3.2.6 scope
3.2.7 updateViaCache
3.2.8 update()
3.2.9 unregister()
3.2.10 Обработчик событий ServiceWorkerRegistration
3.3 navigator.serviceWorker
3.4 Интерфейс ServiceWorkerContainer
3.4.1 controller
3.4.2 ready
3.4.3 register(scriptURL, options)
3.4.4 getRegistration(clientURL)
3.4.5 getRegistrations()
3.4.6 startMessages()
3.4.7 Обработчики событий ServiceWorkerContainer
3.5 События
3.6 Интерфейс NavigationPreloadManager
3.6.1 enable()
3.6.2 disable()
3.6.3 setHeaderValue(value)
3.6.4 getState()

Пример 1

Начальная загрузка с работником службы:

// по умолчанию область видимости соответствует пути, в котором находится скрипт
// "/" в этом примере
navigator.serviceWorker.register("/serviceworker.js").then(registration => {
   console.log("успех!");
   if (registration.installing) {
      registration.installing.postMessage("Привет со страницы установки.");
   }
}, err => {
   console.error("Установить работника не удалось!", err);
});

 

3.1. Интерфейс ServiceWorker

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorker : EventTarget {
   readonly attribute USVString scriptURL;
   readonly attribute ServiceWorkerState state;
   undefined postMessage(any message, sequence<object> transfer);
   undefined postMessage(any message, optional StructuredSerializeOptions options = {});

   // событие
   attribute EventHandler onstatechange;
};
ServiceWorker includes AbstractWorker;

enum ServiceWorkerState {
   "parsed",
   "installing",
   "installed",
   "activating",
   "activated",
   "redundant"
};

 

Объект ServiceWorker представляет работника службы. Каждый объект ServiceWorker связан с работником службы. Несколько отдельных объектов, реализующих интерфейс ServiceWorker для документов и рабочих, могут быть связаны с одним и тем же работником службы одновременно.

Объект ServiceWorker имеет связанный объект ServiceWorkerState, который сам связан с состоянием работника службы.

 

3.1.1 Получение экземпляров ServiceWorker

У объекта настроек среды есть карта объектов работника службы (service worker object map), карта, где ключиработники службы, а значения — объекты ServiceWorker.

Чтобы получить объект работника службы (get the service worker object), представляющий serviceWorker (работник службы) в среде environment (объект настроек среды), выполните следующие действия:

1. Пусть objectMap будет картой объекта работника службы среды environment.
2. Если objectMap[serviceWorker] не существует, тогда:
   2.1 Пусть serviceWorkerObj будет новым ServiceWorker в Области среды, и свяжите его с serviceWorker.
   2.2 Установите состояние state serviceWorkerObj на состояние serviceWorker.
   2.3 Установите для objectMap[serviceWorker] значение serviceWorkerObj.
3. Вернуть objectMap[serviceWorker].

 

3.1.2 Геттер scriptURL

Шаги получателя scriptURL должны вернуть сериализованный URL-адрес сценария работника службы.

Пример 2

Например, рассмотрим документ, созданный путем перехода на «https://example.com/app.html«, который соответствует следующему вызову регистрации, который был ранее выполнен:

// Сценарий на странице https://example.com/app.html
navigator.serviceWorker.register("/service_worker.js");

Значение navigator.serviceWorker.controller.scriptURL будет «https://example.com/service_worker.js«.

 

3.1.3 Атрибут state

Атрибут состояния state должен возвращать значение (в перечислении ServiceWorkerState), которое было установлено в последний раз.

 

3.1.4 Метод postMessage(message, transfer)

Шаги метода postMessage(message, transfer):

1. Пусть options будут «[ "transfer" → transfer ]».
2. Вызов postMessage(message, options) с сообщением message и параметрами options в качестве аргументов.

 

3.1.5 Метод postMessage(message, options)

Шаги метода postMessage(message, options):

1. Пусть serviceWorker будет представителем этого работника службы.
2. Пусть incumbentSettings будет существующим объектом настроек.
3. Пусть incumbentGlobal будет глобальным объектом incumbentSettings.
4. Пусть serializeWithTransferResult будет StructuredSerializeWithTransfer (message, options["transfer"]). Перебросьте все исключения.
5. Если результат выполнения алгоритма Should Skip Event (Должен Пропустить Событие) с "message" и serviceWorker является true, то вернитесь.
6. Выполните эти подэтапы параллельно:
  6.1 Если в результате выполнения алгоритма Run Service Worker (Запустить Работника Службы) с serviceWorker произошел сбой, вернитесь.
  6.2 Поставьте задачу в очередь в источнике задачи манипулирования DOM, чтобы выполнить следующие шаги:
    6.2.1 Пусть source определяется переключением типа incumbentGlobal:

ServiceWorkerGlobalScope
Результат получения объекта работника службы, который представляет работника службы incumbentGlobal в подходящем объекте настроек глобального объекта serviceWorker.

Window
новый объект WindowClient, представляющий подходящий объект настроек incumbentGlobal.

В противном случае
новый объект Client, который представляет работника, связанного с incumbentGlobal.

    6.2.2 Пусть origin будет сериализацией источника incumbentSettings.
    6.2.3 Пусть местом назначения destination будет объект ServiceWorkerGlobalScope, связанный с serviceWorker.
    6.2.4 Пусть deserializeRecord будет StructuredDeserializeWithTransfer(serializeWithTransferResult, Область destination).
        Если это вызывает исключение, пусть e будет результатом создания события с именем messageerror, используя ExtendableMessageEvent, с атрибутом origin, инициализированным как origin, и атрибутом source, инициализированным как source.
    6.2.5 Иначе
      6.2.5.1 Пусть messageClone будет deserializeRecord.[[Deserialized]].
      6.2.5.2 Пусть newPorts будет новым замороженным массивом, состоящим из всех объектов MessagePort в deserializeRecord.[[TransferredValues]], если они есть, сохраняя их относительный порядок.
      6.2.5.3 Пусть e будет результатом создания события с именем message с использованием ExtendableMessageEvent, с атрибутом origin, инициализированным значением origin, атрибутом source, инициализированным значением source, атрибутом data, инициализированным значением messageClone, и атрибутом ports, инициализированным значением newPorts.
    6.2.6 Отправить e в пункте назначения destination.
    6.2.7 Вызвать набор расширенных событий работника службы обновления (Update Service Worker Extended Events Set) с помощью serviceWorker и e.

 

3.1.6 Обработчик событий ServiceWorker

Ниже приводится обработчик событий (и соответствующий ему тип события обработчика событий), который должен поддерживаться в качестве IDL-атрибутов обработчика событий всеми объектами, реализующими интерфейс ServiceWorker:

event handler event handler event type
onstatechange statechange

 

3.2 Интерфейс ServiceWorkerRegistration

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorkerRegistration : EventTarget {
  readonly attribute ServiceWorker? installing;
  readonly attribute ServiceWorker? waiting;
  readonly attribute ServiceWorker? active;
  [SameObject] readonly attribute NavigationPreloadManager navigationPreload;

  readonly attribute USVString scope;
  readonly attribute ServiceWorkerUpdateViaCache updateViaCache;

  [NewObject] Promise<undefined> update();
  [NewObject] Promise<boolean> unregister();

  // event
  attribute EventHandler onupdatefound;
};

enum ServiceWorkerUpdateViaCache {
  "imports",
  "all",
  "none"
};

 

ServiceWorkerRegistration имеет регистрацию работника службы (service worker registrationрегистрация работника службы).

3.2.1 Получение экземпляров ServiceWorkerRegistration

Объект настроек среды имеет карту объектов регистрации работника службы (service worker registration object map), карту, где ключи — это регистрации работника службы, а значения — это объекты ServiceWorkerRegistration.

Чтобы получить объект регистрации работника службы (get the service worker registration object), представляющий регистрацию registration (регистрацию работника службы) в среде environment (объект настроек среды), выполните следующие действия:

1. Пусть objectMap будет картой объектов регистрации работника службы среды environment.
2. Если objectMap[registration] не существует, тогда:
   2.1 Пусть registrationObject будет новым ServiceWorkerRegistration в Области среды environment.
   2.2 Установите регистрацию работника службы registrationObject на registration.
   2.3 Установите для атрибута installing registrationObject значение null.
   2.4 Установите для атрибута waiting registrationObject значение null.
   2.5 Установите для атрибута active registrationObject значение null.
   2.6 Если устанавливающий работник registration, не равен null, то установите для атрибута installing registrationObject значение результата получения объекта работника службы, который представляет устанавливающего работника registration в среде environment.
   2.7 Если ожидающий работник registration, не равен null, тогда установите для атрибута waiting registrationObject значение результата получения объекта работника службы, который представляет ожидающего работника registration в среде environment.
   2.8 Если активный работник регистрации не равен null, тогда установите для атрибута active registrationObject значение результата получения объекта работника службы, который представляет активного работника registration в среде environment.
   2.9 Установите для objectMap[registration] значение registrationObject.
3. Вернуть objectMap[registration].

 

Атрибут installing должен возвращать значение, которое было установлено в последний раз.

Примечание

Внутри Области существует только один объект ServiceWorker для каждого связанного работника службы.

 

Атрибут waiting должен возвращать значение, которое было установлено в последний раз.

Примечание

Внутри Области существует только один объект ServiceWorker для каждого связанного работника службы.

 

Атрибут active должен возвращать значение, которое было установлено в последний раз.

Примечание

Внутри Области существует только один объект ServiceWorker для каждого связанного работника службы.

3.2.5 Геттер navigationPreload

Шаги получателя navigationPreload должны вернуть объект NavigationPreloadManager регистрации работника службы.

 

3.2.6 Геттер scope

Шаги получателя области видимости scope должны вернуть сериализованный URL-адрес области видимости регистрации работника службы.

ПРИМЕР 3

В примере в § 3.1.2 scriptURL значение registration.scope, полученное из navigator.serviceWorker.ready.then(registration => console.log(registration.scope)), например, будет «https://example .com/«.

 

3.2.7 Геттер updateViaCache

Шаги получателя updateViaCache должны вернуть обновление через режим кеширования, регистрации работника службы.

 

3.2.8 Метод update()

Шаги метода update():

1. Пусть регистрация registration будет регистрацией работника службы.
2. Пусть newestWorker будет результатом выполнения алгоритма Получения Новейшего Работника (Get Newest Worker), передавая registration в качестве аргумента.
3. Если newestWorker имеет значение null, верните отклоненное обещание с DOMException "InvalidStateError", и прервите выполнение этих шагов.
4. Если релевантный глобальный объект globalObject этого this является объектом ServiceWorkerGlobalScope, а связанное состояние работника службы globalObject является "installing", верните отклоненное обещание с DOMException "InvalidStateError", и прервите выполнение этих шагов.
5. Пусть promise будет обещанием.
6. Пусть задание job будет результатом выполнения Создать Задание (Create Job) с обновлением update, URL-адресом области видимости регистрации registration, URL-адресом сценария newestWorker, promise и релевантным объектом настроек этого this.
7. Установите тип рабочего задания job на тип newestWorker.
8. Вызов Запланированного Задания (Schedule Job) с помощью job.
9. Вернуть обещание promise.

 

Примечание

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

Шаги метода unregister():

1. Пусть обещание promise станет новым обещанием.
2. Пусть задание job будет результатом выполнения Создать Задание (Create Job) с отменой регистрации unregister, URL-адресом области видимости регистрации работника службы, null, promise и релевантным объектом настроек этого this.
3. Вызов Запланированного Задания (Schedule Job) с помощью job.
4. Вернуть promise.

 

3.2.10 Обработчик событий ServiceWorkerRegistration

Ниже приводится обработчик событий (и соответствующий ему тип события обработчика событий), который должен поддерживаться в качестве IDL-атрибутов обработчика событий всеми объектами, реализующими интерфейс ServiceWorkerRegistration:

event handler event handler event type
onupdatefound updatefound

 



partial interface Navigator {
   [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
};

partial interface WorkerNavigator {
   [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
};

Шаги получателя serviceWorker должны вернуть объект ServiceWorkerContainer, связанный с этим this.

3.4 Интерфейс ServiceWorkerContainer

[SecureContext, Exposed=(Window, Worker)]
interface ServiceWorkerContainer : EventTarget {
  readonly attribute ServiceWorker? controller;
  readonly attribute Promise<ServiceWorkerRegistration> ready;

  [NewObject] Promise<ServiceWorkerRegistration> register(USVString scriptURL, optional RegistrationOptions options = {});

  [NewObject] Promise<(ServiceWorkerRegistration or undefined)> getRegistration(optional USVString clientURL = "");
  [NewObject] Promise<FrozenArray<ServiceWorkerRegistration>> getRegistrations();

  undefined startMessages();

  // события
  attribute EventHandler oncontrollerchange;
  attribute EventHandler onmessage; // event.source of message events is ServiceWorker object
  attribute EventHandler onmessageerror;
};

 

dictionary RegistrationOptions {
   USVString scope;
   WorkerType type = "classic";
   ServiceWorkerUpdateViaCache updateViaCache = "imports";
};


Пользовательский агент должен создать объект ServiceWorkerContainer при создании объекта Navigator или объекта WorkerNavigator и связать его с этим объектом.

ServiceWorkerContainer предоставляет возможности для регистрации, отмены регистрации и обновления регистраций работников службы, а также предоставляет доступ к состоянию регистрации работников службы и связанных с ними работников службы.

ServiceWorkerContainer имеет связанный клиент работника службы (service worker client), который является клиентом работника службы, глобальный объект которого связан с объектом Navigator или объектом WorkerNavigator, из которого извлекается ServiceWorkerContainer.

У объекта ServiceWorkerContainer есть связанное готовое обещание (ready promise — обещание или null). Изначально он равен null.

Объект ServiceWorkerContainer имеет источник задачи, называемый очередью сообщений клиента (client message queue), изначально пустой. Очередь сообщений клиента может быть включена или отключена, и изначально она отключена. Когда очередь сообщений клиента объекта ServiceWorkerContainer включена, цикл событий должен использовать её в качестве одного из своих источников задач. Когда соответствующий глобальный объект объекта ServiceWorkerContainer является объектом Window, все задачи, поставленные в очередь его клиентских сообщений, должны быть связаны с ответственным документом соответствующего объекта настроек.

3.4.1. Атрибут controller

Атрибут controller должен выполнить следующие шаги:

1. Пусть client будет клиентом работника службы этого this.
2. Если активный работник службы клиента client равен null, верните null.
3. Вернуть результат получения объекта работника службы, который представляет активного работника службы клиента client в соответствующем объекте настроек этого this.
Примечание

navigator.serviceWorker.controller возвращает null, если запрос является принудительным обновлением (сдвиг+обновлениеshift+refresh).

 

3.4.2. Атрибут ready

Атрибут ready должен выполнить следующие шаги:

1. Если готовое обещание этого this имеет значение null, установите для готового обещания этого this новое обещание.
2. Пусть readyPromise будет готовым обещанием этого this.
3. Если readyPromise ожидает выполнения, выполните следующие подэтапы параллельно:
   3.1  Пусть регистрация registration будет результатом запуска "Регистрация Соответствия Работника Службы" (Match Service Worker Registration) с URL-адресом создания клиента работника службы этого this.
   3.2 Если регистрация registration не равна null, а активный работник registration не равен null, поставьте задачу в очередь на ответственный цикл событий соответствующего объекта настроек readyPromise, используя источник задачи манипулирования DOM, чтобы разрешить readyPromise с результатом получения объекта регистрации работника службы, который представляет registration в соответствующий объект настроек readyPromise.
4. Вернуть readyPromise.

 

Примечание

Возвращённое готовое обещание никогда не будет отклонено. Если оно не разрешается в этом алгоритме, оно в конечном итоге разрешится, когда будет зарегистрирована соответствующая регистрация работника службы и будет установлен его активный рабочий. (См. Соответствующий шаг алгоритма активации.)

 

Примечание

Метод register(scriptURL, options) создает или обновляет регистрацию работника службы для заданного URL-адреса области видимости. В случае успеха регистрация работника службы привязывает предоставленный scriptURL к URL-адресу области видимости, который впоследствии используется для сопоставления навигации.

Шаги метода register(scriptURL, options):

1. Пусть p будет обещанием.
2. Пусть client будет клиентом работника службы этого this.
3. Пусть scriptURL будет результатом синтаксического анализа scriptURL с базовым URL-адресом API соответствующего объекта настроек этого this.
4. Пусть scopeURL будет null.
5. Если options["scope"] существует, установите для scopeURL результат синтаксического анализа options["scope"] с базовым URL-адресом API соответствующего объекта настроек этого this.
6. Вызвать Стартовую Регистрацию с помощью scopeURL, scriptURL, p, client, URL-адреса создания client, options["type"] и options["updateViaCache"].
7. Вернуть p.

 

Шаги метода getRegistration(clientURL):

1. Пусть client будет клиентом работника службы этого this.
2. Пусть clientURL будет результатом синтаксического анализа clientURL с базовым URL API соответствующего объекта настроек этого this.
3. Если clientURL не удалось, вернуть обещание, отклонённое с ошибкой TypeError.
4. Установите для фрагмента clientURL значение null.
5. Если источник clientURL не является источником client, вернуть promise, отклоненное с помощью исключения DOMException "SecurityError".
6. Пусть promise станет новым обещанием.
7. Параллельно выполните следующие подшаги:
   7.1 Пусть регистрация registration будет результатом выполнения алгоритма "Регистрация Соответствия Работника Службы" (Match Service Worker Registration) с clientURL в качестве аргумента.
   7.2 Если регистрация registration равна null, разрешите promise с помощью undefined и прервите эти шаги.
   7.3 Разрешить promise с результатом получения объекта регистрации работника службы, который представляет registration в соответствующем объекте настроек promise.
8. Вернуть promise.

 

Шаги метода getRegistrations():

1. Пусть client будет клиентом работника службы этого this.
2. Пусть promise станет новым обещанием.
3. Параллельно выполните следующие шаги:
  3.1 Пусть регистрации registrations будут новым списком.
  3.2 Для каждой области видимости scoperegistrations для области видимости на карте:
    3.2.1 Если источник результата синтаксического анализа scope совпадает с тем же источником клиента client, тогда добавьте регистрацию registration к регистрациям registrations.
  3.3 Поставьте задачу в очередь на ответственный цикл событий объекта релевантных настроек обещания promise, используя источник задачи манипулирования DOM, чтобы выполнить следующие шаги:
    3.3.1 Пусть registrationObjects будет новым списком.
    3.3.2 Для каждой регистрации registration из регистраций registrations:
      3.3.2.1 Пусть registrationObj будет результатом получения объекта регистрации работника службы, который представляет регистрацию registration в соответствующем объекте настроек обещания promise.
      3.3.2.2 Добавьте registrationObj к registrationObjects.
    3.3.3 Выполните обещание promise с новым замороженным массивом registrationObjects в соответствующей Области обещания promise.
4. Вернуть promise.

 

Шаги метода startMessages() заключаются в том, чтобы включить очередь сообщений клиента этого this, если она не включена.

 

3.4.7 Обработчики событий ServiceWorkerContainer

Ниже перечислены обработчики событий (и соответствующие им типы событий обработчиков событий), которые должны поддерживаться в качестве IDL-атрибутов обработчиков событий всеми объектами, реализующими интерфейс ServiceWorkerContainer:

Обработчик события (event handler) Тип события обработчика события (event handler event type)
oncontrollerchange controllerchange
onmessage message
onmessageerror messageerror

При первом выполнении шагов установки onmessage включите очередь сообщений клиента этого this.

 

3.5 События

Следующее событие отправляется в объект ServiceWorker:

Имя события Интерфейс Отправлено, когда…
statechange Event Атрибут состояния state объекта ServiceWorker изменён.

Следующее событие отправляется в объект ServiceWorkerRegistration:

Имя события Интерфейс Отправлено, когда…
updatefound Event Изменяется регистрация работника службы, устанавливающего работника. (См. Шаг 8 алгоритма установки.)

Следующие события отправляются объекту ServiceWorkerContainer:

Имя события Интерфейс Отправлено, когда…
controllerchange Event Изменяется активный работник службы клиента работника службы. (См. Шаг 9.2 алгоритма Активации. Флаг пропуска ожидания работника службы вызывает активацию регистрации работника службы, в то время как клиенты работника службы используют регистрацию работника службы, navigator.serviceWorker.controller немедленно отображает активного рабочего как работника службы, который управляет клиентом работника службы.)
message Event Клиент работника службы получает сообщение от работника службы. См. postMessage(message, options).
messageerror Event Клиенту работника службы отправляется сообщение, которое не может быть десериализовано от работника службы. См. postMessage(message, options).

 

[SecureContext, Exposed=(Window,Worker)]
interface NavigationPreloadManager {
  Promise<undefined> enable();
  Promise<undefined> disable();
  Promise<undefined> setHeaderValue(ByteString value);
  Promise<NavigationPreloadState> getState();
};

dictionary NavigationPreloadState {
  boolean enabled = false;
  ByteString headerValue;
};

Шаги метода enable():

1. Пусть обещание promise станет новым обещанием.
2. Параллельно выполните следующие шаги:
3. Пусть регистрация registration будет связанной регистрацией работника службы этого this.
4. Если активный работник регистрации registration равен null, отклоните обещание promise с помощью исключения "InvalidStateError" DOMException и прервите эти шаги.
5. Установите флаг включения предварительной загрузки навигации registration.
6. Разрешить обещание promise с undefined.
7. Вернуть promise.

 

Шаги метода disable():

1. Пусть обещание promise станет новым обещанием.
2. Параллельно выполните следующие шаги:
3. Пусть регистрация registration будет связанной регистрацией работника службы этого this.
4. Если активный работник регистрации registration равен null, отклоните обещание promise с помощью исключения "InvalidStateError" DOMException и прервите эти шаги.
5. Снимите флаг включения предварительной загрузки навигации registration.
6. Разрешить обещание promise с undefined.
7. Вернуть promise.

Шаги метода setHeaderValue(value):

1. Пусть обещание promise станет новым обещанием.
2. Параллельно выполните следующие шаги:
3. Пусть регистрация registration будет связанной регистрацией работника службы этого this.
4. Если активный работник регистрации registration равен null, отклоните обещание promise с помощью исключения "InvalidStateError" DOMException и прервите эти шаги.
5. Установите значение заголовка предварительной загрузки навигации регистрации registration в значение value.
6. Разрешить обещание promise с undefined.
7. Вернуть promise.

 

Шаги метода getState():

1. Пусть обещание promise станет новым обещанием.
2. Параллельно выполните следующие шаги:
3. Пусть регистрация registration будет связанной регистрацией работника службы этого this.
4. Пусть состояние state будет новым словарем NavigationPreloadState.
5. Если установлен флаг включения предварительной загрузки навигации registration, установите для state["enabled"] значение true.
6. Задайте для state["headerValue"] значение заголовка предварительной загрузки навигации registration.
7. Выполните обещание promise с state.
8. Вернуть promise.

 

Информационные ссылки

Стандарт Service Workers Nightlyhttps://w3c.github.io/ServiceWorker/#document-context

Поделись записью