1. 동기
이 섹션은 비규범적입니다.
웹 애플리케이션은 전통적으로 네트워크에 접근할 수 있다는 가정을 합니다. 이 가정은 플랫폼 전반에 퍼져 있습니다. HTML 문서는 HTTP를 통해 로드되고, 전통적으로 모든 하위 리소스를 이후의 HTTP 요청을 통해 가져옵니다. 이는 웹 콘텐츠가 다른 기술 스택에 비해 불리하게 만듭니다.
서비스 워커는 내비게이션이 발생하려고 할 때 런타임이 시작할 수 있는 웹 워커 컨텍스트를 제공함으로써 이러한 불균형을 해소하기 위해 설계되었습니다. 이 이벤트 기반 워커는 출처와 경로(또는 패턴)에 대해 등록되므로, 해당 위치로 내비게이션이 발생할 때 참조될 수 있습니다. 네트워크 요청에 해당하는 이벤트가 워커로 전달되고, 워커가 생성한 응답은 기본 네트워크 스택 동작을 대체할 수 있습니다. 서비스 워커는 개념적으로 네트워크와 문서 렌더러 사이에 위치하므로, 서비스 워커가 오프라인 상태에서도 문서에 콘텐츠를 제공할 수 있게 합니다.
오프라인 문제를 해결하기 위한 이전의 시도에 익숙한 웹 개발자들은 그러한 솔루션의 유연성이 부족하다고 보고했습니다. 그 결과 서비스 워커는 개발자에게 추가적인 복잡성을 요구하는 대신 최대한의 유연성을 제공하기 위해 매우 절차적으로 설계되었습니다. 이러한 복잡성의 일부는 서비스 워커가 단일 스레드 실행 모델에서도 응답성을 유지해야 한다는 필요성에서 비롯됩니다. 그 결과, 서비스 워커에서 노출되는 API는 거의 전부 비동기적으로 설계되어, 다른 자바스크립트 환경에서 익숙한 패턴이지만 문서와 리소스 로딩의 블로킹을 피해야 한다는 점에서 더욱 강조되었습니다.
HTML5 애플리케이션 캐시를 사용하는 개발자들은 설계의 여러 속성이 복구 불가능한 오류를 유발한다고 보고한 바 있습니다. 서비스 워커의 핵심 설계 원칙 중 하나는 오류가 항상 복구 가능해야 한다는 점입니다. 서비스 워커의 업데이트 과정의 많은 세부사항은 이러한 위험을 피하도록 설계되었습니다.
서비스 워커는 문서가 아니라 이벤트와의 관계를 통해 시작되고 유지됩니다. 이러한 설계는 개발자와 벤더가 공유 워커 및 Chrome 배경 페이지에서 얻은 경험에서 크게 차용한 것입니다. 이러한 시스템에서 얻은 주요 교훈 중 하나는 리소스를 절약하고, 백그라운드 컨텍스트가 손실되거나 다시 시작될 수 있음을 개발자가 항상 염두에 두도록 백그라운드 처리 컨텍스트의 실행 시간을 제한해야 한다는 점입니다. 그 결과, 서비스 워커는 Chrome 배경 페이지의 후속 버전인 Chrome 이벤트 페이지와 매우 유사한 특성을 갖습니다. 서비스 워커는 사용자 에이전트에 의해 문서가 연결되지 않은 상태에서 시작될 수 있으며, 거의 언제라도 사용자 에이전트에 의해 종료될 수 있습니다. 개념적으로, 서비스 워커는 문서에서 메시지를 받지 않고도 시작, 이벤트 처리, 종료가 가능한 공유 워커로 생각할 수 있습니다. 개발자들은 서비스 워커가 초당 여러 번 시작되었다가 종료될 수 있음을 유념해야 합니다.
서비스 워커는 오리진에서 동작하는 범용, 이벤트 기반, 시간 제한이 있는 스크립트 컨텍스트입니다. 이러한 특성 덕분에 서비스 워커는 특정 문서의 컨텍스트 수명을 넘어설 수 있는 다양한 런타임 서비스(예: 푸시 알림 처리, 백그라운드 데이터 동기화, 타 오리진의 리소스 요청에 대한 응답, 고비용 데이터(예: 위치 정보나 자이로스코프)의 중앙 집중식 업데이트 수신 등)의 자연스러운 종단점이 됩니다.
2. 모델
2.1. 서비스 워커
서비스 워커는 웹 워커의 한 종류입니다. 서비스 워커는 등록한 서비스 워커 클라이언트의 출처에서 실행됩니다.
서비스 워커는
"parsed", "installing", "installed",
"activating", "activated", "redundant" 중 하나의 상태를 가집니다. 초기 값은 "parsed"입니다.
서비스 워커는
"classic" 또는 "module" 중 하나의 타입을 가집니다. 별도
명시가 없는 경우 "classic"입니다.
서비스 워커는 등록된 서비스 워커 레지스트레이션(서비스 워커 레지스트레이션)을 가집니다. 이는 자기 자신을 포함합니다.
서비스 워커는 글로벌 객체(ServiceWorkerGlobalScope
객체 또는 null)을 가집니다.
서비스 워커는 스크립트 리소스(스크립트)를 가집니다. 이는 해당 워커의 스크립트 리소스를 나타냅니다. 초기 값은 null입니다.
스크립트 리소스는 평가된 적 있음 플래그를 가집니다. 초기에는 설정되지 않습니다.
스크립트 리소스는 정책 컨테이너(policy container)를 가집니다. 초기에는 새로운 정책 컨테이너입니다.
서비스 워커는 스크립트 리소스 맵을 가집니다. 이는 순서 있는 맵으로, 키는 URL이고, 값은 응답입니다.
서비스 워커는 사용된 스크립트 집합(집합)을 가집니다. 각 항목은 URL입니다. 초기에는 새로운 집합입니다.
참고: 사용된 스크립트 집합은 설치 후 새 워커의 맵에서 사용하지 않는 리소스를 제거하기 위해 사용됩니다. 이는 업데이트 검사 과정에서 이전 워커의 맵을 기반으로 채워집니다.
서비스 워커는 skip waiting 플래그를 가집니다. 별도 명시가 없는 한 설정되지 않습니다.
서비스 워커는 클래식 스크립트 import됨 플래그를 가집니다. 초기에는 설정되지 않습니다.
서비스 워커는 처리할 이벤트 타입 집합(집합)을 가집니다. 각 항목은 이벤트 리스너의 이벤트 타입입니다. 초기에는 새로운 집합입니다.
서비스 워커는 확장 이벤트 집합(집합)을 가집니다. 각 항목은 ExtendableEvent입니다.
초기에는 새로운 집합입니다.
서비스 워커는 시작 상태를 가집니다. 이는 null 또는 Completion일 수 있으며, 초기에는 null입니다.
서비스 워커는 fetch 리스너가 모두 비어 있음 플래그를 가집니다. 초기에는 설정되지 않습니다.
서비스 워커는 라우터 규칙 목록(리스트의 RouterRule들)입니다.
초기에는 빈 리스트입니다.
서비스 워커는 실행 중이라고 합니다. 이는 이벤트 루프가 실행 중일 때를 의미합니다.
서비스 워커는 [[service worker queue]](병렬 큐)를 가집니다.
2.1.1. 수명
서비스 워커의
수명은 이벤트의 실행 수명에 연결되며, 서비스 워커 클라이언트가 ServiceWorker
객체에 보유한 참조와는 관련이 없습니다.
사용자 에이전트는 다음과 같은 상황에서 언제든지 서비스 워커를 종료할 수 있습니다:
-
처리할 이벤트가 없을 때.
-
이벤트를 처리하는 중에 무한 루프, 시간 제한 초과 등의 비정상 동작을 감지한 경우.
2.1.2. 이벤트
서비스 워커 명세에서는 서비스 워커 이벤트(각각은 이벤트)를 정의합니다. 여기에는 아래와 같은 것들이 포함됩니다(목록 참조):
2.2. 서비스 워커 타이밍
서비스 워커는 특정 시점을 표시하며, 나중에 navigation timing API와 resource timing API를 통해 노출된다.
서비스 워커 타이밍 정보는 구조체이다. 다음과 같은 항목을 가진다:
- 시작 시간
-
DOMHighResTimeStamp, 초기값은 0이다. - fetch 이벤트 디스패치 시간
-
DOMHighResTimeStamp, 초기값은 0이다. - 워커 라우터 평가 시작
-
DOMHighResTimeStamp, 초기값은 0이다. - 워커 캐시 조회 시작
-
DOMHighResTimeStamp, 초기값은 0이다. - 워커 매치된 라우터 소스
-
DOMString, 초기값은 빈 문자열이다. - 워커 최종 라우터 소스
-
DOMString, 초기값은 빈 문자열이다.
2.3. 서비스 워커 등록
서비스 워커 등록은 scope url, storage key, 서비스 워커 집합(서비스 워커), installing worker, waiting worker, active worker의 튜플입니다. 사용자 에이전트는 서비스 워커 등록을 단일 출처에 여러 개 활성화할 수 있습니다. 단 scope url이 서로 달라야 합니다. 동일한 scope url의 서비스 워커 등록이 이미 존재하는 경우, 기존 서비스 워커 등록이 대체됩니다.
서비스 워커 등록은 storage key(storage key)를 가집니다.
서비스 워커 등록은 scope url(URL)을 가집니다.
서비스 워커 등록은 installing worker(서비스 워커 또는 null)로, 상태가
"installing"입니다. 초기값은 null입니다.
서비스 워커 등록은 waiting worker(서비스 워커 또는 null)로, 상태가 "installed"입니다. 초기값은 null입니다.
서비스 워커 등록은 active worker(서비스 워커 또는 null)로, 상태가 "activating" 또는
"activated"입니다. 초기값은 null입니다.
서비스 워커 등록은 마지막 업데이트 검사 시간을 가집니다. 초기값은 null입니다.
서비스 워커 등록은 오래된(stale) 상태가 될 수 있습니다. 이 경우 등록의 마지막 업데이트 검사 시간이 null이 아니고, 현재 시간에서 마지막 업데이트 검사 시간을 뺀 초 단위의 차이가 86400보다 크면 해당됩니다.
서비스 워커 등록은 update via cache mode를 가집니다. 값은 "imports",
"all", "none" 중 하나이며, 초기값은 "imports"입니다.
서비스 워커 등록은 하나 이상의 작업 큐(task queue)를 가집니다. 이는 작업을 active worker의 이벤트 루프의 해당 작업 큐에서 백업합니다. (백업의 대상 작업 소스는 handle fetch task source와 handle functional event task source입니다.) 사용자 에이전트는 active worker의 작업을 서비스 워커 등록의 작업 큐에 덤프하며, 작업을 다시 큐로 active worker의 이벤트 루프의 해당 작업 큐에 재할당합니다. 작업 큐가 이벤트 루프에 의해 처리되는 것과 달리, 서비스 워커 등록의 작업 큐는 자체적으로 어떤 이벤트 루프에서도 처리되지 않습니다.
서비스 워커 등록은 NavigationPreloadManager
객체를 가집니다.
서비스 워커 등록은 navigation preload enabled 플래그를 가집니다. 초기에는 설정되지 않습니다.
서비스 워커 등록은 navigation preload header
값을 가집니다. 이는 바이트 시퀀스이며, 초기값은 `true`입니다.
서비스 워커 등록은 등록 해제됨(unregistered) 상태가 될 수 있습니다. 이때 registration map[해당 서비스 워커 등록의 (storage key, 직렬화된 scope url)]이 해당 서비스 워커 등록이 아닐 경우입니다.
2.3.1. 수명
사용자 에이전트는 등록된 서비스 워커 등록 목록을 명시적으로 등록 해제하지 않는 한 지속적으로 유지해야
합니다. 사용자 에이전트는 registration map을 가지고 있습니다. 이는 서비스 워커 등록의 (storage key, 직렬화된 scope url) 튜플과 해당 서비스
워커 등록을 저장합니다. 서비스 워커 등록의 수명은 해당 서비스 워커 클라이언트의
수명 내에서 이를 나타내는 ServiceWorkerRegistration
객체의 수명보다 깁니다.
2.4. 서비스 워커 클라이언트
서비스 워커 클라이언트는 environment입니다.
서비스 워커 클라이언트는 discarded flag를 가집니다. 초기에는 설정되지 않습니다.
각 서비스 워커 클라이언트는 다음 environment discarding steps를 따릅니다:
-
client의 discarded flag를 설정합니다.
참고: discard된 flag가 설정된 클라이언트는 구현에 따라 폐기될 수 있습니다.
서비스 워커 클라이언트는 origin이라는 알고리즘을 가집니다. 이는 서비스 워커 클라이언트가 environment settings object일 경우 origin을 반환하고, 그렇지 않으면 creation URL의 origin을 반환합니다.
window client는 서비스 워커 클라이언트 중 global object가 Window
객체인 경우입니다.
dedicated worker client는 서비스 워커 클라이언트 중 global object가 DedicatedWorkerGlobalScope
객체인 경우입니다.
shared worker client는 서비스 워커 클라이언트 중 global object가 SharedWorkerGlobalScope
객체인 경우입니다.
worker client는 dedicated worker client 또는 shared worker client입니다.
2.5. 제어 및 사용
서비스 워커 클라이언트는 자신의 로딩과 하위 리소스 처리에 사용되는 active service worker를 가집니다. 서비스 워커 클라이언트가 null이 아닌 active service worker를 가지면, 해당 클라이언트는 그 active service worker에 의해 제어됨(controlled) 상태가 됩니다. 서비스 워커 클라이언트가 제어됨 상태일 때, 해당 클라이언트는 서비스 워커의 등록 정보를 사용함(used) 상태라 합니다. 서비스 워커 클라이언트의 active service worker는 아래 하위 섹션에서 설명한 대로 결정됩니다.
이 섹션의 나머지 부분은 비규범적입니다.
이 섹션의 동작은 아직 완전히 명세되지 않았으며, HTML 표준에서 명세될 예정입니다. 관련 작업은 이슈와 풀 리퀘스트에서 추적 중입니다.
2.5.1. 윈도우 클라이언트 케이스
window client는 생성될 때, 즉 browsing context가 생성될 때와 내비게이션이 발생할 때 생성됩니다.
window client가 생성되는 과정에서 browsing context가 생성된다면:
browsing context의 초기 active document의 origin이 opaque origin이면, window client의 active service worker는 null로 설정합니다. 그렇지 않으면, 생성자 document의 서비스 워커 클라이언트의 active service worker로 설정합니다.
window client가 생성되는 과정에서 browsing context의 내비게이션이 발생한다면:
fetch가 HTTP fetch를 통해 라우팅된다면, window client의 active service worker는 서비스 워커 등록 매칭의 결과로 설정합니다. 그렇지 않고 생성된 document의 origin이 opaque origin이거나 생성자 document의 origin과 동일하지 않다면, window client의 active service worker는 null로 설정합니다. 그렇지 않으면, 생성자 document의 서비스 워커 클라이언트의 active service worker로 설정합니다.
참고: 초기 대체 내비게이션의 경우, window client가 생성될 때 browsing context가 생성되지만, active service worker 결정 방식은 위와 동일하게 적용됩니다.
참고: 샌드박스된
iframe
에서 allow-same-origin과 allow-scripts 샌드박싱 지시자가 없으면, 해당 active service worker 값이 null이
됩니다. 이는 origin이 opaque origin이기 때문입니다.
2.5.2. 워커 클라이언트 케이스
worker client는 사용자 에이전트가 워커 환경 설정 객체를 생성할 때, 즉 worker를 실행할 때 생성됩니다.
worker client가 생성될 때:
fetch가 HTTP fetch를 통해 라우팅된다면, worker client의 active service worker는 서비스 워커 등록 매칭의 결과로 설정합니다. 그렇지 않고 worker client의 origin이 opaque origin이거나, request의 URL이 blob URL이고 worker client의 origin이 동일하지 않다면, origin과 owner set의 마지막 worker client의 global object의 owner set과 동일하지 않다면, worker client의 active service worker는 null로 설정합니다. 그렇지 않으면, environment settings object의 마지막 owner set의 worker client의 global object의 owner set의 active service worker로 설정합니다.
참고: Window client와 worker client가 data: URL을 사용하면, 해당 active service worker 값은 null이 되며, 이는 origin이 opaque origin이기 때문입니다. Window client와 worker client가 blob URL을 사용하면, 생성자 document 또는 소유자의 active service worker를 상속받을 수 있습니다. 하지만 request의 origin이 생성자 document 또는 소유자의 origin과 동일하지 않으면, active service worker는 null로 설정됩니다.
2.6. 작업 소스
2.7. 사용자 에이전트 종료
사용자 에이전트는 저장된 서비스 워커 등록의 상태를 재시작 시에도 다음 규칙에 따라 반드시 유지해야 합니다:
-
설치 중인 워커는 지속되지 않고 버려집니다. 만약 설치 중인 워커가 해당 서비스 워커 등록의 유일한 서비스 워커였다면, 서비스 워커 등록도 버려집니다.
-
waiting worker는 active worker로 승격됩니다.
이를 위해 사용자 에이전트는 종료 시 Handle User Agent Shutdown을 반드시 호출해야 합니다.
3. 클라이언트 컨텍스트
// scope는 기본적으로 스크립트가 위치한 경로가 됩니다 // 이 예제에선 "/" 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 = {}); // eventoptions attribute EventHandler onstatechange ; };ServiceWorker includes AbstractWorker ;enum {ServiceWorkerState ,"parsed" ,"installing" ,"installed" ,"activating" ,"activated" };"redundant"
ServiceWorker
객체는 서비스 워커를
나타냅니다. 각 ServiceWorker
객체는 하나의 서비스
워커에 연결되어 있습니다. 여러 문서와 워커에서 ServiceWorker
인터페이스를 구현하는 별개의 객체들이 동시에 같은 서비스 워커에 연관될 수 있습니다.
ServiceWorker
객체는 ServiceWorkerState
객체를 가지고 있으며, 이는 서비스 워커의 상태와 연결되어 있습니다.
3.1.1. ServiceWorker
인스턴스 얻기
environment settings object는 service worker
object map을 가집니다. 이는 맵으로,
키는 서비스 워커이고, 값은 ServiceWorker
객체입니다.
-
objectMap을 environment의 service worker object map으로 한다.
-
objectMap[serviceWorker]이 존재하지 않으면 다음을 수행:
-
serviceWorkerObj를 environment의 Realm에서 생성된 새로운
ServiceWorker객체로 하고, serviceWorker와 연관시킨다. -
objectMap[serviceWorker]에 serviceWorkerObj를 할당한다.
-
-
objectMap[serviceWorker]을 반환한다.
3.1.2.
scriptURL
3.1.3.
state
state 속성은 마지막으로 설정된 값을
(ServiceWorkerState
열거형에서) 반환해야 합니다.
3.1.4. postMessage(message, transfer)
postMessage(message, transfer)
메서드 단계:
-
options를 «[ "transfer" → transfer ]»로 한다.
-
postMessage(message, options)를 message와 options로 호출한다.
3.1.5. postMessage(message, options)
postMessage(message, options)
메서드 단계:
-
serviceWorker를 service worker로, this가 나타내는 서비스 워커로 설정한다.
-
incumbentSettings를 현재 settings object로 설정한다.
-
incumbentGlobal를 incumbentSettings의 글로벌 객체로 설정한다.
-
serializeWithTransferResult를 StructuredSerializeWithTransfer(message, options["
transfer"]) 호출 결과로 설정한다. 예외가 발생하면 다시 던진다. -
"message"와 serviceWorker를 인자로 Should Skip Event 알고리즘을 실행한 결과가 true라면, return 한다.
-
다음 하위 단계들을 병렬로 실행한다:
-
Run Service Worker 알고리즘을 serviceWorker로 실행한 결과가 failure이면, return 한다.
-
Queue a task를 DOM manipulation task source 에 생성하여, 다음 단계들을 실행한다:
-
source를 incumbentGlobal 타입에 따라 결정한다:
ServiceWorkerGlobalScope- incumbentGlobal의 service worker를 serviceWorker의 relevant settings object의 글로벌 객체에서 get the service worker object 실행 결과로 선택한다.
Window- incumbentGlobal의
relevant settings
object를 나타내는
새로운
WindowClient객체로 선택한다. - 그 외
- incumbentGlobal의 연결된 worker를 나타내는
새로운
Client객체로 선택한다.
-
origin을 incumbentSettings의 origin 값으로 설정한다.
-
destination을 serviceWorker에 연결된
ServiceWorkerGlobalScope객체로 설정한다. -
deserializeRecord를 StructuredDeserializeWithTransfer(serializeWithTransferResult, destination의 Realm) 실행 결과로 설정한다.
예외가 발생하면, e를 event 생성 결과로 설정한다. 이벤트 이름은
messageerror이고,ExtendableMessageEvent를 사용하며, origin을 origin으로,source속성을 source로 초기화한다. -
그 외의 경우:
-
messageClone을 deserializeRecord의 [[Deserialized]] 값으로 설정한다.
-
newPorts를 frozen array로 생성하며, deserializeRecord의 [[TransferredValues]] 내 모든
MessagePort객체를 포함, 상대 순서 유지한다. -
e를 event 생성 결과로 설정. 이름은
message이고,ExtendableMessageEvent사용. origin을 origin으로,source를 source로,data를 messageClone으로,ports를 newPorts로 초기화한다.
-
-
Dispatch e를 destination에 보낸다.
-
Update Service Worker Extended Events Set을 serviceWorker와 e를 인자로 호출한다.
-
-
3.1.6. 이벤트 핸들러
아래는 이벤트 핸들러(및 해당 이벤트 핸들러 이벤트 타입)로, 이벤트 핸들러 IDL 속성으로 모든 ServiceWorker
인터페이스 객체가 반드시 지원해야 합니다:
| 이벤트 핸들러 | 이벤트 핸들러 이벤트 타입 |
|---|---|
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 <ServiceWorkerRegistration >update (); [NewObject ]Promise <boolean >unregister (); // eventattribute EventHandler onupdatefound ; };enum {ServiceWorkerUpdateViaCache ,"imports" ,"all" };"none"
ServiceWorkerRegistration
객체는 서비스 워커 등록(서비스 워커 등록)을 가집니다.
3.2.1. ServiceWorkerRegistration
인스턴스 얻기
environment settings object는 서비스 워커
등록 객체 맵을 가집니다. 이는 맵으로,
키는 서비스
워커 등록이고, 값은 ServiceWorkerRegistration
객체입니다.
-
objectMap을 environment의 서비스 워커 등록 객체 맵으로 한다.
-
objectMap[registration]이 존재하지 않으면 다음을 수행:
-
registrationObject를 environment의 Realm에서 생성된 새로운
ServiceWorkerRegistration객체로 한다. -
registrationObject의 서비스 워커 등록을 registration으로 설정한다.
-
registrationObject의
installing속성을 null로 설정한다. -
registrationObject의
waiting속성을 null로 설정한다. -
registrationObject의
active속성을 null로 설정한다. -
registration의 installing worker가 null이 아니면, registrationObject의
installing속성을 registration의 installing worker를 environment에서 서비스 워커 객체 얻기로 반환한 값으로 설정한다. -
registration의 waiting worker가 null이 아니면, registrationObject의
waiting속성을 registration의 waiting worker를 environment에서 서비스 워커 객체 얻기로 반환한 값으로 설정한다. -
registration의 active worker가 null이 아니면, registrationObject의
active속성을 registration의 active worker를 environment에서 서비스 워커 객체 얻기로 반환한 값으로 설정한다. -
objectMap[registration]에 registrationObject를 할당한다.
-
-
objectMap[registration]을 반환한다.
3.2.2. installing
installing 속성은 마지막으로
설정된 값을 반환해야 합니다.
참고: Realm 내에서는, 연관된 서비스
워커마다 하나의 ServiceWorker
객체만 존재합니다.
3.2.3. waiting
waiting 속성은 마지막으로 설정된
값을 반환해야 합니다.
참고: Realm 내에서는, 연관된 서비스
워커마다 하나의 ServiceWorker
객체만 존재합니다.
3.2.4. active
active 속성은 마지막으로 설정된
값을 반환해야 합니다.
참고: Realm 내에서는, 연관된 서비스
워커마다 하나의 ServiceWorker
객체만 존재합니다.
3.2.5. navigationPreload
navigationPreload
getter 단계는 서비스 워커 등록의 NavigationPreloadManager
객체를 반환한다.
3.2.6. scope
scope getter 단계는 서비스 워커 등록의 직렬화된 scope url을 반환한다.
registration.scope의 값은
navigator.serviceWorker.ready.then(registration => console.log(registration.scope))
와 같이 얻을 때 "https://example.com/"이 됩니다.
3.2.7. updateViaCache
updateViaCache getter
단계는 서비스 워커 등록의 update
via cache mode를 반환한다.
3.2.8. update()
update() 메서드 단계:
-
registration을 서비스 워커 등록으로 한다.
-
newestWorker를 최신 워커 얻기 알고리즘을 registration을 인자로 실행한 결과로 한다.
-
newestWorker가 null이면, "
InvalidStateError"DOMException으로 거부된 프라미스를 반환하고 단계를 중단한다. -
this의 관련 글로벌 객체 globalObject가
ServiceWorkerGlobalScope객체이고, globalObject에 연관된 서비스 워커의 상태가 "installing"이면, "InvalidStateError"DOMException으로 거부된 프라미스를 반환하고 단계를 중단한다. -
promise를 프라미스로 한다.
-
job을 작업 생성 알고리즘을 update, registration의 storage key, registration의 scope url, newestWorker의 script url, promise, this의 관련 settings object를 인자로 실행한 결과로 한다.
-
job의 worker type을 newestWorker의 type으로 설정한다.
-
작업 예약을 job로 호출한다.
-
promise를 반환한다.
3.2.9. unregister()
참고: unregister()
메서드는 서비스 워커 등록을 등록 해제합니다. 현재 제어된 서비스 워커 클라이언트의 active service worker의 등록 정보는 해당 서비스 워커 등록을 사용하는 모든 서비스 워커 클라이언트 (자기 자신 포함)가 언로드될 때까지 유효합니다. 즉,
unregister()
메서드는 이후의 내비게이션에만 영향을 미칩니다.
unregister()
메서드 단계:
-
registration을 서비스 워커 등록으로 한다.
-
promise를 새 프라미스로 한다.
-
job을 작업 생성 알고리즘을 unregister, registration의 storage key, registration의 scope url, null, promise, this의 관련 settings object를 인자로 실행한 결과로 한다.
-
작업 예약을 job로 호출한다.
-
promise를 반환한다.
3.2.10. 이벤트 핸들러
아래는 이벤트 핸들러(및 해당 이벤트 핸들러 이벤트 타입)로, 이벤트 핸들러 IDL 속성으로 모든 ServiceWorkerRegistration
인터페이스 객체가 반드시 지원해야 합니다:
| 이벤트 핸들러 | 이벤트 핸들러 이벤트 타입 |
|---|---|
onupdatefound
| updatefound
|
3.3.
navigator.serviceWorker
partial interface Navigator { [SecureContext ,SameObject ]readonly attribute ServiceWorkerContainer serviceWorker ; };partial interface WorkerNavigator { [SecureContext ,SameObject ]readonly attribute ServiceWorkerContainer serviceWorker ; };
serviceWorker getter 단계는
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 ((TrustedScriptURL or USVString ),scriptURL optional RegistrationOptions = {}); [options NewObject ]Promise <(ServiceWorkerRegistration or undefined )>getRegistration (optional USVString = ""); [clientURL NewObject ]Promise <FrozenArray <ServiceWorkerRegistration >>getRegistrations ();undefined startMessages (); // eventsattribute EventHandler oncontrollerchange ;attribute EventHandler onmessage ; // event.source of message events is ServiceWorker objectattribute EventHandler onmessageerror ; };
dictionary {RegistrationOptions USVString ;scope WorkerType = "classic";type ServiceWorkerUpdateViaCache = "imports"; };updateViaCache
사용자 에이전트는 ServiceWorkerContainer
객체를 Navigator
객체 또는 WorkerNavigator
객체가 생성될 때 만들고 해당 객체와 연관시켜야 한다.
ServiceWorkerContainer
객체는 서비스 워커 등록을 등록, 해제, 업데이트하는 기능을 제공하며, 서비스 워커 등록 및 연관된 서비스 워커의 상태에 접근할 수 있다.
ServiceWorkerContainer
객체는 연관된 서비스 워커 클라이언트를 가진다. 이는 서비스 워커 클라이언트로, global object가 Navigator
객체 또는 WorkerNavigator
객체와 연관된 것이다.
ServiceWorkerContainer
객체는 연관된 ready promise
(promise 또는 null)을 가진다. 초기값은 null이다.
ServiceWorkerContainer
객체는 작업 소스인 클라이언트 메시지 큐를 가진다(초기값은 비어 있음). 클라이언트 메시지 큐는 활성/비활성화
상태가 될 수 있으며, 초기에는 비활성화 상태다. ServiceWorkerContainer
객체의 클라이언트 메시지 큐가 활성화되면, 이벤트 루프는 이를 작업 소스 중 하나로 사용해야 한다. ServiceWorkerContainer
객체의 관련 글로벌 객체가 Window
객체일 때, 클라이언트 메시지 큐에 대기 중인 모든 작업은 해당 settings object의 연관된 문서와 연관되어야 한다.
3.4.1. controller
controller
속성은 다음 단계를 반드시 실행해야 한다:
-
client를 this의 서비스 워커 클라이언트로 한다.
-
client의 active service worker 값이 null이면, null을 반환한다.
-
client의 active service worker를 서비스 워커 객체 얻기로 얻은 값을 this의 settings object에서 반환한다.
참고: navigator.serviceWorker.controller
는 요청이 강제 새로고침(shift+refresh)일 때 null을 반환한다.
3.4.2. ready
ready 속성은 다음 단계를
반드시 실행해야 한다:
-
this의 ready promise가 null이면, this의 ready promise를 새 프라미스로 설정한다.
-
readyPromise를 this의 ready promise로 한다.
-
readyPromise가 pending이면, 다음 하위 단계를 병렬로 실행한다:
-
client를 this의 서비스 워커 클라이언트로 한다.
-
storage key를 obtain a storage key를 client에 대해 실행한 결과로 한다.
-
registration을 서비스 워커 등록 매칭을 storage key와 client의 creation URL을 인자로 실행한 결과로 한다.
-
registration이 null이 아니고, registration의 active worker가 null이 아니면, 작업 큐에 추가를 readyPromise의 settings object의 responsible event loop에서 DOM manipulation 작업 소스로 실행하여, readyPromise를 서비스 워커 등록 객체 얻기로 registration을 readyPromise의 settings object에서 반환한 값으로 resolve한다.
-
-
readyPromise를 반환한다.
참고: 반환된 ready promise는 절대 reject되지 않는다. 만약 이 알고리즘에서 resolve되지 않으면, 매칭되는 서비스 워커 등록이 등록되고 active worker가 설정될 때 결국 resolve된다. (Activate 알고리즘 단계 참고)
3.4.3. register(scriptURL, options)
참고: register(scriptURL, options)
메서드는 주어진 scope
url에 대해 서비스 워커 등록을 생성하거나 업데이트한다. 성공 시, 서비스 워커 등록은 제공된 scriptURL을 scope url에 연결하며,
이후 navigation
matching에 사용된다.
register(scriptURL, options)
메서드 단계:
-
p를 프라미스(promise)로 두자.
-
scriptURL을 Trusted Type 호환 문자열 얻기를
TrustedScriptURL, this의 관련된 글로벌 오브젝트, scriptURL, "ServiceWorkerContainer register", "script"와 함께 호출한 결과로 설정한다. -
client를 this의 service worker 클라이언트로 둔다.
-
scriptURL을 파싱 scriptURL에 대해 this의 관련 설정 객체의 API 기본 URL과 함께 파싱한 결과로 한다.
-
scopeURL을 null로 둔다.
-
만약 options["
scope"] 가 존재한다면, scopeURL을 파싱 options["scope"] 에 대해 this의 관련 설정 객체의 API 기본 URL과 함께 파싱한 결과로 설정한다. -
등록 시작을 scopeURL, scriptURL, p, client, client의 생성 URL, options["
type"], 및 options["updateViaCache"] 와 함께 호출한다. -
p를 반환한다.
3.4.4. getRegistration(clientURL)
getRegistration(clientURL)
메서드 단계:
-
client를 this의 서비스 워커 클라이언트로 둔다.
-
storage key를 client가 주어졌을 때 스토리지 키를 얻는 알고리즘을 실행한 결과로 둔다.
-
clientURL을 this의 관련 설정 객체의 API 기준 URL을 사용하여 clientURL을 구문 분석한 결과로 둔다.
-
clientURL이 실패이면,
TypeError로 거부된 프로미스를 반환한다. -
clientURL의 프래그먼트를 null로 설정한다.
-
clientURL의 출처가 client의 출처와 같지 않으면, "
SecurityError"DOMException으로 거부된 promise를 반환한다. -
promise를 새로운 프로미스로 둔다.
-
다음 하위 단계를 병렬로 실행한다.
-
registration을 storage key와 clientURL이 주어졌을 때 서비스 워커 등록 일치시키기를 실행한 결과로 둔다.
-
promise의 관련 설정 객체의 담당 이벤트 루프에, DOM 조작 태스크 소스를 사용하여 다음 단계를 실행하는 태스크를 큐에 넣는다.
-
registration이 null이면, promise를 undefined로 이행하고 이 단계를 중단한다.
-
promise의 관련 설정 객체에서 registration을 나타내는 서비스 워커 등록 객체를 가져온 결과로 promise를 이행한다.
-
-
-
promise를 반환한다.
3.4.5. getRegistrations()
getRegistrations()
메서드 단계:
-
client를 this의 서비스 워커 클라이언트로 둔다.
-
client storage key를 client가 주어졌을 때 스토리지 키를 얻는 알고리즘을 실행한 결과로 둔다.
-
promise를 새 프로미스로 둔다.
-
다음 단계를 병렬로 실행한다.
-
registrations를 새로운 리스트로 둔다.
-
promise의 관련 설정 객체의 담당 이벤트 루프에, DOM 조작 태스크 소스를 사용하여 다음 단계를 실행하는 태스크를 큐에 넣는다.
-
-
promise를 반환한다.
3.4.6. startMessages()
startMessages()
메서드 단계는 this의 클라이언트 메시지 큐가 비활성화 상태라면 활성화한다.
3.4.7. 이벤트 핸들러
아래는 이벤트 핸들러(및 해당 이벤트 핸들러 이벤트 타입)로, 이벤트 핸들러 IDL 속성으로 모든 ServiceWorkerContainer
인터페이스 객체가 반드시 지원해야 한다:
| 이벤트 핸들러 | 이벤트 핸들러 이벤트 타입 |
|---|---|
oncontrollerchange
| controllerchange
|
onmessage
| message
|
onmessageerror
| messageerror
|
onmessage
setter가 처음 수행될 때, this의 클라이언트 메시지 큐를 활성화한다.
3.5. 이벤트
다음 이벤트는 ServiceWorker
객체에서 디스패치됩니다:
| 이벤트 이름 | 인터페이스 | 언제 디스패치되는가… |
|---|---|---|
statechange
| Event
| state
속성이 ServiceWorker
객체에서 변경될 때.
|
다음 이벤트는 ServiceWorkerRegistration
객체에서 디스패치됩니다:
| 이벤트 이름 | 인터페이스 | 언제 디스패치되는가… |
|---|---|---|
updatefound
| Event
| 서비스 워커 등록의 installing worker가 변경될 때. (설치 알고리즘의 8단계 참고) |
다음 이벤트들은 ServiceWorkerContainer
객체에서 디스패치됩니다:
| 이벤트 이름 | 인터페이스 | 언제 디스패치되는가… |
|---|---|---|
controllerchange
| Event
| 서비스 워커 클라이언트의 active service worker
값이 변경될 때. (활성화 알고리즘의
9.2단계 참고. skip waiting 플래그가 설정된 서비스 워커는 서비스 워커 등록 활성화를 서비스 워커 클라이언트가 사용 중인 상황에서 발생시킬 수 있으며, navigator.serviceWorker.controller
값은 즉시 active worker를 서비스 워커로 반영하여 제어 중인 서비스 워커 클라이언트임을 나타냅니다.)
|
message
| MessageEvent
| 서비스 워커 클라이언트가 서비스 워커로부터 메시지를 받을 때. postMessage(message, options)
참고.
|
messageerror
| MessageEvent
| 서비스 워커 클라이언트가 서비스 워커로부터 역직렬화할 수 없는 메시지를 받을 때. postMessage(message, options)
참고.
|
3.6.
NavigationPreloadManager
[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
3.6.1. enable()
enable() 메서드 단계는 다음과 같다:
-
promise를 새 프로미스로 둔다.
-
다음 단계를 병렬로 실행한다:
-
registration의 활성 워커가 null이면, 태스크를 큐에 추가한다. promise의 관련 설정 객체의 담당 이벤트 루프에서 DOM 조작 태스크 소스를 사용하여 promise를 "
InvalidStateError"DOMException으로 거부하고, 이 단계들을 중단한다. -
registration의 내비게이션 프리로드 활성화 플래그를 설정한다.
-
태스크를 큐에 추가한다. promise의 관련 설정 객체의 담당 이벤트 루프에서 DOM 조작 태스크 소스를 사용하여 promise를 undefined로 이행한다.
-
promise를 반환한다.
3.6.2. disable()
disable() 메서드 단계는 다음과
같다:
-
promise를 새 promise로 둔다.
-
다음 단계를 병렬로 실행한다:
-
registration을 this의 연관된 service worker registration으로 둔다.
-
registration의 active worker가 null이면, task를 큐에 넣어 promise의 relevant settings object의 responsible event loop에서, DOM manipulation task source를 사용해, promise를 reject하고 "
InvalidStateError"DOMException으로 처리한 뒤, 이 단계들을 중단한다. -
registration의 navigation preload enabled flag를 해제한다.
-
task를 큐에 넣어 promise의 relevant settings object의 responsible event loop에서, DOM manipulation task source를 사용해, promise를 undefined로 resolve한다.
-
-
promise를 반환한다.
3.6.3. setHeaderValue(value)
setHeaderValue(value)
메서드 단계는 다음과 같다:
-
value를 정규화한 결과를 value로 둔다.
-
value가 header value가 아니면,
TypeError로 거부된 promise를 반환한다. -
promise를 새 promise로 둔다.
-
다음 단계를 병렬로 실행한다:
-
registration을 this의 연관된 service worker registration으로 둔다.
-
registration의 active worker가 null이면, task를 큐에 넣어 promise의 relevant settings object의 responsible event loop에서, DOM manipulation task source를 사용해, promise를 reject하고 "
InvalidStateError"DOMException으로 처리한 뒤, 이 단계들을 중단한다. -
registration의 navigation preload header value를 value로 설정한다.
-
task를 큐에 넣어 promise의 relevant settings object의 responsible event loop에서, DOM manipulation task source를 사용해, promise를 undefined로 resolve한다.
-
-
promise를 반환한다.
3.6.4. getState()
getState() 메서드 단계는 다음과
같다:
-
promise를 새 promise로 둔다.
-
다음 단계를 병렬로 실행한다:
-
registration을 this의 연관된 service worker registration으로 둔다.
-
state를 새로운
NavigationPreloadState사전으로 둔다. -
registration의 navigation preload enabled flag가 설정되어 있으면, state["
enabled"]를 true로 설정한다. -
state["
headerValue"]를 registration의 navigation preload header value로 설정한다. -
task를 큐에 넣어 promise의 relevant settings object의 responsible event loop에서, DOM manipulation task source를 사용해 promise를 state로 resolve한다.
-
-
promise를 반환한다.
4. 실행 컨텍스트
// caching.js self. addEventListener( "install" , event=> { event. waitUntil( // 리소스 캐시를 연다. caches. open( "shell-v1" ). then( cache=> { // 리소스를 가져오는 과정을 시작한다. 모든 리소스가 저장되어야 성공한다. // 하나라도 실패하면 전체 작업이 실패한다. return cache. addAll([ "/app.html" , "/assets/v1/base.css" , "/assets/v1/app.js" , "/assets/v1/logo.png" , "/assets/v1/intro_video.webm" ]); }) ); }); self. addEventListener( "fetch" , event=> { // 서비스 워커가 성공적으로 설치되고 활성화되어야만 "fetch" 이벤트가 전달된다. // 캐시의 모든 작업은 비동기이므로, URL 매칭도 포함해 promise를 사용한다. e.respondWith()도 promise를 받을 수 있다: event. respondWith( caches. match( e. request). then( response=> { return response|| fetch( e. request); }). catch (() => { return caches. match( "/fallback.html" ); }) ); });
4.1. ServiceWorkerGlobalScope
[Global =(Worker ,ServiceWorker ),Exposed =ServiceWorker ,SecureContext ]interface :ServiceWorkerGlobalScope WorkerGlobalScope { [SameObject ]readonly attribute Clients clients ; [SameObject ]readonly attribute ServiceWorkerRegistration registration ; [SameObject ]readonly attribute ServiceWorker serviceWorker ; [NewObject ]Promise <undefined >skipWaiting ();attribute EventHandler oninstall ;attribute EventHandler onactivate ;attribute EventHandler onfetch ;attribute EventHandler onmessage ;attribute EventHandler onmessageerror ; };
ServiceWorkerGlobalScope
객체는 서비스 워커의
글로벌 실행 컨텍스트를 나타낸다.
ServiceWorkerGlobalScope
객체는 서비스 워커(서비스 워커)와 연관된다.
ServiceWorkerGlobalScope
객체는 import
스크립트 캐시 무시 플래그를 가진다. 처음에는 해제되어 있다.
ServiceWorkerGlobalScope
객체는 race response map을 가진다. 이는
순서가 있는 map으로, key는 request이고 value는 race response이다.
race
response는 구조체로, "race-network-and-fetch-handler"
실행 시 네트워크 응답을 담는다. value는 response, "pending", 또는 null 이다.
참고: ServiceWorkerGlobalScope
객체는 오리진에서 실행되는 일반적인 이벤트 기반, 시간 제한 스크립트 실행 컨텍스트를 제공한다. 등록에 성공하면 서비스 워커는 이벤트와의 관계에 따라 시작·유지·종료된다. 서비스 워커 클라이언트와는 관련
없다. 서비스 워커
내부에서는 동기 요청을 시작하면 안 된다.
4.1.1. clients
4.1.2. registration
registration getter 단계는 서비스 워커 registration 객체를 this의 서비스 워커의 containing service worker
registration을 this의 관련 설정 객체에서 반환한다.
4.1.3. serviceWorker
serviceWorker getter 단계는
서비스 워커 객체를 this의 서비스 워커를 this의 관련 설정 객체에서 반환한다.
4.1.4. skipWaiting()
참고: skipWaiting()
메서드는 이 서비스
워커가 registration의 대기
위치에서 활성으로
진행하도록 한다. 서비스 워커 클라이언트가 사용 중이어도 registration이 진행된다.
skipWaiting()
메서드 단계는 다음과 같다:
-
promise를 새로운 프라미스로 설정한다.
-
다음 하위 단계들을 병렬로 실행한다:
-
서비스 워커의 skip waiting 플래그를 설정한다.
-
Try Activate를 서비스 워커의 containing service worker registration에 대해 호출한다.
-
태스크를 큐에 넣는다 서비스 워커의 담당 이벤트 루프에서, promise를 undefined로 이행하기 위해 태스크를 큐에 넣는다.
-
-
promise를 반환한다.
4.1.5. 이벤트 핸들러
다음은 이벤트 핸들러(그리고 대응되는 이벤트 핸들러 이벤트 타입)로서, 반드시 ServiceWorkerGlobalScope
인터페이스를 구현하는 모든 객체가 지원해야 한다:
| 이벤트 핸들러 | 이벤트 핸들러 이벤트 타입 |
|---|---|
oninstall
| install
|
onactivate
| activate
|
onfetch
| fetch
|
onmessage
| message
|
onmessageerror
| messageerror
|
4.2. 클라이언트
[Exposed =ServiceWorker ]interface {Client readonly attribute USVString url ;readonly attribute FrameType frameType ;readonly attribute DOMString id ;readonly attribute ClientType type ;undefined postMessage (any ,message sequence <object >);transfer undefined postMessage (any ,message optional StructuredSerializeOptions = {}); }; [options Exposed =ServiceWorker ]interface :WindowClient Client {readonly attribute VisibilityState visibilityState ;readonly attribute boolean focused ; [SameObject ]readonly attribute FrozenArray <USVString >ancestorOrigins ; [NewObject ]Promise <WindowClient >focus (); [NewObject ]Promise <WindowClient ?>navigate (USVString ); };url enum {FrameType ,"auxiliary" ,"top-level" ,"nested" };"none"
Client
객체는 서비스 워커 클라이언트
(a 서비스 워커 클라이언트)와 연관되어 있다.
Client
객체는 프레임 타입과 연관되어 있는데, 이는
"auxiliary", "top-level", "nested", "none" 중
하나이다.
별도의 명시가 없으면 "none"이다.
WindowClient
객체는 브라우징 컨텍스트와 연관되어 있는데,
이는 해당 서비스 워커 클라이언트의 글로벌 객체의 브라우징 컨텍스트이다.
WindowClient
객체에는 visibility state가 연관되어 있으며, 이는 visibilityState
속성값 중 하나입니다.
WindowClient
객체는 포커스 상태와 연관되어 있는데, true 또는 false (초기값은 false)이다.
WindowClient
객체는 조상 출처 배열과 연관되어 있다.
4.2.1.
url
url getter 단계는 this가 연관된 서비스 워커 클라이언트의 직렬화된 생성 URL을 반환한다.
4.2.2.
frameType
4.2.3.
id
id getter 단계는 this가 연관된 서비스 워커 클라이언트의 id를 반환한다.
4.2.4.
type
type getter 단계는 다음과 같다:
-
client를 this의 서비스 워커 클라이언트로 한다.
-
client가 환경 설정 객체라면:
-
client가 window client라면
"window"를 반환한다. -
그 외에 client가 dedicated worker client라면
"worker"를 반환한다. -
그 외에 client가 shared worker client라면
"sharedworker"를 반환한다.
-
-
그 외의 경우:
-
"window"를 반환한다.
-
4.2.5.
postMessage(message, transfer)
postMessage(message, transfer)
메서드 단계는 다음과 같다:
-
options를 «[ "transfer" → transfer ]»로 한다.
-
postMessage(message, options)를 message와 options를 인수로 하여 호출한다.
4.2.6. postMessage(message, options)
postMessage(message, options)
메서드 단계는 다음과 같다:
-
contextObject를 this로 둔다.
-
sourceSettings를 contextObject의 relevant settings object로 둔다.
-
serializeWithTransferResult를 StructuredSerializeWithTransfer(message, options["
transfer"])의 결과로 둔다. 예외가 있으면 그대로 다시 던진다. -
다음 단계를 병렬로 실행한다:
-
targetClient를 null로 둔다.
-
각 service worker client client에 대해:
-
client가 contextObject의 service worker client이면, targetClient를 client로 설정하고, 중단한다.
-
-
targetClient가 null이면, 반환한다.
-
destination을, 연관된 service worker client가 targetClient인
ServiceWorkerContainer객체로 둔다. -
다음 단계를 실행하는 task를 destination의 client message queue에 추가한다:
-
origin을 sourceSettings의 origin으로 둔다.
-
source를, contextObject의 relevant global object의 service worker를 targetClient에서 나타내는 service worker object를 가져온 결과로 둔다.
-
deserializeRecord를 StructuredDeserializeWithTransfer(serializeWithTransferResult, destination의 relevant Realm)으로 둔다.
이 과정에서 예외가 발생하면 이를 포착하고, destination에서 이름이
messageerror인 이벤트를 발생시키며MessageEvent를 사용한다. 이때 그 origin은 origin으로 초기화하고source속성은 source로 초기화한 다음, 이 단계들을 중단한다. -
messageClone을 deserializeRecord.[[Deserialized]]로 둔다.
-
newPorts를, 있다면 deserializeRecord.[[TransferredValues]]에 있는 모든
MessagePort객체로 구성된 새로운 frozen array로 둔다. -
destination에서 이름이
message인 이벤트를 디스패치하며MessageEvent를 사용한다. 이때 그 origin은 origin으로 초기화하고,source속성은 source로,data속성은 messageClone으로,ports속성은 newPorts로 초기화한다.
-
-
4.2.7. visibilityState
4.2.8.
focused
4.2.9. ancestorOrigins
4.2.10.
focus()
focus() 메서드 단계는 다음과 같다:
-
이 origin에 속한 어떤
Window도 transient activation을 갖고 있지 않다면, "InvalidAccessError"DOMException으로 거부된 promise를 반환한다. -
serviceWorkerEventLoop를 surrounding agent의 event loop로 둔다.
-
promise를 새로운 promise로 둔다.
-
task를 큐에 넣어 this의 연관된 service worker client의 responsible event loop에서, user interaction task source를 사용해 다음 단계를 실행한다:
-
focusing steps를 this의 browsing context와 함께 실행한다.
-
frameType을, Get Frame Type을 this의 browsing context와 함께 실행한 결과로 둔다.
-
visibilityState를 this의 browsing context의 active document의
visibilityState속성 값으로 둔다. -
focusState를 has focus steps를 this의 browsing context의 active document와 함께 실행한 결과로 둔다.
-
ancestorOriginsList를 this의 browsing context의 active document의 ancestor origins list의 연관된 목록으로 둔다.
-
task를 큐에 넣어 serviceWorkerEventLoop에서 DOM manipulation task source를 사용해 다음 단계를 실행한다:
-
windowClient를 Create Window Client를 this의 연관된 service worker client, frameType, visibilityState, focusState, ancestorOriginsList와 함께 실행한 결과로 둔다.
-
windowClient의 focus state가 true이면, promise를 windowClient로 resolve한다.
-
그렇지 않으면, promise를
TypeError로 reject한다.
-
-
-
promise를 반환한다.
4.2.11.
navigate(url)
navigate(url) 메서드 단계는 다음과 같다:
-
url을 파싱한 결과를 url로 두되, 기준은 this의 relevant settings object의 API base URL로 한다.
-
url이 failure이면, promise를
TypeError로 거부하여 반환한다. -
url이
about:blank이면, promise를TypeError로 거부하여 반환한다. -
this의 연관된 service worker client의 active service worker가 this의 relevant global object의 service worker가 아니면, promise를
TypeError로 거부하여 반환한다. -
serviceWorkerEventLoop를 current global object의 event loop로 둔다.
-
promise를 새로운 promise로 둔다.
-
task를 큐에 넣어 this의 연관된 service worker client의 responsible event loop에서 user interaction task source를 사용하여 다음 단계를 실행한다:
-
browsingContext를 this의 browsing context로 둔다.
-
browsingContext의 associated document가 fully active가 아니면, task를 큐에 넣어 serviceWorkerEventLoop에서 DOM manipulation task source를 사용해 promise를
TypeError로 reject하고, 이 단계들을 중단한다. -
HandleNavigate: Navigate를 실행하여 browsingContext를 url로 이동시키되, browsingContext의 associated document를 사용하고 exceptionsEnabled를 true로 한다.
-
HandleNavigate 단계에서 호출된 알고리즘 단계가 예외를 던지면, task를 큐에 넣어 serviceWorkerEventLoop에서 DOM manipulation task source를 사용해 그 예외로 promise를 reject하고, 이 단계들을 중단한다.
-
frameType을 Get Frame Type을 browsingContext와 함께 실행한 결과로 둔다.
-
visibilityState를 browsingContext의 active document의
visibilityState속성 값으로 둔다. -
focusState를 has focus steps를 browsingContext의 active document와 함께 실행한 결과로 둔다.
-
ancestorOriginsList를 browsingContext의 active document의 ancestor origins list의 연관된 목록으로 둔다.
-
task를 큐에 넣어 serviceWorkerEventLoop에서 DOM manipulation task source를 사용해 다음 단계를 실행한다:
-
browsingContext의
Window객체의 environment settings object의 creation URL의 origin이 동일한 것이 service worker의 origin이 아니면, promise를 null로 resolve하고 이 단계들을 중단한다. -
windowClient를 Create Window Client를 this의 service worker client, frameType, visibilityState, focusState, ancestorOriginsList와 함께 실행한 결과로 둔다.
-
promise를 windowClient로 resolve한다.
-
-
-
promise를 반환한다.
4.3.
Clients
[Exposed =ServiceWorker ]interface { // The objects returned will be new instances every time [Clients NewObject ]Promise <(Client or undefined )>get (DOMString ); [id NewObject ]Promise <FrozenArray <Client >>matchAll (optional ClientQueryOptions = {}); [options NewObject ]Promise <WindowClient ?>openWindow (USVString ); [url NewObject ]Promise <undefined >claim (); };
dictionary {ClientQueryOptions boolean =includeUncontrolled false ;ClientType = "window"; };type
enum {ClientType ,"window" ,"worker" ,"sharedworker" };"all"
사용자 에이전트는 Clients
객체를 ServiceWorkerGlobalScope
객체가 생성될 때 반드시 생성하고 해당 객체에 연관시켜야 한다.
4.3.1.
get(id)
get(id) 메서드 단계는 다음과 같다:
-
promise를 새로운 promise로 둔다.
-
다음 하위 단계를 병렬로 실행한다:
-
service worker client client 각각에 대해, client가 주어졌을 때 storage key를 얻기를 실행한 결과가 연관된 service worker의 containing service worker registration의 storage key와 같은 경우:
-
client의 execution ready flag가 설정되거나 client의 discarded flag가 설정될 때까지 기다린다.
-
client의 execution ready flag가 설정되어 있으면, task를 큐에 넣어 promise의 relevant settings object의 responsible event loop에서, DOM manipulation task source를 사용하여 다음 단계를 실행한다:
-
Resolve Get Client Promise를 client와 promise로 호출한다.
-
이 단계들을 중단한다.
-
-
task를 큐에 넣어 promise의 relevant settings object의 responsible event loop에서, DOM manipulation task source를 사용해 promise를 undefined로 resolve한다.
-
-
promise를 반환한다.
4.3.2.
matchAll(options)
matchAll(options) 메서드 단계는 다음과 같다:
-
promise를 새 프로미스로 둔다.
-
다음 단계를 병렬로 실행한다.
-
targetClients를 새 목록으로 둔다.
-
client가 주어졌을 때 스토리지 키를 얻기를 실행한 결과가 연결된 서비스 워커의 포함 서비스 워커 등록의 스토리지 키와 같은 각 서비스 워커 클라이언트 client에 대해:
-
matchedWindowData를 새 목록으로 둔다.
-
matchedClients를 새 목록으로 둔다.
-
targetClients에 있는 각 서비스 워커 클라이언트 client에 대해:
-
options["
type"]이"window"또는"all"이고, client가 환경 설정 객체가 아니거나 윈도 클라이언트이면:-
windowData를 «[ "client" → client, "ancestorOriginsList" → 새 목록 ]»으로 둔다.
-
browsingContext를 null로 둔다.
-
isClientEnumerable을 true로 둔다.
-
client가 환경 설정 객체이면, browsingContext를 client의 전역 객체의 브라우징 컨텍스트로 설정한다.
-
그렇지 않으면, browsingContext를 client의 대상 브라우징 컨텍스트로 설정한다.
-
browsingContext의 이벤트 루프에서 사용자 상호작용 태스크 소스를 사용하여 다음 하위 단계를 실행하도록 태스크 task를 큐에 넣는다.
-
browsingContext가 폐기되었으면, isClientEnumerable을 false로 설정하고 이 단계들을 중단한다.
-
client가 윈도 클라이언트이고 client의 연결된 문서가 browsingContext의 활성 문서가 아니면, isClientEnumerable을 false로 설정하고 이 단계들을 중단한다.
-
windowData["
frameType"]을 browsingContext로 프레임 유형 가져오기를 실행한 결과로 설정한다. -
windowData["
visibilityState"]를 browsingContext의 활성 문서의visibilityState속성 값으로 설정한다. -
windowData["
focusState"]를 browsingContext의 활성 문서를 인수로 하여 포커스 여부 단계를 실행한 결과로 설정한다. -
client가 윈도 클라이언트이면, windowData["
ancestorOriginsList"]를 browsingContext의 활성 문서의 조상 출처 목록에 연결된 목록으로 설정한다.
-
-
task의 실행이 완료될 때까지 기다린다.
참고: 이 대기는 차단 대기이지만, 상태가 손상되지 않는 한 구현자는 반복을 병렬로 실행할 수 있다.
-
isClientEnumerable이 true이면:
-
windowData를 matchedWindowData에 추가한다.
-
-
-
그렇지 않고 options["
type"]이"worker"또는"all"이고 client가 전용 워커 클라이언트이거나, options["type"]이"sharedworker"또는"all"이고 client가 공유 워커 클라이언트이면:-
client를 matchedClients에 추가한다.
-
-
-
task를 큐에 넣어 다음 단계를 promise의 relevant settings object의 responsible event loop에서 DOM manipulation task source를 사용하여 실행한다:
-
clientObjects를 새 목록으로 둔다.
-
matchedWindowData에 있는 각 windowData에 대해 반복한다.
-
windowClient를 windowData["
client"], windowData["frameType"], windowData["visibilityState"], windowData["focusState"] 및 windowData["ancestorOriginsList"]를 인수로 하여 윈도 클라이언트 생성 알고리즘을 실행한 결과로 둔다. -
windowClient를 clientObjects에 추가한다.
-
-
matchedClients에 있는 각 client에 대해 반복한다.
-
clientObjects를 다음과 같이 정렬한다.
-
브라우징 컨텍스트가 포커스된 적이 있는
WindowClient객체를 먼저 배치하고, 가장 최근에 포커스된 순서로 정렬한다. -
브라우징 컨텍스트가 한 번도 포커스되지 않은
WindowClient객체를 그다음에 배치하고, 해당 서비스 워커 클라이언트의 생성 순서로 정렬한다. -
연결된 서비스 워커 클라이언트가 워커 클라이언트인
Client객체를 그다음에 배치하고, 해당 서비스 워커 클라이언트의 생성 순서로 정렬한다.
-
-
-
-
promise를 반환한다.
4.3.3.
openWindow(url)
openWindow(url) 메서드 단계는 다음과 같다:
-
url을 파싱한 결과로 둔다. 이때 this의 관련 설정 객체의 API 기본 URL을 사용하여 url을 파싱한다.
-
url이 실패이면,
TypeError로 거부된 프로미스를 반환한다. -
url이
about:blank이면,TypeError로 거부된 프로미스를 반환한다. -
이 출처의 어떠한
Window도 일시적 활성화를 갖고 있지 않으면, "InvalidAccessError"DOMException으로 거부된 프로미스를 반환한다. -
promise를 새 프로미스로 둔다.
-
다음 하위 단계를 병렬로 실행한다:
-
newContext를 새 최상위 브라우징 컨텍스트로 둔다.
-
newContext의
Window객체의 환경 설정 객체의 담당 이벤트 루프에서 사용자 상호작용 태스크 소스를 사용하여 다음 단계를 실행하도록 태스크를 큐에 추가한다:-
HandleNavigate: newContext를 url로 내비게이트하며, exceptionsEnabled는 true로 하고, historyHandling은 "
replace"로 한다. -
HandleNavigate라는 레이블이 지정된 단계에서 호출된 알고리즘 단계가 예외를 던지면, serviceWorkerEventLoop에서 DOM 조작 태스크 소스를 사용하여 promise를 그 예외로 거부하도록 태스크를 큐에 추가하고, 이 단계들을 중단한다.
-
frameType을 newContext를 사용하여 프레임 유형 가져오기를 실행한 결과로 둔다.
-
visibilityState를 newContext의 활성 문서의
visibilityState속성 값으로 둔다. -
focusState를 newContext의 활성 문서를 인수로 사용하여 포커스 보유 단계를 실행한 결과로 둔다.
-
ancestorOriginsList를 newContext의 활성 문서의 상위 출처 목록에 연결된 목록으로 둔다.
-
serviceWorkerEventLoop에서 DOM 조작 태스크 소스를 사용하여 다음 단계를 실행하도록 태스크를 큐에 추가한다:
-
newContext의
Window객체의 환경 설정 객체가 주어졌을 때 저장소 키를 얻기를 실행한 결과가 서비스 워커의 포함하는 서비스 워커 등록의 저장소 키와 같지 않으면, promise를 null로 이행하고 이 단계들을 중단한다. -
client를 newContext의
Window객체의 환경 설정 객체, frameType, visibilityState, focusState, ancestorOriginsList를 인수로 사용하여 윈도우 클라이언트 생성을 실행한 결과로 둔다. -
promise를 client로 이행한다.
-
-
-
-
promise를 반환한다.
4.3.4.
claim()
claim() 메서드 단계는 다음과 같다:
-
서비스 워커가 활성 워커가 아니면, "
InvalidStateError"DOMException으로 거부된 프로미스를 반환한다. -
promise를 새로운 프로미스로 둔다.
-
다음 하위 단계를 병렬로 실행한다.
-
client가 주어졌을 때 스토리지 키를 얻기를 실행한 결과가 서비스 워커의 포함 서비스 워커 등록의 스토리지 키와 같은 각 서비스 워커 클라이언트 client에 대해:
-
client의 실행 준비 플래그가 설정되지 않았거나 client의 폐기 플래그가 설정되어 있으면, 계속한다.
-
storage key를 client가 주어졌을 때 스토리지 키를 얻기를 실행한 결과로 둔다.
-
registration을 storage key와 client의 생성 URL이 주어졌을 때 서비스 워커 등록 일치시키기를 실행한 결과로 둔다.
-
registration이 서비스 워커의 포함 서비스 워커 등록이 아니면, 계속한다.
참고: 서비스 워커의 포함 서비스 워커 등록이 등록 해제됨 상태이면 registration은 null이다.
-
client의 활성 서비스 워커가 서비스 워커가 아니면:
-
client를 인수로 하여 서비스 워커 클라이언트 언로드 처리를 호출한다.
-
client를 인수로 하여 컨트롤러 변경 알림 알고리즘을 호출한다.
-
-
-
task를 큐에 넣어 promise의 relevant settings object의 responsible event loop에서 DOM manipulation task source를 사용하여 promise를 undefined로 resolve한다.
-
-
promise를 반환한다.
4.4.
ExtendableEvent
[Exposed =ServiceWorker ]interface :ExtendableEvent Event {(constructor DOMString ,type optional ExtendableEventInit = {});eventInitDict undefined waitUntil (Promise <any >); };f
dictionary :ExtendableEventInit EventInit { // Defined for the forward compatibility across the derived events };
ExtendableEvent
객체는 수명 연장 프라미스(프라미스
배열)을 가지고 있다. 최초에는 빈 배열이다.
ExtendableEvent
객체는 대기 중 프라미스 수(수명 연장 프라미스 중 대기 중인 프라미스의 수)을 가지고 있다.
최초에는 0으로 설정된다.
ExtendableEvent
객체는 타임아웃 플래그를 가진다. 최초에는 설정되지 않으며, 대기 중 프라미스 수가 0보다 크면 사용자 에이전트가 부여한 선택적 지연
후에 설정된다.
ExtendableEvent
객체는 활성 상태라고 하는데, 이는 타임아웃 플래그가
설정되지 않았고, 대기 중 프라미스 수가 0보다 크거나 dispatch 플래그가 설정된 경우이다.
서비스 워커는 두 개의
라이프사이클
이벤트(install
및 activate)를
갖는다.
서비스 워커는
ExtendableEvent
인터페이스를 activate
및 install
이벤트에 사용한다.
서비스 워커 확장에서 이벤트 핸들러를
정의하는 경우에는 ExtendableEvent
인터페이스를 사용할 수도 있고, 확장할 수도 있다.
4.4.1.
event.waitUntil(f)
참고: waitUntil()
메서드는 이벤트의 수명을 연장한다.
waitUntil(f)
메서드 단계는 수명 연장 프라미스 추가 f를 this에 추가하는 것이다.
ExtendableEvent)에
추가하려면 다음 단계들을 실행한다:
-
event의
isTrusted속성이 false이면, "InvalidStateError"DOMException을 throw한다. -
event가 활성 상태가 아니면, "
InvalidStateError"DOMException을 throw한다.참고: 이벤트 핸들러를 호출한 태스크에서 수명 연장 프라미스가 추가되지 않았다면, 이후 비동기 태스크에서
waitUntil()을 호출하면 예외가 발생한다. -
promise를 event의 수명 연장 프라미스에 추가한다.
-
event의 대기 중 프라미스 수를 1 증가시킨다.
참고: 주어진 프라미스가 이미 settle된 경우에도 대기 중 프라미스 수는 증가한다. 해당 카운트 감소는 프라미스 반응의 미크로태스크에서 처리된다.
-
promise가 이행 또는 거부될 때, 미크로태스크를 큐에 추가하여 다음 하위 단계들을 실행한다:
-
event의 대기 중 프라미스 수를 1 감소시킨다.
-
event의 대기 중 프라미스 수가 0이면:
-
registration이 등록 해제됨이면, Try Clear Registration을 registration을 인수로 실행한다.
-
registration이 null이 아니면, Try Activate를 registration을 인수로 실행한다.
-
사용자 에이전트는 서비스 워커에 대기 중 이벤트 없음이 서비스 워커에 대해 false를 반환하면 해당 서비스 워커를 종료하지 않아야 한다.
서비스 워커와 확장 기능이 이벤트 핸들러를 정의하는 경우, 자체 동작을 정의할 수 있으며, extend lifetime promises로 연산의 지속 시간을 제안하거나, 프라미스(promise)의 거부 상태를 통해 extend lifetime promises에서 연산 실패를 알릴 수 있습니다.
참고: 서비스 워커는 설치 중인 워커를
"installed" 상태로 간주하는 것을,
install
이벤트의 extend lifetime promises에 속한 모든 프라미스가 성공적으로 resolve될 때까지 지연합니다. (관련 설치 알고리즘 단계 참고.) 만약 어떤 프라미스라도 reject된다면, 설치는 실패합니다. 이는 주로 서비스 워커가
의존하는 필수 캐시가 모두 채워지기 전까지 "installed"로 간주되지 않도록 하기 위함입니다. 마찬가지로, 서비스 워커는 active worker를
"activated" 상태로 간주하는 것을, activate
이벤트의 extend lifetime promises에 속한 모든 프라미스가 settle될 때까지 지연합니다. (관련 activate 알고리즘 단계 참고.) 이는 기능성 이벤트가 해당 서비스 워커에
디스패치되기 전에 데이터베이스 스키마가 업그레이드되고, 오래된 캐시 항목이 삭제될 수 있도록 보장하기 위한 것입니다.
4.5.
InstallEvent
[Exposed =ServiceWorker ]interface :InstallEvent ExtendableEvent {(constructor DOMString ,type optional ExtendableEventInit = {});eventInitDict Promise <undefined >addRoutes ((RouterRule or sequence <RouterRule >)); };rules dictionary {RouterRule required RouterCondition ;condition required RouterSource ; };source dictionary {RouterCondition URLPatternCompatible ;urlPattern ByteString ;requestMethod RequestMode ;requestMode RequestDestination ;requestDestination RunningStatus ;runningStatus sequence <RouterCondition >;_or RouterCondition ; };not typedef (RouterSourceDict or RouterSourceEnum );RouterSource dictionary {RouterSourceDict DOMString ; };cacheName enum {RunningStatus ,"running" };"not-running" enum {RouterSourceEnum ,"cache" ,"fetch-event" ,"network" };"race-network-and-fetch-handler"
라우터 조건 결과 카운트는 구조체이며 다음으로 구성된다:
-
조건 카운트(숫자).
-
쿼터 초과(불리언).
4.5.1. event.addRoutes(rules)
참고: addRoutes(rules)
메서드는 이 서비스 워커를 위해 fetch 이벤트 핸들러가 일반적으로 하는 단순 작업을 오프로드할 규칙을 등록한다.
addRoutes(rules)
메서드 단계는 다음과 같다:
-
rules가
RouterRule딕셔너리이면, rules를 « rules »로 설정한다. -
serviceWorker를 current global object의 연관된 service worker로 둔다.
-
rules의 각 rule에 대해:
-
Verify Router Condition 알고리즘을 rule["
condition"] 및 serviceWorker와 함께 실행한 결과가 false를 반환하면, a promise rejected with aTypeError를 반환한다. -
rule["
source"]가 "fetch-event" 또는 "race-network-and-fetch-handler" 중 하나이고, serviceWorker의 set of event types to handle에fetch가 포함되어 있지 않으면, a promise rejected with aTypeError를 반환한다.
-
-
lifetimePromise를 새로운 promise로 둔다.
-
Add lifetime promise lifetimePromise를 this에 추가한다.
Note:
event.addRoutes(rules)는 기본적으로event.waitUntil(promise)가 호출된 것처럼 이벤트의 수명을 연장한다. -
promise를 새로운 promise로 둔다.
-
promise가 이행되거나 거부되면, lifetimePromise를 undefined로 resolve한다.
Note: 이 단계는 install 이벤트 실패를 피하기 위해 lifetimePromise가 항상 이행되도록 하기 위한 것이다.
-
serviceWorkerEventLoop를 current global object의 event loop로 둔다.
-
다음 단계를 Enqueue하여 [[service worker queue]]에 넣는다:
-
allRules를 serviceWorker의 list of router rules의 복사본으로 둔다.
-
rules의 각 rule에 대해:
-
rule을 allRules에 추가한다.
-
-
Check Router Registration Limit을 allRules와 함께 실행한 결과가 false이면, 다음을 수행한다:
-
task를 큐에 넣어 다음 단계를 serviceWorkerEventLoop에서 DOM manipulation task source를 사용해 실행한다:
-
promise를
TypeError로 reject한다.
-
-
이 단계들을 중단한다.
-
-
serviceWorker의 list of router rules를 allRules로 설정한다.
-
task를 큐에 넣어 다음 단계를 serviceWorkerEventLoop에서 DOM manipulation task source를 사용해 실행한다:
-
promise를 undefined로 resolve한다.
-
-
-
promise를 반환한다.
4.6.
FetchEvent
[Exposed =ServiceWorker ]interface :FetchEvent ExtendableEvent {(constructor DOMString ,type FetchEventInit ); [eventInitDict SameObject ]readonly attribute Request request ;readonly attribute Promise <any >preloadResponse ;readonly attribute DOMString clientId ;readonly attribute DOMString resultingClientId ;readonly attribute DOMString replacesClientId ;readonly attribute Promise <undefined >handled ;undefined respondWith (Promise <Response >); };r
dictionary :FetchEventInit ExtendableEventInit {required Request ;request Promise <any >;preloadResponse DOMString = "";clientId DOMString = "";resultingClientId DOMString = "";replacesClientId Promise <undefined >; };handled
서비스 워커는 필수
기능성
이벤트 fetch를
가진다.
fetch
이벤트에 대해, 서비스
워커는 FetchEvent
인터페이스를 사용하며, 이 인터페이스는 ExtendableEvent
인터페이스를 확장한다.
FetchEvent
인터페이스를 사용하는 각 이벤트는 잠재적 응답(response)을 갖고, 초깃값은 null이며 다음의 플래그들도 갖는다(초기값은 모두 unset):
-
응답 대기 플래그
-
respondWith 진입 플래그
-
respondWith 오류 플래그
4.6.1.
event.request
request 속성은 반드시 초기화된 값을 반환해야 한다.
4.6.2. event.preloadResponse
preloadResponse 속성은 반드시 초기화된 값을 반환해야
한다.
이벤트가 생성될 때 해당 속성은 반드시 undefined로 resolve된 promise로 초기화되어야 한다.
4.6.3.
event.clientId
clientId 속성은 반드시 초기화된 값을 반환해야 한다.
이벤트가 생성될 때 해당 속성은 반드시 빈 문자열로 초기화되어야 한다.
참고: clientId는
요청에 이를 시작한 서비스 워커
클라이언트가 있는 경우 request의 클라이언트의 ID이며, 그 밖의 경우에는 빈 문자열이다(예: 시작자가 없는 최상위 탐색 요청). 탐색
요청의 결과 문서와 연결된 환경은 resultingClientId를
참조한다.
4.6.4. event.resultingClientId
resultingClientId 속성은 반드시 초기화된 값을
반환해야 한다.
이벤트가 생성될 때 해당 속성은 반드시 빈 문자열로 초기화되어야 한다.
참고: resultingClientId는
request의 예약된 클라이언트의 ID이다. 하위 리소스 요청, 대상이 "report"인
요청, 그리고 request의 예약된 클라이언트가 null인 경우에는 빈 문자열이다.
4.6.5. event.replacesClientId
replacesClientId 속성은 반드시 초기화된 값을
반환해야 한다.
이벤트가 생성될 때 해당 속성은 반드시 빈 문자열로 초기화되어야 한다.
4.6.6.
event.handled
handled 속성은 반드시 초기화된 값을 반환해야 한다.
이벤트가 생성될 때 해당 속성은 반드시 pending 상태의 promise로 초기화되어야 한다.
4.6.7. event.respondWith(r)
참고: 개발자는 r 인수에 promise나 Response
객체를 직접 넣을 수 있다(Response 객체는 자동으로 promise로 캐스팅됨). 그렇지 않으면 네트워크 에러가 Fetch로
반환된다.
렌더러 측 보안 검사는 cross-origin 콘텐츠의 tainting과 관련이 있으며 filtered responses 타입에 따라 결정된다(Fetch 참고).
respondWith(r) 메서드 단계는 다음과 같다:
-
event를 this로 한다.
-
event의 dispatch 플래그가 unset이면, "
InvalidStateError"DOMException을 throw한다. -
event의 respondWith 진입 플래그가 설정되어 있으면, "
InvalidStateError"DOMException을 throw한다. -
수명 연장 프라미스 추가 r를 event에 추가한다.
참고:
event.respondWith(r)호출은event.waitUntil(r)과 같이 이벤트의 수명을 기본적으로 연장한다. -
event의 stop propagation 플래그와 stop immediate propagation 플래그를 설정한다.
-
event의 respondWith 진입 플래그를 설정한다.
-
event의 응답 대기 플래그를 설정한다.
-
targetRealm을 event의 relevant Realm으로 한다.
-
-
event의 respondWith 오류 플래그를 설정한다.
-
event의 응답 대기 플래그를 unset한다.
-
-
r가 이행될 때 response로:
-
response가
Response객체가 아니면 respondWith 오류 플래그를 설정한다.참고: respondWith 오류 플래그가 설정되면, 네트워크 에러가 Fetch로 Handle Fetch 알고리즘을 통해 반환된다(21.1단계 참고). 그렇지 않으면 response 값이 Fetch로 Handle Fetch 알고리즘을 통해 반환된다(22.1단계 참고).
-
그 외에는:
-
bytes를 빈 바이트 시퀀스로 한다.
-
end-of-body를 false로 한다.
-
done을 false로 한다.
-
potentialResponse를 response의 연관 response의 복사본으로 하되, body는 제외한다.
-
response의 body가 null이 아니면, 다음 하위 단계를 실행한다:
-
pullAlgorithm을 다음 단계들을 실행하는 액션으로 한다:
-
readRequest를 새로운 read request로 하고, 다음 항목을 포함한다:
- chunk 단계, chunk가 주어졌을 때
-
-
단언: chunk는
Uint8Array이다. -
chunk가 나타내는 바이트를 bytes에 추가한다.
-
potentialResponse의 body info의 encoded size를 bytes의 byte length만큼 증가시킨다.
-
potentialResponse의 body info의 decoded size를 bytes의 byte length만큼 증가시킨다.
-
! DetachArrayBuffer(chunk.[[ViewedArrayBuffer]])를 수행한다.
-
- close 단계
-
-
end-of-body를 true로 한다.
-
- error 단계
-
reader에서 chunk 읽기를 readRequest로 실행한다.
-
-
cancelAlgorithm을 reader cancel을 실행하는 액션으로 한다.
-
highWaterMark를 사용자 에이전트가 선택한 0 이상의 NaN이 아닌 값으로 한다.
-
sizeAlgorithm을 chunk 객체를 받아서 0 이상의 NaN/무한대가 아닌 값을 반환하는 알고리즘으로 한다(사용자 에이전트가 선택).
-
newStream을
ReadableStream의 새 인스턴스로 만들고, set up에 pullAlgorithm pullAlgorithm, cancelAlgorithm cancelAlgorithm, highWaterMark highWaterMark, sizeAlgorithm sizeAlgorithm을 targetRealm에서 실행한다. -
potentialResponse의 body를, body의 새 인스턴스로 하고 그 stream을 newStream으로 한다.
-
done이 false인 동안 반복적으로 다음 하위 단계를 병렬로 실행한다:
-
newStream이 errored면 done을 true로 한다.
-
그 외에 bytes가 비어 있고 end-of-body가 true면, newStream 닫기를 하고 done을 true로 한다.
-
그 외에 bytes가 비어 있지 않으면 다음 하위 단계를 실행한다:
-
chunk를 bytes 처음부터의 부분 시퀀스로 한다.
-
chunk를 bytes에서 제거한다.
-
buffer를
ArrayBuffer의 새 인스턴스로 만들고, targetRealm에서 chunk를 담는다. -
newStream에 enqueue한다.
Uint8Array로 targetRealm에서 buffer를 감싼다.
-
-
참고: 이 단계들은 response의 body의 stream을 potentialResponse에 "파이프"하는 것과 동등한 observable 결과를 만든다.
참고: 서비스 워커가 chunk 단위로 쓴 데이터는 클라이언트가 동일 chunk 단위로 읽는다고 보장되지 않는다. 즉, 클라이언트는 동일 데이터를 읽지만 chunk 분할은 브라우저에 따라 다를 수 있다.
-
event의 잠재적 응답을 potentialResponse로 한다.
-
-
event의 응답 대기 플래그를 unset한다.
-
4.7. ExtendableMessageEvent
[Exposed =ServiceWorker ]interface :ExtendableMessageEvent ExtendableEvent {(constructor DOMString ,type optional ExtendableMessageEventInit = {});eventInitDict readonly attribute any data ;readonly attribute USVString origin ;readonly attribute DOMString lastEventId ; [SameObject ]readonly attribute (Client or ServiceWorker or MessagePort )?source ;readonly attribute FrozenArray <MessagePort >ports ; };
dictionary :ExtendableMessageEventInit ExtendableEventInit {any =data null ;USVString = "";origin DOMString = ""; (lastEventId Client or ServiceWorker or MessagePort )?=source null ;sequence <MessagePort >= []; };ports
각 ExtendableMessageEvent는
origin (원본(origin), 문자열 또는 null)을 가지며,
처음에는 null로 설정됩니다.
서비스 워커는
이벤트의 생명주기를 확장하기 위해 extendable
message
이벤트를 정의합니다. message
이벤트에 대해서는, 서비스
워커가
ExtendableMessageEvent
인터페이스를 사용하며, 이 인터페이스는
ExtendableEvent
인터페이스를 상속합니다.
4.7.1. event.data
data 속성은 초기화된 값을
반환해야 합니다. 객체가 생성될 때 이 속성은 null로 초기화되어야 합니다. 이 속성은 전송되는 메시지를 나타냅니다.
4.7.2. event.origin
origin 속성은 메시지를 보낸 서비스 워커
클라이언트의 출처를 나타낸다.
origin
getter 단계는 다음과 같습니다:
-
this의 origin이 origin이라면, origin의 직렬화 문자열을 반환합니다.
origin
속성이 “초기화”될 때
(예: ExtendableMessageEvent
컨스트럭터 내),
초기화 값이 객체의 origin에 저장됩니다.
4.7.3. event.lastEventId
lastEventId 속성은
초기화된 값을 반환해야 합니다. 객체가 생성될 때, 이 속성은
빈 문자열로 초기화되어야 합니다.
ExtendableMessageEvent
인터페이스를 구현하는 객체의 origin 추출 단계는
this의 origin이 origin일 경우 반환하고, 아니면 null 반환합니다.
4.7.4. event.source
source 속성은 초기화된 값을
반환해야 합니다. 객체가 생성될 때 이 속성은 null로 초기화되어야 합니다. 이 속성은 메시지를 보낸 Client
객체를 나타냅니다.
4.7.5. event.ports
ports 속성은 초기화된 값을
반환해야 합니다. 객체가 생성될 때 이 속성은 빈 배열로 초기화되어야 합니다. 이 속성은 전송되는 MessagePort
배열을 나타냅니다.
4.8. 이벤트
다음 이벤트들은 서비스 워커 이벤트라고 하며, ServiceWorkerGlobalScope
객체에서 발생합니다:
| 이벤트 이름 | 인터페이스 | 범주 | 디스패치되는 시점… |
|---|---|---|---|
install
| InstallEvent
| 수명 주기 | 서비스 워커의 포함 서비스 워커 등록의 설치 중인 워커가 변경될 때. (설치 알고리즘의 11.2단계를 참조한다.) |
activate
| ExtendableEvent
| 수명 주기 | 서비스 워커의 포함 서비스 워커 등록의 활성 워커가 변경될 때. (활성화 알고리즘의 12.2단계를 참조한다.) |
fetch
| FetchEvent
| 기능 | HTTP 가져오기가 request로 가져오기
처리를 호출할 때. 가져오기 처리를 수행한 결과, 서비스 워커는 HTTP 가져오기에 응답을 반환한다. Response
객체로 나타내는 응답은 Cache
객체에서 가져오거나 self.fetch(input, init)
메서드를 사용하여 네트워크에서 직접 가져올 수 있다. (사용자 정의 Response
객체를 사용하는 것도 한 가지 방법이다.)
|
| push | PushEvent
| 기능 | (푸시 이벤트 발동을 참조한다.) |
| notificationclick | NotificationEvent
| 기능 | (알림 활성화를 참조한다.) |
| notificationclose | NotificationEvent
| 기능 | (알림 닫기를 참조한다.) |
| sync | SyncEvent
| 기능 | (동기화 이벤트 발동을 참조한다.) |
| canmakepayment | CanMakePaymentEvent | 기능 | (CanMakePaymentEvent 처리를 참조한다.) |
| paymentrequest | PaymentRequestEvent | 기능 | (PaymentRequestEvent 처리를 참조한다.) |
message
| ExtendableMessageEvent
| 레거시 | 메시지를 수신할 때. |
messageerror
| ExtendableMessageEvent
| 레거시 | 역직렬화할 수 없는 메시지가 전송되었을 때. |
5. 캐시
저자들이 오프라인 사용을 위해 콘텐츠 캐시를 완전히 관리할 수 있도록, Window
및 WorkerGlobalScope
는 비동기 캐싱 메서드를 제공하여 Cache 객체를 열고 조작할 수
있게 합니다. 하나의
origin은 여러 개의 이름이 있는 Cache 객체를 가질 수 있으며,
그 내용은 스크립트가 완전히 제어합니다. 캐시는 origin 간에 공유되지 않고, 브라우저의 HTTP 캐시와 완전히 분리되어 있습니다.
5.1. 구성요소
요청 응답 리스트는 요청(요청)과 응답(응답)으로 구성된 튜플의 리스트이다.
관련 요청 응답 리스트는 this가 나타내는 인스턴스이다.
이름에서 캐시로의 맵은 키(요청 응답 리스트의 이름을 나타내는 문자열)와 값(요청 응답 리스트)으로 구성된 항목을 갖는 정렬된 맵이다.
CacheStorage
객체의 관련
이름에서 캐시로의 맵은 객체의 관련 설정 객체와 "caches"를 사용하여 로컬 스토리지 보틀 맵을 얻는 알고리즘을 실행한
결과와 연결된 이름에서 캐시로의 맵이다.
5.2. 캐시의 수명 이해하기
Cache
인스턴스는 브라우저의 HTTP 캐시의 일부가 아닙니다. Cache 객체는
저자가 직접 관리해야 하는 대상입니다. Cache 객체는 저자가
명시적으로 요청하지 않는 한 업데이트되지 않습니다. Cache 객체는 저자가
항목을 삭제하지 않는 한 만료되지 않습니다. Cache 객체는 서비스 워커
스크립트가 업데이트되어도 사라지지 않습니다. 즉, 캐시는 자동으로 업데이트되지 않으며, 수동으로 관리해야 합니다. 따라서 저자들은 캐시 이름에 버전을 부여하고, 해당 서비스 워커
버전에서만 캐시를 사용해야 합니다.
5.3. self.caches
partial interface mixin WindowOrWorkerGlobalScope { [SecureContext ,SameObject ]readonly attribute CacheStorage caches ; };
5.3.1.
caches
caches
getter 단계는 this의 연관된 CacheStorage
객체를 반환하는 것입니다.
5.4. Cache
[SecureContext ,Exposed =(Window ,Worker )]interface { [Cache NewObject ]Promise <(Response or undefined )>match (RequestInfo ,request optional CacheQueryOptions = {}); [options NewObject ]Promise <FrozenArray <Response >>matchAll (optional RequestInfo ,request optional CacheQueryOptions = {}); [options NewObject ]Promise <undefined >add (RequestInfo ); [request NewObject ]Promise <undefined >addAll (sequence <RequestInfo >); [requests NewObject ]Promise <undefined >put (RequestInfo ,request Response ); [response NewObject ]Promise <boolean >delete (RequestInfo ,request optional CacheQueryOptions = {}); [options NewObject ]Promise <FrozenArray <Request >>keys (optional RequestInfo ,request optional CacheQueryOptions = {}); };options
dictionary {CacheQueryOptions boolean =ignoreSearch false ;boolean =ignoreMethod false ;boolean =ignoreVary false ; };
Cache 객체는 request response list를 나타냅니다. 문서와 워커에서 Cache
인터페이스를 구현하는 여러 개의 별도 객체가 동시에 동일한 request response list에 연결될 수 있습니다.
cache batch operation은 struct로 구성되며 다음을 포함합니다:
-
type ("
delete" 또는 "put") -
request (request)
-
response (response)
-
options (
CacheQueryOptions)
5.4.1.
match(request, options)
match(request, options) 메서드
단계는 다음과 같습니다:
-
promise를 새로운 promise로 둡니다.
-
다음 하위 단계를 병렬로 실행합니다:
-
p를
matchAll(request, options)메서드에 request와 options를 전달하여 실행한 결과로 둡니다. -
p가 완료될 때까지 대기합니다.
-
p가 예외와 함께 reject되면,
-
promise를 해당 예외로 reject합니다.
-
-
그렇지 않고 p가 배열 responses로 resolve되면,
-
responses가 빈 배열이면,
-
promise를 undefined로 resolve합니다.
-
-
그 외의 경우:
-
promise를 responses의 첫 번째 요소로 resolve합니다.
-
-
-
-
promise를 반환합니다.
5.4.2.
matchAll(request, options)
matchAll(request, options)
메서드 단계는 다음과 같습니다:
-
r을 null로 둔다.
-
선택적 인수 request가 생략되지 않았으면:
-
promise를 새 프로미스로 둔다.
-
다음 하위 단계를 병렬로 실행한다.
-
responses를 빈 목록으로 둔다.
-
선택적 인수 request가 생략되었으면:
-
각 관련 요청 응답 목록의 requestResponse에 대해:
-
requestResponse의 응답 복사본을 responses에 추가한다.
-
-
-
그렇지 않으면:
-
responses의 각 response에 대해:
-
response의 type이 "
opaque"이고 promise의 relevant settings object의 origin, promise의 relevant settings object, "", 그리고 response의 internal response로 cross-origin resource policy check를 수행한 결과가 blocked를 반환하면, promise를TypeError로 reject하고 이 단계들을 중단한다.
-
-
task를 큐에 넣어, promise의 relevant settings object의 responsible event loop에서 DOM manipulation task source를 사용해 다음 단계를 수행한다:
-
responseList를 list로 둔다.
-
responses의 각 response에 대해:
-
realm에서 responseList로부터 생성된 frozen array로 promise를 resolve한다.
-
-
-
promise를 반환한다.
5.4.3.
add(request)
add(request) 메서드 단계는 다음과 같습니다:
-
requests를 request만을 포함하는 배열로 둡니다.
-
responseArrayPromise를
addAll(requests)알고리즘에 requests를 인자로 전달하여 실행한 결과로 둡니다. -
responseArrayPromise가 fulfill될 때 undefined를 반환하는 fulfillment handler와 함께 reacting한 결과를 반환합니다.
5.4.4.
addAll(requests)
addAll(requests) 메서드 단계는 다음과 같습니다:
-
responsePromises를 빈 리스트로 둔다.
-
requestList를 빈 리스트로 둔다.
-
requests에서 유형이
Request인 각 request에 대해: -
requests의 각 request에 대해:
-
r을 request를 인수로 사용하여
Request의 초기 값을 생성자로 호출한 결과와 연결된 요청으로 둔다. 이것이 예외를 던지면, 해당 예외로 거부된 프로미스를 반환한다. -
r의 클라이언트의 전역 객체가
ServiceWorkerGlobalScope객체이면, request의 서비스 워커 모드를 "none"으로 설정한다. -
r을 requestList에 추가한다.
-
responsePromise를 새 프로미스로 둔다.
-
다음 하위 단계를 병렬로 실행한다.
-
response에 대한 processResponse로서 다음 하위 단계를 실행한다.
-
response에 대한 processResponseEndOfBody로서 다음 하위 단계를 실행한다.
-
response의 중단됨 플래그가 설정되어 있으면, responsePromise를 "
AbortError"DOMException으로 거부하고 이 단계를 중단한다. -
responsePromise를 response로 이행한다.
참고: 응답의 본문이 완전히 수신되면 캐시 커밋이 허용된다.
-
-
responsePromise를 responsePromises에 추가한다.
-
-
p를 responsePromises의 모든 항목을 기다리는 프로미스를 얻은 결과로 둔다.
-
p에 반응한 결과를 반환한다. 이때 이행 핸들러는 인수 responses로 호출되면 다음 하위 단계를 수행한다.
-
operations를 빈 목록으로 둔다.
-
index를 0으로 둔다.
-
responses의 각 response에 대해:
-
cacheJobPromise를 새 프로미스로 둔다.
-
다음 하위 단계를 병렬로 실행한다.
-
errorData를 null로 둔다.
-
Batch Cache Operations를 operations와 함께 호출한다. 이 과정에서 예외를 던지면, errorData를 해당 예외로 설정한다.
-
task를 큐에 넣어, cacheJobPromise의 relevant settings object의 responsible event loop에서 DOM manipulation task source를 사용하여 다음 하위 단계를 수행한다:
-
-
cacheJobPromise를 반환한다.
-
5.4.5.
put(request, response)
put(request, response) 메서드 단계는
다음과 같습니다:
-
innerRequest를 null로 둔다.
-
만약 request가
Request객체라면, innerRequest를 request의 request로 설정한다. -
그렇지 않으면:
-
requestObj를
Request의 생성자에 request를 인자로 넘겨 호출한 결과로 둔다. 만약 이것이 예외(exception)를 발생시키면, 해당 예외와 함께 거부된 프라미스를 반환한다. -
innerRequest를 requestObj의 request로 설정한다.
-
-
만약 innerRequest의 url의 scheme이 "
http"와 "https" 중 하나가 아니거나, innerRequest의 method가 `GET`이 아니라면, TypeError와 함께 거부된 프라미스를 반환한다. -
innerResponse를 response의 response로 둔다.
-
만약 innerResponse의 status가
206이라면, TypeError와 함께 거부된 프라미스를 반환한다. -
만약 innerResponse의 header list에 header 이름이 `
Vary`인 항목이 있다면:-
fieldValues를 리스트(list)로, 해당 아이템이 Vary 헤더의 필드 값(field-values)을 포함하도록 한다.
-
각 fieldValue에 대하여 fieldValues에서:
-
만약 fieldValue가 "
*"와 일치한다면, TypeError와 함께 거부된 프라미스를 반환한다.
-
-
-
만약 innerResponse의 body가 disturbed 상태이거나, locked 상태라면, TypeError와 함께 거부된 프라미스를 반환한다.
-
clonedResponse를 innerResponse의 복제(clone)로 둔다.
-
bodyReadPromise를 undefined로 resolve된 프라미스로 한다.
-
만약 innerResponse의 body가 null이 아니라면, 다음 하위 단계를 실행한다:
-
reader를 stream에 대해 reader 얻기의 결과로 한다.
-
bodyReadPromise를 reader로부터 모든 바이트를 읽는 결과로 설정한다.
참고: 이는 innerResponse의 body가 locked 상태가 되며, clonedResponse에 버퍼링된 전체 본문 복사본이 존재함을 보장한다. 구현에서는 메모리 대신 디스크 스트리밍 최적화가 가능하다.
-
operations를 빈 리스트로 둔다.
-
operation을 캐시 배치 작업(cache batch operation)으로 둔다.
-
operation의 type을 "
put"으로 설정한다. -
operation의 request를 innerRequest로 설정한다.
-
operation의 response를 clonedResponse로 설정한다.
-
bodyReadPromise의 이행(fulfillment) 결과를 반환한다:
-
cacheJobPromise를 새로운 프라미스로 둔다.
-
cacheJobPromise를 반환하고, 다음 단계를 병렬로 실행:
-
errorData를 null로 둔다.
-
operations를 사용하여 캐시 작업 일괄 처리를 호출한다. 이 호출이 예외를 던지면, errorData를 해당 예외로 설정한다.
-
cacheJobPromise의 관련 설정 객체의 담당 이벤트 루프에서 DOM 조작 태스크 소스를 사용하여, 다음 하위 단계를 수행하도록 태스크를 큐에 넣는다:
-
-
5.4.6.
delete(request, options)
delete(request, options)
메서드 단계는 다음과 같습니다:
-
r을 null로 둡니다.
-
request가
Request객체라면:-
r에 request의 request를 설정합니다.
-
r의 method가 `
GET`이 아니고 options.ignoreMethod가 false인 경우, false로 resolve된 promise를 반환합니다.
-
-
그 외에 request가 문자열이라면:
-
r을
Request생성자에 request를 인자로 하여 얻은 결과의 관련 request로 설정합니다. 만약 예외가 발생하면 해당 예외로 reject된 promise를 반환합니다.
-
-
operations를 빈 리스트로 둡니다.
-
operation을 캐시 배치 작업(cache batch operation)으로 둡니다.
-
operation의 type을 "
delete"로 설정합니다. -
operation의 request를 r로 설정합니다.
-
operation의 options를 options로 설정합니다.
-
Append를 통해 operation을 operations에 추가합니다.
-
cacheJobPromise를 새로운 promise로 둡니다.
-
다음 하위 단계를 병렬로 실행합니다:
-
errorData를 null로 둔다.
-
requestResponses를 operations로 캐시 작업 일괄 수행을 실행한 결과로 둔다. 이 과정에서 예외를 던지면, errorData를 해당 예외로 설정한다.
-
task를 큐에 넣어, cacheJobPromise의 relevant settings object의 responsible event loop에서 DOM manipulation task source를 사용해 다음 하위 단계를 수행한다:
-
-
cacheJobPromise를 반환합니다.
5.4.7.
keys(request, options)
keys(request, options) 메서드 단계는
다음과 같습니다:
-
r을 null로 둡니다.
-
선택적 인자인 request가 생략되지 않았다면:
-
request가
Request객체라면:-
r을 request의 request로 설정합니다.
-
r의 method가 `
GET`이 아니고 options.ignoreMethod가 false인 경우, 빈 배열로 resolve된 promise를 반환합니다.
-
-
그 외에 request가 문자열이라면:
-
r을
Request생성자에 request를 인자로 하여 얻은 결과의 관련 request로 설정합니다. 만약 예외가 발생하면, 해당 예외로 reject된 promise를 반환합니다.
-
-
-
promise를 새로운 promise로 둡니다.
-
다음 하위 단계를 병렬로 실행합니다:
-
requests를 빈 리스트로 둡니다.
-
선택적 인자인 request가 생략된 경우,
-
각 requestResponse를 relevant request response list에서 반복하여:
-
requestResponse의 request를 requests에 추가합니다.
-
-
-
그 외의 경우:
-
requestResponses를 Query Cache에 r과 options를 전달하여 실행한 결과로 둡니다.
-
각 requestResponse를 requestResponses에서 반복하여:
-
requestResponse의 request를 requests에 추가합니다.
-
-
-
task를 큐에 넣어, promise의 relevant settings object의 responsible event loop에서 DOM manipulation task source를 사용해 다음 단계를 수행한다:
-
-
promise를 반환합니다.
5.5.
CacheStorage
[SecureContext ,Exposed =(Window ,Worker )]interface { [CacheStorage NewObject ]Promise <(Response or undefined )>match (RequestInfo ,request optional MultiCacheQueryOptions = {}); [options NewObject ]Promise <boolean >has (DOMString ); [cacheName NewObject ]Promise <Cache >open (DOMString ); [cacheName NewObject ]Promise <boolean >delete (DOMString ); [cacheName NewObject ]Promise <sequence <DOMString >>keys (); };dictionary :MultiCacheQueryOptions CacheQueryOptions {DOMString ; };cacheName
참고: CacheStorage
인터페이스는 주로 ECMAScript 6 Map 객체와 일치하도록 설계되었으나, 완전히 비동기적이며 추가적인 편의 메서드를
포함합니다. clear, forEach, entries, values 메서드는
TC39의 비동기 반복자 논의가 계속되고 있기 때문에 일부러 첫 번째 버전의 범위에서 제외되었습니다.
사용자 에이전트는 CacheStorage
객체를 Window
객체나 WorkerGlobalScope
객체가 생성될 때 반드시 생성해야 합니다.
CacheStorage
객체는 자신의 name to cache map을 나타내며, 이 맵은 객체의 로컬 스토리지 병 맵 얻기를 관련 설정 객체와 "caches"를 인자로 실행한 결과와 연관됩니다.
여러 문서와 워커에서 CacheStorage
인터페이스를 구현하는 별개의 객체들이 동시에 동일한 name to cache map과 연관될 수 있습니다.
5.5.1.
match(request, options)
match(request, options)
메서드 단계는 다음과 같습니다:
-
만약 options["
cacheName"] 존재한다면,-
새로운 프라미스(promise) promise를 반환하고, 다음 하위 단계를 병렬로 실행한다:
-
각 cacheName → cache에 대해 관련 name to cache 맵에서 순회한다:
-
만약 options["
cacheName"] 이 cacheName에 일치하면,-
promise를
Cache인터페이스의match(request, options)메서드에 request와 options를 인자로 넘기고(cache를\[[Call]]내부 메서드의 thisArgument로 제공) 지정된 알고리즘의 결과로 resolve한다. -
이 단계를 중단한다.
-
-
-
promise를 undefined로 resolve한다.
-
-
-
그렇지 않으면:
-
promise를 undefined로 resolve된 프라미스로 둔다.
-
각 cacheName → cache에 대해 관련 name to cache 맵에서 순회한다:
-
promise를, fulfillment 핸들러가 호출될 때(인자로 response를 받음) 다음 하위 단계를 수행하는 방식으로, 자기 자신에 대해 reacting한 결과로 설정한다:
-
만약 response가 undefined가 아니라면, response를 반환한다.
-
promise를
Cache인터페이스의match(request, options)메서드에 request와 options를 인자로 넘기고(cache를\[[Call]]내부 메서드의 thisArgument로 제공) 지정된 알고리즘의 결과로 반환한다.
-
-
-
promise를 반환한다.
-
5.5.2.
has(cacheName)
has(cacheName) 메서드 단계는 다음과 같습니다:
-
promise를 새로운 프라미스로 둔다.
-
다음 하위 단계를 병렬로 실행한다:
-
각 key → value에 대해 관련 name to cache 맵을 순회한다:
-
cacheName이 key와 일치하면, promise를 true로 resolve하고 이 단계를 중단한다.
-
-
promise를 false로 resolve한다.
-
-
promise를 반환한다.
5.5.3.
open(cacheName)
open(cacheName) 메서드 단계는 다음과 같다:
-
promise를 새로운 프라미스(promise)로 둔다.
-
다음 하위 단계를 병렬로 실행한다:
-
각 key → value에 대하여, 관련 name to cache map에서 순회한다:
-
만약 cacheName이 key와 일치하면:
-
promise를 value를 나타내는 새로운
Cache객체로 resolve한다. -
이 단계를 중단한다.
-
-
-
cache를 새로운 request response list로 둔다.
-
Set 관련 name to cache map[cacheName]을 cache로 설정한다. 이 캐시 쓰기 작업이 할당된 quota 한도를 초과하여 실패한 경우, promise를
QuotaExceededError로 reject하고 이 단계를 중단한다. -
promise를 cache를 나타내는 새로운
Cache객체로 resolve한다.
-
-
promise를 반환한다.
5.5.4.
delete(cacheName)
delete(cacheName)
메서드 단계는 다음과 같다:
-
promise를
has(cacheName)메서드에서 cacheName으로 지정된 알고리즘을 실행한 결과로 둔다. -
promise에 fulfillment 핸들러로 reacting(reacting) 한 결과를 반환한다. 이 핸들러는 cacheExists 인자를 받으면 다음 하위 단계를 수행한다:
-
만약 cacheExists가 false라면:
-
false를 반환한다.
-
-
cacheJobPromise를 새로운 프라미스로 둔다.
-
다음 하위 단계를 병렬로 실행한다:
-
Remove 관련 name to cache map[cacheName].
-
cacheJobPromise를 true로 resolve한다.
참고: 이 단계가 끝난 후, 기존 DOM 객체(즉, 현재 참조된 Cache, Request, Response 객체)는 계속 동작해야 한다.
-
-
cacheJobPromise를 반환한다.
-
5.5.5.
keys()
keys() 메서드 단계는 다음과 같다:
-
promise를 새로운 프라미스로 둔다.
-
다음 하위 단계를 병렬로 실행한다:
-
cacheKeys를 관련 name to cache map의 키를 얻은 결과로 둔다.
참고: 결과 ordered set에 있는 항목들은 name to cache map에 해당 엔트리가 추가된 순서대로 정렬되어 있다.
-
promise를 cacheKeys로 resolve한다.
-
-
promise를 반환한다.
6. 보안 고려사항
6.1. 보안 컨텍스트
서비스 워커는 보안 컨텍스트에서 실행되어야 한다. 서비스 워커 클라이언트도 서비스 워커 등록을 등록하고, 서비스 워커 등록 및 서비스 워커에 접근하며, 서비스 워커와 메시지를 주고받고, 서비스 워커에 의해 조작되려면 보안 컨텍스트여야 한다.
참고: 이는 사실상 서비스
워커와 그 서비스 워커 클라이언트가 HTTPS를 통해 호스팅되어야
함을 의미한다. 사용자 에이전트는 개발 목적으로 localhost(요구사항 참조),
127.0.0.0/8 및 ::1/128을 허용할 수 있다. 이 제한의 주된 이유는
비보안 컨텍스트와 관련된
위험으로부터 사용자를 보호하기 위해서이다.
6.2. 콘텐츠 보안 정책
사용자 에이전트가 서비스 워커 실행 알고리즘을 서비스 워커 serviceWorker에 대해 호출할 때:
-
serviceWorker의 스크립트 리소스가
Content-Security-PolicyHTTP 헤더와 policy 값을 포함하여 전달되었다면, 사용자 에이전트는 반드시 policy를 적용해야 합니다. -
serviceWorker의 스크립트 리소스가
Content-Security-Policy-Report-OnlyHTTP 헤더와 policy 값을 포함하여 전달되었다면, 사용자 에이전트는 반드시 policy를 모니터링해야 합니다.
이러한 제한의 주요 목적은 교차 사이트 스크립팅(XSS)과 같은 다양한 컨텐츠 주입 취약점을 완화하기 위함입니다.
6.3. 오리진 상대성
6.3.1. 오리진 제한
이 절은 규범적이지 않습니다.
서비스 워커는 등록한 클라이언트의 오리진에서 실행됩니다. 주요 응용 프로그램에서 마주할 수 있는 고급 문제 중 하나는 CDN에서 서비스 워커를 호스팅할 수 있는지입니다. 정의상 CDN은 종종 다른 오리진에 위치합니다. 따라서 서비스 워커는 CDN에서 호스팅할 수 없습니다. 대신 importScripts()를 통해 리소스를 포함할 수 있습니다. 이러한 제한의 이유는 서비스 워커가 악의적인 공격자에게 심각한 보안 위협을 줄 수 있기 때문입니다.
6.3.2.
importScripts(urls)
importScripts(urls) 메서드가
ServiceWorkerGlobalScope
객체에서 호출되면, 사용자 에이전트는 반드시 해당 ServiceWorkerGlobalScope
객체와 urls를 사용해 워커 글로벌 스코프에 스크립트 가져오기를 수행해야 하며, 다음과
같은 페치 훅 단계를 request request에 대해 수행합니다:
-
map을 serviceWorker의 스크립트 리소스 맵으로 둡니다.
-
url을 request의 url로 둡니다.
-
serviceWorker의 상태가 "
parsed" 또는 "installing"이 아니면: -
map[url]이 존재하면:
-
Append를 통해 url을 serviceWorker의 사용된 스크립트 집합에 추가합니다.
-
map[url]을 반환합니다.
-
-
registration을 serviceWorker의 포함 서비스 워커 등록으로 둡니다.
-
request의 service-workers mode를 "
none"으로 설정합니다. -
다음 중 하나라도 참이면 request의 cache mode를 "
no-cache"로 설정합니다:-
registration의 update via cache mode가 "
none"인 경우 -
현재 글로벌 객체의 importScripts 캐시 우회 플래그가 설정된 경우
-
registration이 stale인 경우
-
-
response를 request에 대해 fetch한 결과로 둡니다.
-
response의 cache state가 "
local"이 아니면, registration의 마지막 업데이트 확인 시간을 현재 시간으로 설정합니다. -
response의 unsafe response가 잘못된 import 스크립트 응답이면 네트워크 오류를 반환합니다.
-
Set을 통해 map[url]에 response를 저장합니다.
-
Append를 통해 url을 serviceWorker의 사용된 스크립트 집합에 추가합니다.
-
serviceWorker의 클래식 스크립트 import 플래그를 설정합니다.
-
response를 반환합니다.
6.4. 교차 오리진 리소스 및 CORS
이 절은 규범적이지 않습니다.
애플리케이션은 CDN이나 기타 오리진에서 가져온 항목들을 캐싱하는 경우가 많습니다.
<script>, <img>, <video>, <link> 요소를
사용해 많은 자원을 직접 요청하는 것도 가능합니다. 이런 런타임 협업이 오프라인일 때 깨진다면 크게 제한될 것입니다. 마찬가지로 적절한 CORS 헤더들이 설정되어 있다면 다양한
오리진-외부(origin 외부) 자원들을 fetch로 가져올 수
있습니다.
서비스 워커는
Caches가 fetch와 캐싱을 오리진 외부 항목에 대해 할 수 있도록 하여 이를 가능하게 합니다. 다만 몇 가지 제한이
있습니다. 우선, 같은 오리진 리소스가 Cache에서 Response
객체로 관리되고 해당 response가 기본 필터링 응답(basic filtered response)인 것과 달리, 저장되는
객체는 Response이고,
그 response가 CORS 필터링 응답 또는 Opaque 필터링 응답인 경우입니다. 이 객체들은 event.respondWith(r)
메서드에, Response의
response가 기본 필터링 응답인 경우와 동일하게 전달할 수 있지만, 프로그램적으로 의미 있게
직접 생성할 수 없습니다. 이러한 제한은 플랫폼의 보안 불변성을 보장하기 위해 필요합니다. Caches가 이런
객체들도 저장할 수 있게 함으로써 대부분의 경우 애플리케이션이 구조를 재설계하지 않아도 되게 해줍니다.
6.5. 경로 제한
이 절은 규범적이지 않습니다.
오리진 제한 외에도, 서비스 워커는 서비스 워커 스크립트의 경로에 의해
제한됩니다. 예를 들어 https://www.example.com/~bob/sw.js에 위치한 서비스 워커 스크립트는 scope url
https://www.example.com/~bob/에는 등록할 수 있지만, https://www.example.com/ 또는
https://www.example.com/~alice/에는 등록할 수 없습니다. 이는 같은 오리진 내에서 여러 사용자 콘텐츠를 별도의 디렉터리에 분리해
호스팅하는 사이트에 어느 정도 보호를 제공합니다. 그러나 경로 제한은 오리진만큼 강력한 보안 경계로 간주되지 않습니다. 사이트에서는 적절할 경우 서로 다른 오리진을 사용해 사이트의
부분을 안전하게 격리할 것을 권장합니다.
서버는 서비스 워커 스크립트에 Service-Worker-Allowed 헤더를 설정함으로써 경로 제한을 제거할 수 있습니다.
6.6. 서비스 워커 스크립트 요청
이 절은 규범적이지 않습니다.
악의적인 서비스 워커의 등록을 방지하기 위해, 이 명세는 다음을 요구합니다:
-
서비스 워커 스크립트 요청에 Service-Worker 헤더가 포함되어야 하며,
-
서비스 워커 스크립트는 자바스크립트 MIME 타입으로 제공되어야 합니다.
6.7. 구현자 고려사항
이 절은 규범적이지 않습니다.
구현자들은 다음을 주의해야 합니다:
-
플러그인은 서비스 워커를 통해 로드되어서는 안 됩니다. 플러그인은 자체 URL에서 보안 오리진을 얻을 수 있으므로, 임베딩한 서비스 워커가 이를 처리할 수 없습니다. 이런 이유로 Handle Fetch 알고리즘은
<embed>및<object>요청을fetch이벤트를 디스패치하지 않고 즉시 네트워크로 폴백합니다. -
레거시 네트워킹 스택 코드 중 일부는 서비스 워커와의 상호작용으로 인한 영향을 이해하기 위해 신중한 점검이 필요할 수 있습니다.
6.8. 프라이버시
서비스 워커는 새로운 영구 저장소 기능을 도입합니다. 여기에는 등록 맵(서비스 워커 등록과 그 서비스 워커용), 요청-응답 리스트와 name to cache 맵(캐시 용), 그리고 스크립트 리소스 맵(스크립트 리소스 용)이 포함됩니다. 사용자들이 인가되지 않은 추적 위협으로부터 보호받을 수 있도록, 이러한 영구 저장소는 사용자가 삭제를 의도할 때 반드시 삭제되어야 하며, 기존 사용자 제어 기능(예: 모든 영구 저장소 전체 삭제)과 호환되어야 하고 연동되어야 합니다.
7. 확장성
서비스 워커 명세는 다른 명세에서 확장할 수 있습니다.
7.1. Service Worker Registration에 바인딩된 API 정의
명세는 API를 서비스 워커 등록에 연결하여, ServiceWorkerRegistration
인터페이스에 부분 인터페이스(partial interface) 정의를 사용해서, 명세별 속성과 메서드를
정의할 수 있습니다:
partial interface ServiceWorkerRegistration { // 예시: API 네임스페이스 정의readonly attribute APISpaceType APISpace ; // 예시: 메서드 정의Promise <T >methodName (/* 인자 목록 */); };
7.2. 기능적 이벤트 정의
명세는 기능적 이벤트(functional event)를 ExtendableEvent
인터페이스를 확장하여 정의할 수 있습니다:
// 예: FunctionalEvent 인터페이스 정의interface FunctionalEvent :ExtendableEvent { // 기능성 이벤트 고유 속성과 메서드 추가 };
7.3. 이벤트 핸들러 정의
명세는 기능적 이벤트(functional event)에 해당하는 이벤트 핸들러 속성을 partial interface 정의를 ServiceWorkerGlobalScope
인터페이스에 추가하여 정의할 수 있습니다:
partial interface ServiceWorkerGlobalScope {attribute EventHandler onfunctionalevent ; };
7.4. 기능적 이벤트 발생
기능적 이벤트를 활성 워커에 디스패치하도록 요청하려면, 명세는 반드시 Fire Functional Event를 호출해야 합니다.
부록 A: 알고리즘
다음 정의들은 명세 전반에서 사용되는 사용자 에이전트의 내부 데이터 구조입니다.
등록 맵은 (순서가 있는 맵)으로, 키는 (storage key, 직렬화된 scope url)이고 값은 서비스 워커 등록입니다.
job은 서비스 워커 등록에 대한 register, update, unregister 요청 중 하나의 추상화입니다.
job은 storage key(storage key)를 가집니다.
job은 worker type("classic" 또는 "module")을 가집니다.
job은 update via cache mode("imports", "all", "none") 중 하나입니다.
job은 client(서비스 워커 클라이언트)를 가지며, 초기값은 null입니다.
job은 referrer(URL 또는 null)을 가집니다.
job은 job promise(promise)를 가지며, 초기값은 null입니다.
job은 containing job queue(job queue 또는 null)을 가지며, 초기값은 null입니다.
job은 동등 job 리스트(job 리스트)이며, 초기값은 빈 리스트입니다.
job은 force bypass cache flag를 가지며, 초기값은 unset입니다.
두 job이 동등이려면 job type이 동일해야 하며, 다음 조건을 만족해야 합니다:
-
register와 update job의 경우, scope url, script url, worker type, update via cache mode가 모두 동일해야 합니다.
job queue는 동시 job 집합의 동기화를 위해 사용되는 thread-safe 큐입니다. job queue는 job을 item으로 포함하며, 초기값은 비어 있습니다.
scope to job queue map은 키가 scope url(직렬화됨)이고, 값이 job queue인 순서가 있는 맵입니다.
잘못된 import 스크립트 응답은 아래 조건 중 하나를 만족하는 response입니다:
-
response의 type이 "
error"인 경우 -
response의 header list에서 MIME type 추출 결과가 자바스크립트 MIME 타입이 아닌 경우
참고: 이 정의는 클래식 워커-imported 스크립트 fetch와 동기화되어야 합니다.
race result는 튜플이며, 구성 요소는 라우팅된 응답(routed response)과 사용된 라우트(used route)이다.
race result에는 라우팅된 응답(routed response)이 연관되어 있으며, 이는 response이다.
race result에는 사용된 라우트(used route)가 연관되어 있으며, 이는 RouterSourceEnum
타입이다.
작업 생성
작업 스케줄
- 입력
-
job, 작업
- 출력
-
없음
-
jobQueue를 null로 둔다.
-
scope to job queue map[jobScope]가 존재하지 않으면, scope to job queue map[jobScope]에 새 작업 큐를 설정한다.
-
jobQueue를 scope to job queue map[jobScope]로 설정한다.
-
jobQueue가 비어 있으면:
-
job의 containing job queue를 jobQueue로 설정하고, jobQueue에 job을 enqueue한다.
-
작업 실행을 jobQueue로 호출한다.
-
-
그 외의 경우:
-
lastJob을 jobQueue의 마지막 요소로 둔다.
-
job이 동등하고 lastJob의 작업 프라미스가 아직 settle되지 않았다면, job을 lastJob의 동등 작업 리스트에 추가한다.
-
그 외에는, job의 containing job queue를 jobQueue로 설정하고, jobQueue에 job을 enqueue한다.
-
작업 실행
- 입력
-
jobQueue, 작업 큐
- 출력
-
없음
작업 완료
- 입력
-
job, 작업
- 출력
-
없음
-
jobQueue를 job의 containing job queue로 둔다.
-
단언: jobQueue의 첫 번째 item이 job임을 보장한다.
작업 프라미스 해결
- 입력
-
job, 작업
value, 임의 값
- 출력
-
없음
-
job의 client가 null이 아니면, task를 큐에 넣어, job의 client의 responsible event loop에서 DOM manipulation task source를 사용해 다음 하위 단계를 실행한다:
-
convertedValue를 null로 둔다.
-
job의 job type이 register 또는 update 중 하나이면, convertedValue를 service worker registration object를 가져오기를 통해 job의 client에서 value를 나타내는 결과로 설정한다.
-
job의 job promise를 convertedValue로 resolve한다.
-
-
job의 list of equivalent jobs에 있는 각 equivalentJob에 대해:
-
equivalentJob의 client가 null이면, 루프의 다음 반복으로 계속한다.
-
task를 큐에 넣어, equivalentJob의 client의 responsible event loop에서 DOM manipulation task source를 사용해 다음 하위 단계를 실행한다:
-
convertedValue를 null로 둔다.
-
equivalentJob의 job type이 register 또는 update 중 하나이면, convertedValue를 service worker registration object를 가져오기를 통해 equivalentJob의 client에서 value를 나타내는 결과로 설정한다.
-
그렇지 않으면, convertedValue를 equivalentJob의 client의 Realm에서 value로 설정한다.
-
equivalentJob의 job promise를 convertedValue로 resolve한다.
-
-
작업 프라미스 거부
- 입력
-
job, 작업
errorData, 예외 생성에 필요한 정보
- 출력
-
없음
등록 시작
- 입력
-
scopeURL, URL 또는 실패 또는 null
scriptURL, URL 또는 실패
promise, 프라미스
client, 서비스 워커 클라이언트
referrer, URL
workerType, 워커 타입
updateViaCache, update via cache mode
- 출력
-
없음
-
scriptURL이 실패이면, promise를
TypeError로 reject하고 이 단계를 중단한다. -
scriptURL의 fragment를 null로 설정한다.
참고: 사용자 에이전트는 스크립트 url의 fragment를 저장하지 않는다. 즉, fragment는 서비스 워커 식별에 영향을 주지 않는다.
-
scriptURL의 scheme이 "
http", "https"가 아니면, promise를TypeError로 reject하고 이 단계를 중단한다. -
scriptURL의 path에 포함된 어떤 문자열이 ASCII 대소문자 구분 없이 "
%2f", "%5c"를 포함하면, promise를TypeError로 reject하고 이 단계를 중단한다. -
scopeURL이 null이면, scopeURL을 "./" 문자열과 scriptURL로 파싱한 결과로 설정한다.
참고: 등록의 기본 scope url은 서비스 워커 스크립트 위치로 설정된다.
-
scopeURL이 실패이면, promise를
TypeError로 reject하고 이 단계를 중단한다. -
scopeURL의 fragment를 null로 설정한다.
참고: 사용자 에이전트는 scope url의 fragment를 저장하지 않는다. 즉, fragment는 서비스 워커 등록 식별에 영향을 주지 않는다.
-
scopeURL의 scheme이 "
http", "https"가 아니면, promise를TypeError로 reject하고 이 단계를 중단한다. -
scopeURL의 path에 포함된 어떤 문자열이 ASCII 대소문자 구분 없이 "
%2f", "%5c"를 포함하면, promise를TypeError로 reject하고 이 단계를 중단한다. -
storage key를 클라이언트에서 스토리지 키 얻기 결과로 설정한다.
-
job을 작업 생성을 register, storage key, scopeURL, scriptURL, promise, client로 실행한 결과로 둔다.
-
job의 워커 타입을 workerType으로 설정한다.
-
job의 update via cache mode를 updateViaCache로 설정한다.
-
job의 referrer를 referrer로 설정한다.
-
작업 스케줄을 job로 호출한다.
등록
- 입력
-
job, 작업
- 출력
-
없음
-
잠재적으로 신뢰할 수 있는 오리진 알고리즘을 job의 script url의 오리진에 대해 실행한 결과가
Not Trusted이면:-
작업 프라미스 거부를 job과 "
SecurityError"DOMException"로 호출한다. -
작업 완료를 job로 호출하고 이 단계를 중단한다.
-
-
job의 script url의 오리진과 job의 referrer의 오리진이 동일 오리진이 아니면:
-
작업 프라미스 거부를 job과 "
SecurityError"DOMException"로 호출한다. -
작업 완료를 job로 호출하고 이 단계를 중단한다.
-
-
job의 scope url의 오리진과 job의 referrer의 오리진이 동일 오리진이 아니면:
-
작업 프라미스 거부를 job과 "
SecurityError"DOMException"로 호출한다. -
작업 완료를 job로 호출하고 이 단계를 중단한다.
-
-
registration을 등록 가져오기를 job의 스토리지 키와 job의 scope url로 실행한 결과로 둔다.
-
registration이 null이 아니면:
-
newestWorker를 최신 워커 가져오기를 registration에 대해 실행한 결과로 둔다.
-
newestWorker가 null이 아니고, job의 script url이 동등하고, job의 워커 타입이 newestWorker의 type과 같고, job의 update via cache mode 값이 registration의 update via cache mode와 같으면:
-
작업 프라미스 해결을 job과 registration으로 호출한다.
-
작업 완료를 job로 호출하고 이 단계를 중단한다.
-
-
-
그 외에는:
-
등록 설정 알고리즘을 job의 스토리지 키, job의 scope url, job의 update via cache mode로 실행한다.
-
-
업데이트 알고리즘을 job로 실행한다.
업데이트
- 입력
-
job, 작업
- 출력
-
없음
-
registration을 등록 가져오기를 job의 스토리지 키와 job의 scope url로 실행한 결과로 둔다.
-
registration이 null이면:
-
작업 프라미스 거부를 job과
TypeError로 호출한다. -
작업 완료를 job로 호출하고 이 단계를 중단한다.
-
-
newestWorker를 최신 워커 가져오기 알고리즘을 registration에 대해 실행한 결과로 둔다.
-
job의 작업 타입이 update이고, newestWorker가 null이 아니면서 newestWorker의 script url이 동등하지 않으면 job의 script url과:
-
작업 프라미스 거부를 job과
TypeError로 호출한다. -
작업 완료를 job로 호출하고 이 단계를 중단한다.
-
-
hasUpdatedResources를 false로 둔다.
-
job의 워커 타입에 따라 다음 옵션으로 하위 단계를 실행한다:
- "
classic" -
클래식 워커 스크립트 가져오기를 job의 직렬화된 script url, job의 클라이언트, "
serviceworker", 그리고 이 서비스 워커의 환경 설정 객체로 실행한다. - "
module" -
모듈 워커 스크립트 그래프 가져오기를 job의 직렬화된 script url, job의 클라이언트, "
serviceworker", "same-origin", 그리고 이 서비스 워커의 환경 설정 객체로 실행한다.
아직 생성되지 않은 environment settings object를 사용하는 것은, 구체적인 environment settings object 대신입니다. 이는 서비스 워커가 다른 웹 워커와 다른 고유한 처리 모델을 가지기 때문입니다. HTML 표준의 스크립트 페치 알고리즘은 원래 다른 웹 워커를 위해 설계되었으며, 실행 환경의 environment settings object를 필요로 합니다. 그러나 서비스 워커는 Update 알고리즘에서 스크립트를 별도로 가져온 후, 그 스크립트가 이후 Run Service Worker 알고리즘을 통해 여러 번 실행됩니다.
HTML의 워커 스크립트 fetch 알고리즘은 job의 클라이언트를 인자로 받는다. job의 클라이언트는 Soft Update 알고리즘에서 전달받을 때 null이다.
fetch hook 수행에서 request에 대해 다음 단계를 실행한다:
-
Service-Worker/script를 request의 헤더 리스트에 추가한다.참고: Service-Worker 헤더의 정의는 부록 B: 확장 HTTP 헤더를 참조하세요.
-
다음 중 하나라도 해당되면 request의 캐시 모드(cache mode)를 "
no-cache"로 설정한다:-
registration의 update via cache mode가 "
all"이 아닌 경우. -
job의 강제 캐시 우회 플래그(force bypass cache flag)가 설정된 경우.
-
newestWorker가 null이 아니고 registration이 stale 상태인 경우.
참고: 캐시 모드가 "
no-cache"로 설정되지 않더라도, 네트워크 계층 단에서 사용자 에이전트는 Cache-Control 헤더의 max-age 값을 따르므로 브라우저 캐시를 우회할 수 있습니다. -
-
request의 service-workers 모드를 "
none"으로 설정한다. -
만약 isTopLevel 플래그가 설정되어 있지 않으면, fetching request의 결과를 반환한다.
-
request의 리디렉션 모드(redirect mode)를 "
error"로 설정한다. -
Fetch request를 수행하고, 비동기적으로 나머지 단계를 fetch의 processResponse (응답: response)의 일부로서 진행한다.
-
response의 헤더 리스트에서 MIME 타입을 추출한다. 이 MIME 타입(매개변수는 무시)의 값이 자바스크립트 MIME 타입이 아니라면:
-
Reject Job Promise를 job과 "
SecurityError"DOMException과 함께 호출한다. -
비동기적으로 이 단계를 네트워크 에러로 완료한다.
-
-
serviceWorkerAllowed를 가져오기의 결과로 둔다. response의 헤더 목록에서 `
Service-Worker-Allowed`를 가져온 결과이다.참고: Service-Worker-Allowed 헤더의 정의는 부록 B: 확장 HTTP 헤더를 보라.
-
serviceWorkerAllowed가 null이 아니면, serviceWorkerAllowed를 동형 디코드의 결과로 설정한다. serviceWorkerAllowed에 대해 수행한다.
-
policyContainer를 response가 주어진 상태에서 fetch 응답에서 정책 컨테이너 생성하기의 결과로 설정한다.
-
scopeURL을 registration의 scope url로 둔다.
-
maxScopeString을 null로 둔다.
-
serviceWorkerAllowed가 null이면:
-
resolvedScope를 파싱의 결과로 둔다. "
./"을 job의 script url을 기준 URL로 사용하여 파싱한다. -
maxScopeString을 "
/"와, 그 뒤에 resolvedScope의 경로에 있는 문자열들(빈 문자열 포함)을 서로 "/"로 구분해 이어 붙인 값으로 설정한다.참고: resolvedScope의 경로의 마지막 항목은 항상 빈 문자열이므로, maxScopeString은 뒤에 "
/"가 붙는다.
-
-
그렇지 않으면:
-
maxScope를 파싱의 결과로 둔다. serviceWorkerAllowed를 job의 script url을 기준 URL로 사용하여 파싱한다.
-
maxScope가 실패이면:
-
이 단계들을 네트워크 오류로 비동기적으로 완료한다.
-
-
maxScope의 출처가 job의 script url의 출처이면:
-
maxScopeString을 "
/"와, 그 뒤에 maxScope의 경로에 있는 문자열들(빈 문자열 포함)을 서로 "/"로 구분해 이어 붙인 값으로 설정한다.
-
-
-
scopeString을 "
/"와, 그 뒤에 scopeURL의 경로에 있는 문자열들(빈 문자열 포함)을 서로 "/"로 구분해 이어 붙인 값으로 둔다. -
maxScopeString이 null이거나 scopeString이 maxScopeString으로 시작하지 않으면:
-
Reject Job Promise를 job 및 "
SecurityError"DOMException으로 호출한다. -
이 단계들을 네트워크 오류로 비동기적으로 완료한다.
-
-
url을 request의 url로 둔다.
-
updatedResourceMap[url]을 response로 설정한다.
-
response의 캐시 상태가 "
local"이 아니면, registration의 마지막 업데이트 확인 시간을 현재 시각으로 설정한다. -
다음 중 어느 하나라도 참이면 hasUpdatedResources를 true로 설정한다:
-
newestWorker가 null이다.
-
newestWorker의 script url이 url이 아니거나 newestWorker의 타입이 job의 worker type이 아니다.
-
newestWorker의 스크립트 리소스 맵[url]의 본문이 response의 본문과 바이트 단위로 동일하지 않다.
-
-
hasUpdatedResources가 false이고 newestWorker의 클래식 스크립트 가져오기 플래그가 설정되어 있으면:
참고: 다음은 주 스크립트가 변경되지 않았으므로 가져온 스크립트가 업데이트되었는지 확인한다.
-
newestWorker의 스크립트 리소스 맵의 각 importUrl → storedResponse에 대해 순회한다:
-
importUrl이 url이면 계속한다.
-
importRequest를 새 요청으로 둔다. 이 요청의 URL은 importUrl이고, 클라이언트는 job의 클라이언트이며, 대상은 "
script"이고, 파서 메타데이터는 "not parser-inserted"이며, 요청의 URL 자격 증명 사용 플래그가 설정되어 있다. -
다음 중 어느 하나라도 참이면 importRequest의 캐시 모드를 "
no-cache"로 설정한다:-
registration의 update via cache mode가 "
none"이다. -
job의 force bypass cache flag가 설정되어 있다.
-
registration이 오래됨이다.
-
-
fetchedResponse를 fetching의 결과로 둔다. importRequest에 대해 수행한다.
-
updatedResourceMap[importRequest의 url]을 fetchedResponse로 설정한다.
-
fetchedResponse를 fetchedResponse의 unsafe response로 설정한다.
-
fetchedResponse의 캐시 상태가 "
local"이 아니면, registration의 마지막 업데이트 확인 시간을 현재 시각으로 설정한다. -
fetchedResponse가 잘못된 가져오기 스크립트 응답이면 계속한다.
참고: importScripts()에 대한 잘못된 응답은 바이트 단위 확인 목적에서는 무시된다. 현재 작업자에 대한 정상 응답과 잠재적 업데이트 작업자에 대한 정상 응답만 고려된다. 근거 일부는 이슈 #1374를 보라.
-
fetchedResponse의 본문이 storedResponse의 unsafe response의 본문과 바이트 단위로 동일하지 않으면, hasUpdatedResources를 true로 설정한다.
참고: 이 단계의 제어는 캐시를 채우기 위해 가져온 모든 스크립트에 대해 계속 진행하도록 루프를 중단하지 않는다.
-
-
-
비동기적으로 이 단계를 response로 완료한다.
이 알고리즘이 비동기로 완료되면, 남은 단계들을 script를 비동기 완료 값으로 하여 계속한다.
- "
-
만약 script가 null이거나 Is Async Module이 script의 record, script의 base URL, 그리고 « »로 실행되어 true이면:
-
Reject Job Promise를 job과
TypeError를 인자로 호출한다.참고: 이전에 Reject Job Promise가 "
SecurityError"DOMException과 함께 호출되었다면 이 단계는 아무것도 하지 않는다. -
newestWorker가 null이면 remove registration map[(registration의 storage key, serialized scopeURL)]를 실행한다.
-
Finish Job을 job에 대해 호출하고 이 단계를 중단한다.
-
-
hasUpdatedResources가 false이면:
-
registration의 update via cache mode를 job의 update via cache mode로 설정한다.
-
Resolve Job Promise를 job 및 registration을 인자로 호출한다.
-
Finish Job을 job에 대해 호출하고 이 단계를 중단한다.
-
-
worker를 새로운 service worker로 둔다.
-
worker의 script url을 job의 script url로, worker의 script resource를 script로, worker의 type을 job의 worker type으로, worker의 script resource map을 updatedResourceMap으로 설정한다.
-
url을 worker의 set of used scripts에 추가한다.
-
worker의 script resource의 policy container를 policyContainer로 설정한다.
-
forceBypassCache를 job의 force bypass cache flag가 설정되어 있으면 true, 그렇지 않으면 false로 둔다.
-
runResult를 Run Service Worker 알고리즘을 worker와 forceBypassCache를 인자로 실행한 결과로 둔다.
-
runResult가 실패 또는 abrupt completion인 경우:
-
Reject Job Promise를 job과
TypeError를 인자로 호출한다. -
newestWorker가 null이면 remove registration map[(registration의 storage key, serialized scopeURL)]를 실행한다.
-
Finish Job을 job에 대해 호출한다.
-
-
아니라면, Install 알고리즘을 job, worker, registration을 인자로 실행한다.
소프트 업데이트
사용자 에이전트는 업데이트를 확인하기 위해 원하는 만큼 자주 이 알고리즘을 호출할 수 있습니다.
- 입력
-
registration, 서비스 워커 등록
forceBypassCache, 선택적 불리언, 기본값은 false
참고: 구현자는 forceBypassCache를 디버깅(예: 개발자 도구에서 호출)이나 서비스 워커를 확장하는 다른 명세에서 필요에 따라 사용할 수 있습니다.
- 출력
-
없음
-
newestWorker를 최신 워커 가져오기 알고리즘을 registration에 대해 실행한 결과로 둔다.
-
newestWorker가 null이면 이 단계를 중단한다.
-
job을 작업 생성을 update, registration의 스토리지 키, registration의 scope url, newestWorker의 script url, null, null로 실행한 결과로 둔다.
-
forceBypassCache가 true이면 job의 force bypass cache flag를 설정한다.
-
작업 스케줄을 job로 호출한다.
설치
-
installFailed를 false로 둔다.
-
newestWorker를 registration을 인수로 전달하여 최신 워커 가져오기 알고리즘을 실행한 결과로 둔다.
-
registration의 캐시를 통한 업데이트 모드를 job의 캐시를 통한 업데이트 모드로 설정한다.
-
registration, "
installing", worker를 인수로 전달하여 등록 상태 업데이트 알고리즘을 실행한다. -
registration의 설치 중인 워커와 "
installing"을 인수로 전달하여 워커 상태 업데이트 알고리즘을 실행한다. -
단언: job의 작업 프로미스는 null이 아니다.
-
job과 registration을 사용하여 작업 프로미스 이행을 호출한다.
-
settingsObjects를 환경 설정 객체 중 그 출처가 registration의 범위 URL의 출처인 모든 객체로 둔다.
-
settingsObjects의 각 settingsObject에 대해, settingsObject의 담당 이벤트 루프에서 DOM 조작 태스크 소스를 사용해 다음 단계를 실행하도록 태스크를 큐에 추가한다:
-
registrationObjects를 settingsObject의 realm에 있는 모든
ServiceWorkerRegistration객체 중, 그 서비스 워커 등록이 registration인 객체로 둔다. -
registrationObjects의 각 registrationObject에 대해, registrationObject에서
updatefound라는 이름의 이벤트를 발생시킨다.
-
-
installingWorker를 registration의 설치 중인 워커로 둔다.
-
installingWorker와 "install"을 사용해 이벤트 건너뛰기 여부 알고리즘을 실행한 결과가 false이면:
-
job의 강제 캐시 우회 플래그가 설정되어 있으면 forceBypassCache를 true로, 그렇지 않으면 false로 둔다.
-
installingWorker와 forceBypassCache를 사용해 서비스 워커 실행 알고리즘을 실행한 결과가 실패이면:
-
installFailed를 true로 설정한다.
-
-
그렇지 않으면:
-
installingWorker의 이벤트 루프에서 DOM 조작 태스크 소스를 사용하여 다음 단계를 실행하도록 task라는 태스크를 큐에 추가한다:
-
e를
InstallEvent로 이벤트를 생성한 결과로 둔다. -
WaitForAsynchronousExtensions: 다음 하위 단계를 병렬로 실행한다:
-
e가 더 이상 활성 상태가 아닐 때까지 기다린다.
-
e의 시간 초과 플래그가 설정되어 있으면, installFailed를 true로 설정한다.
-
p를 e의 수명 연장 프로미스 모두를 기다리기 위한 프로미스를 가져온 결과로 둔다.
-
p가 거부되면, installFailed를 true로 설정한다.
-
task가 폐기되면, installFailed를 true로 설정한다.
-
-
task가 실행되거나 폐기될 때까지 기다린다.
-
WaitForAsynchronousExtensions라는 레이블이 지정된 단계가 완료될 때까지 기다린다.
-
-
-
installFailed가 true이면:
-
registration의 설치 중인 워커와 "
redundant"를 인수로 전달하여 워커 상태 업데이트 알고리즘을 실행한다. -
registration, "
installing", null을 인수로 전달하여 등록 상태 업데이트 알고리즘을 실행한다. -
newestWorker가 null이면, 등록 맵[(registration의 저장소 키, 직렬화된 registration의 범위 URL)]을 제거한다.
-
job을 사용하여 작업 완료를 호출하고 이 단계들을 중단한다.
-
-
map을 registration의 설치 중인 워커의 스크립트 리소스 맵으로 둔다.
-
usedSet을 registration의 설치 중인 워커의 사용된 스크립트 집합으로 둔다.
-
map의 각 url에 대해:
-
registration의 대기 중인 워커가 null이 아니면:
-
registration의 대기 중인 워커와 "
redundant"를 인수로 전달하여 워커 상태 업데이트 알고리즘을 실행한다.
-
registration, "
waiting", registration의 설치 중인 워커를 인수로 전달하여 등록 상태 업데이트 알고리즘을 실행한다. -
registration, "
installing", null을 인수로 전달하여 등록 상태 업데이트 알고리즘을 실행한다. -
registration의 대기 중인 워커와 "
installed"를 인수로 전달하여 워커 상태 업데이트 알고리즘을 실행한다. -
job을 사용하여 작업 완료를 호출한다.
-
이 알고리즘에서 호출된 워커 상태 업데이트가 큐에 추가한 모든 태스크가 실행될 때까지 기다린다.
-
registration을 사용하여 활성화 시도를 호출한다.
참고: 여기에서 활성화 시도가 활성화를 트리거하지 않으면, 기존 활성 워커가 제어하는 마지막 클라이언트가 언로드되거나,
skipWaiting()이 비동기적으로 호출되거나, 기존 활성 워커의 수명 연장 프로미스가 확정될 때 활성화를 다시 시도한다.
활성화
- 입력
-
registration, 서비스 워커 등록
- 출력
-
없음
-
registration의 대기 중인 워커가 null이면, 이 단계들을 중단한다.
-
registration의 활성 워커가 null이 아니면:
-
registration의 활성 워커와 "
redundant"를 인수로 전달하여 워커 상태 업데이트 알고리즘을 실행한다.
-
registration, "
active", registration의 대기 중인 워커를 인수로 전달하여 등록 상태 업데이트 알고리즘을 실행한다. -
registration, "
waiting", null을 인수로 전달하여 등록 상태 업데이트 알고리즘을 실행한다. -
registration의 활성 워커와 "
activating"을 인수로 전달하여 워커 상태 업데이트 알고리즘을 실행한다.참고: 활성 워커가 활성화 중인 상태가 되면, 런타임 스크립트 오류도 활성 워커의 강제 종료도 활성 워커가 활성화되는 것을 방지하지 못한다.
참고: 활성화 핸들러는 중요하지 않은 작업(예: 정리)을 수행하도록 설계해야 한다. 이는 특히 활성화 중 브라우저가 종료되는 경우 활성화 핸들러가 모두 완료될 때까지 실행되지 않을 수 있기 때문이다. Service Worker는 활성화 핸들러가 모두 성공적으로 완료되지 않더라도 올바르게 동작하도록 설계해야 한다.
-
matchedClients를 목록으로 둔다. 이 목록은 서비스 워커 클라이언트 중 그 생성 URL이 registration의 저장소 키와 registration의 범위 URL에 일치하는 것들로 구성된다.
-
matchedClients의 각 client에 대해, client의 담당 이벤트 루프에서 DOM 조작 태스크 소스를 사용하여 다음 하위 단계를 실행하도록 태스크를 큐에 추가한다:
-
readyPromise를 client의 전역 객체의
ServiceWorkerContainer객체의 ready 프로미스로 둔다. -
readyPromise가 null이면, 계속한다.
-
readyPromise가 대기 중이면, readyPromise의 관련 설정 객체에서 registration을 나타내는 서비스 워커 등록 객체를 가져온 결과로 readyPromise를 이행한다.
-
-
registration을 사용하는 각 서비스 워커 클라이언트 client에 대해:
-
client를 인수로 사용하여 컨트롤러 변경 알림 알고리즘을 호출한다.
-
activeWorker를 registration의 활성 워커로 둔다.
-
activeWorker와 "activate"를 사용하여 이벤트 건너뛰기 여부 알고리즘을 실행한 결과가 false이면:
-
activeWorker를 사용하여 서비스 워커 실행 알고리즘을 실행한 결과가 실패가 아니면:
-
activeWorker의 이벤트 루프에서 DOM 조작 태스크 소스를 사용하여 다음 단계를 실행하도록 task라는 태스크를 큐에 추가한다:
-
task가 실행되거나 폐기될 때까지 기다린다.
-
WaitForAsynchronousExtensions라는 레이블이 지정된 단계가 완료될 때까지 기다린다.
-
-
-
registration의 활성 워커와 "
activated"를 인수로 전달하여 워커 상태 업데이트 알고리즘을 실행한다.
활성화 시도
- 입력
-
registration, 서비스 워커 등록
- 출력
-
없음
-
registration의 대기 중인 워커가 null이면 반환한다.
-
registration의 활성 워커가 null이 아니면서, registration의 활성 워커의 state가 "
activating"이면 반환한다.참고: 기존 활성 워커가 activating 상태라면, 대기 중인 워커의 활성화가 지연된다.
-
다음 중 하나라도 참이면 활성화를 registration로 호출한다:
-
registration의 활성 워커가 null인 경우
-
서비스 워커에 보류 중인 이벤트 없음 알고리즘을 registration의 활성 워커로 실행한 결과가 true이고, 서비스 워커 클라이언트가 registration을 사용하지 않거나, registration의 대기 중인 워커의 skip waiting flag가 설정된 경우.
-
ServiceWorkerGlobalScope 설정
- 입력
-
serviceWorker, 서비스 워커
- 출력
-
ServiceWorkerGlobalScope객체 또는 null
참고: 이 알고리즘은 CSP 검사 등에 사용할 수 있는 ServiceWorkerGlobalScope를
반환하거나 null을 반환한다. serviceWorker에 활성 ServiceWorkerGlobalScope가
있으면 반환하고, 아니면 새로 생성한다.
명세에서 이러한 보안 검사는 ServiceWorkerGlobalScope,
relevant settings object, realm, agent의 생성을 요구합니다. 실제 구현에서는 해야 할
작업이 훨씬 적을 수 있습니다. 따라서 구현에서는 이 알고리즘과 등가인 부분에서 적은 작업만 처리하고, Run Service Worker에서 더 많은
작업을 할 수도 있습니다. 단, 결과가 밖에서 볼 때 동일하다면 허용됩니다. (특히 보안 검사 결과가 동일하다면 문제없습니다.)
-
unsafeCreationTime을 공유 비안전 현재 시간(unsafe shared current time)으로 둔다.
-
만약 serviceWorker가 실행중(running)이라면, serviceWorker의 global object를 반환한다.
-
serviceWorker의 state가 "
redundant"라면 null을 반환한다. -
만약 serviceWorker의 global object가 null이 아니라면, serviceWorker의 global object를 반환한다.
-
명제: serviceWorker의 start status는 null이다.
-
setupFailed를 false로 둔다.
-
globalObject를 null로 둔다.
-
agent를 서비스 워커 에이전트 획득의 결과로 두고, 그 컨텍스트에서 다음 단계를 실행한다:
-
realmExecutionContext를 새로운 realm 생성을 agent와 아래 커스터마이즈를 인자로 실행한 결과로 둔다:
-
글로벌 객체(global object)로 새로운
ServiceWorkerGlobalScope객체를 생성한다. 생성한 객체를 workerGlobalScope로 둔다.
-
-
settingsObject를 다음 알고리즘이 정의된 새로운 environment settings object로 둔다:
- Realm 실행 컨텍스트
-
realmExecutionContext를 반환한다.
- 모듈 맵
-
workerGlobalScope의 모듈 맵을 반환한다.
- API 기준 URL
-
serviceWorker의 스크립트 URL을 반환한다.
- 출처
-
이를 등록한 서비스 워커 클라이언트의 출처를 반환한다.
- 교차 사이트 조상 존재 여부
-
이를 등록한 서비스 워커 클라이언트의 교차 사이트 조상 존재 여부를 반환한다.
- 정책 컨테이너
-
workerGlobalScope의 정책 컨테이너를 반환한다.
- 시간 원점
-
workerGlobalScope의 교차 출처 격리 기능이 주어졌을 때 unsafeCreationTime을 정밀도를 낮춘 결과를 반환한다.
-
settingsObject의 ID를 새로운 고유 불투명 문자열로, 생성 URL을 serviceWorker의 스크립트 URL로, 최상위 생성 URL을 null로, 최상위 출처를 구현 정의 값으로, 대상 브라우징 컨텍스트를 null로, 그리고 활성 서비스 워커를 null로 설정한다.
-
workerGlobalScope의 url을 serviceWorker의 script url로 설정한다.
-
workerGlobalScope의 policy container를 serviceWorker의 script resource의 policy container로 설정한다.
-
새
WorkerLocation객체를 생성하여 workerGlobalScope와 연결한다. -
전역 객체의 CSP 초기화 알고리즘을 workerGlobalScope에 실행하여 "
Blocked"를 반환하면 setupFailed를 true로 하고 이 단계를 중단한다. -
globalObject를 workerGlobalScope로 설정한다.
-
-
globalObject가 null이 아니거나, setupFailed가 true가 될 때까지 기다린다.
-
만약 setupFailed가 true라면 null을 반환한다.
-
globalObject를 반환한다.
서비스 워커 실행
- 입력
-
serviceWorker, 서비스 워커
forceBypassCache, 선택적 불리언, 기본값은 false
- 출력
-
Completion 또는 실패
참고: 이 알고리즘은 서비스 워커가 실행 중이 되거나 시작에 실패할 때까지 블록됩니다.
-
serviceWorker의 상태가 "
redundant"이면, 실패를 반환한다. -
단언: serviceWorker의 시작 상태는 null이다.
-
script를 serviceWorker의 스크립트 리소스로 둔다.
-
단언: script는 null이 아니다.
-
startFailed를 false로 둔다.
-
workerGlobalScope를 serviceWorker의 전역 객체로 둔다.
-
workerGlobalScope가 null이면:
-
workerGlobalScope를 serviceWorker를 사용하여 ServiceWorkerGlobalScope 설정 알고리즘을 실행한 결과로 설정한다.
-
workerGlobalScope가 null이면, 실패를 반환한다.
-
serviceWorker의 전역 객체를 workerGlobalScope로 설정한다.
-
-
workerGlobalScope의 Realm 실행 컨텍스트에 대한 에이전트를 얻고, 해당 컨텍스트에서 다음 단계를 실행한다.
-
forceBypassCache가 true이면 workerGlobalScope의 가져오기 스크립트에 대한 강제 캐시 우회 플래그를 설정한다.
-
serviceWorker가 활성 워커이고, serviceWorker의 포함 서비스 워커 등록의 태스크 큐에 큐에 들어간 태스크가 있으면, 원래의 태스크 소스를 사용하여 동일한 순서로 serviceWorker의 이벤트 루프의 태스크 큐에 그것들을 큐에 넣는다.
-
evaluationStatus를 null로 둔다.
-
script가 클래식 스크립트이면:
-
evaluationStatus를 script 클래식 스크립트를 실행한 결과로 설정한다.
-
evaluationStatus.[[Value]]가 비어 있으면, 이는 스크립트가 평가되지 않았음을 의미한다. startFailed를 true로 설정하고 이 단계를 중단한다.
-
-
그렇지 않고 script가 모듈 스크립트이면:
-
evaluationPromise를 오류 보고를 false로 설정하여 script 모듈 스크립트를 실행한 결과로 둔다.
-
단언: evaluationPromise.[[PromiseState]]는 "pending"이 아니다.
-
evaluationPromise.[[PromiseState]]가 "rejected"이면:
-
evaluationStatus를 ThrowCompletion(evaluationPromise.[[PromiseResult]])으로 설정한다.
-
-
그렇지 않으면:
-
evaluationStatus를 NormalCompletion(undefined)으로 설정한다.
-
-
-
스크립트가 서비스 워커 종료 알고리즘에 의해 중단된 경우, startFailed를 true로 설정하고 이 단계를 중단한다.
-
serviceWorker의 시작 상태를 evaluationStatus로 설정한다.
-
script의 평가된 적 있음 플래그가 설정되어 있지 않으면:
-
settingsObject의 전역 객체와 연결된 이벤트 리스너 리스트의 이벤트 유형 각각의 eventType에 대해:
-
eventType을 workerGlobalScope와 연결된 서비스 워커의 처리할 이벤트 유형 집합에 추가한다.
참고: 전역 객체와 연결된 이벤트 리스너 리스트에 현재 추가된 이벤트 리스너가 하나도 없으면, 서비스 워커의 처리할 이벤트 유형 집합은 빈 집합으로 유지된다.
-
-
script의 평가된 적 있음 플래그를 설정한다.
-
serviceWorker의 모든 가져오기 리스너가 비어 있음 플래그를 해제한다.
-
사용자 에이전트는 workerGlobalScope를 사용한 모든 가져오기 리스너가 비어 있음 알고리즘이 true를 반환하는 경우, serviceWorker의 모든 가져오기 리스너가 비어 있음 플래그를 설정할 수 있다.
-
-
settingsObject이 지정한 담당 이벤트 루프가 파괴될 때까지 실행한다.
-
-
serviceWorker가 실행 중이 되거나 startFailed가 true가 될 때까지 기다린다.
-
startFailed가 true이면, 실패를 반환한다.
-
serviceWorker의 시작 상태를 반환한다.
모든 fetch 리스너 비어 있음
- 입력
-
workerGlobalScope, 글로벌 객체
- 출력
-
불리언 값
-
workerGlobalScope의 처리할 이벤트 타입 집합이 fetch를 포함하지 않으면 true를 반환한다.
-
eventHandler를 workerGlobalScope의 event handler map["onfetch"] 값으로 둔다.
-
eventListenerCallbacks를 legacy-obtain service worker fetch event listener callbacks를 workerGlobalScope에 대해 실행한 결과로 둔다.
-
각 eventListenerCallback을 eventListenerCallbacks에서 반복하여:
-
callback을 null로 둔다.
-
만약 eventHandler가 null이 아니고 eventListenerCallback이 eventHandler의 listener의 callback과 같다면, callback을 ECMAScript 값으로 변환한 eventHandler의 value 결과로 설정한다.
-
그 외에는, callback을 ECMAScript 값으로 변환한 eventListenerCallback의 결과로 설정한다.
-
만약 IsCallable(callback)이 false라면 false를 반환한다.
참고: Callback 객체가
handleEvent(event)형식을 사용할 경우 비어 있지 않은 것으로 간주한다. 이는 체크 도중handleEvent(event)getter를 호출하여 리스너가 변경되는 것을 방지한다. -
만약 callback의 function body가 비어 있지 않다면(즉, statement 또는 declaration이 존재할 경우), false를 반환한다.
참고: 이는
() => {}와 같은 빈 fetch 리스너를 탐지한다. 어떤 사이트들은 fetch 이벤트 리스너에 빈 본문을 추가하여 Chromium에서 PWA로 인식시키기도 한다. -
-
true를 반환한다.
참고: 사용자 에이전트는 불필요한 빈 "fetch" 리스너가
있을 때 경고를 표시하고, 성능에 악영향을 줄 수 있음을 안내할 수 있다.
서비스 워커 종료
- 입력
-
serviceWorker, 서비스 워커
- 출력
-
없음
-
serviceWorker의 메인 루프와 병렬로 다음 단계를 실행한다.
-
serviceWorkerGlobalScope를 serviceWorker의 전역 객체로 둔다.
-
serviceWorkerGlobalScope의 닫는 중 플래그를 true로 설정한다.
-
serviceWorker의 연장된 이벤트 집합에서 모든 항목을 제거한다.
-
serviceWorkerGlobalScope의 이벤트 루프의 태스크 큐에 큐에 들어간 태스크 중, 태스크 소스가 가져오기 처리 태스크 소스 또는 기능 이벤트 처리 태스크 소스인 것이 있으면, 원래의 태스크 소스를 사용하여 동일한 순서로 serviceWorker의 포함 서비스 워커 등록의 해당 태스크 큐에 그것들을 큐에 넣고, serviceWorkerGlobalScope의 이벤트 루프의 태스크 큐에서 모든 태스크(태스크 소스가 가져오기 처리 태스크 소스도 기능 이벤트 처리 태스크 소스도 아닌 태스크 포함)를 처리하지 않고 폐기한다.
참고: 이는 사실상 가져오기 이벤트와 푸시 이벤트 같은 기타 기능 이벤트는 등록의 태스크 큐에 백업되는 반면, 메시지 이벤트를 포함한 기타 태스크는 폐기됨을 의미한다.
-
serviceWorker에서 현재 실행 중인 스크립트를 중단한다.
-
serviceWorker의 시작 상태를 null로 설정한다.
-
Fetch 처리
Fetch 처리 알고리즘은 fetch 처리를 서비스 워커 컨텍스트에 전달하는 진입점입니다.
- 입력
-
request, 요청
fetchController, 가져오기 컨트롤러
useHighResPerformanceTimers, 불리언
- 출력
-
응답 또는 서비스 워커 타이밍 정보
-
registration을 null로 둔다.
-
client를 request의 클라이언트로 둔다.
-
reservedClient를 request의 예약된 클라이언트로 둔다.
-
preloadResponse를 새로운 프로미스로 둔다.
-
workerRealm을 null로 둔다.
-
timingInfo를 새로운 서비스 워커 타이밍 정보로 둔다.
-
단언: request의 대상은 "
serviceworker"가 아니다. -
request의 대상이 "
embed" 또는 "object"이면:-
null을 반환한다.
-
-
그렇지 않고 request가 비하위 리소스 요청이면:
-
reservedClient가 null이 아니며 환경 설정 객체이면:
-
reservedClient가 보안 컨텍스트가 아니면, null을 반환한다.
-
-
그렇지 않으면:
-
request의 URL이 잠재적으로 신뢰할 수 있는 URL이 아니면, null을 반환한다.
-
-
request가 탐색 요청이고 이를 트리거한 탐색이 shift+reload 또는 이에 상응하는 동작으로 시작되었으면, null을 반환한다.
-
reservedClient가 null이 아님을 단언한다.
-
storage key를 reservedClient가 주어졌을 때 스토리지 키를 얻는 알고리즘을 실행한 결과로 둔다.
-
registration을 storage key와 request의 URL이 주어졌을 때 서비스 워커 등록 일치시키기를 실행한 결과로 설정한다.
-
registration이 null이거나 registration의 활성 워커가 null이면, null을 반환한다.
-
request의 대상이
"report"가 아니면, reservedClient의 활성 서비스 워커를 registration의 활성 워커로 설정한다.
참고: 이 시점부터 서비스 워커 클라이언트는 자신의 활성 서비스 워커의 포함 서비스 워커 등록을 사용하기 시작한다.
-
-
그렇지 않고 request가 하위 리소스 요청이면:
-
client의 활성 서비스 워커가 null이 아니면, registration을 client의 활성 서비스 워커의 포함 서비스 워커 등록으로 설정한다.
-
그렇지 않으면, null을 반환한다.
-
-
activeWorker를 registration의 활성 워커로 둔다.
-
다음 중 하나라도 true이면 shouldSoftUpdate를 true로, 그렇지 않으면 false로 둔다.
-
request가 비하위 리소스 요청이다.
-
-
activeWorker의 라우터 규칙 리스트가 비어 있지 않으면:
-
timingInfo의 워커 라우터 평가 시작을 useHighResPerformanceTimers가 주어졌을 때의 정밀도가 낮아진 공유 현재 시간으로 설정한다.
-
source를 registration의 활성 워커와 request를 사용하여 라우터 소스 가져오기 알고리즘을 실행한 결과로 둔다.
-
source가 null이 아니면:
-
timingInfo의 워커와 일치한 라우터 소스를 source로 설정하고, 워커 최종 라우터 소스를
"network"로 설정한다. -
source가
"network"이면: -
그렇지 않고 source가
"cache"이거나, source["cacheName"]이 존재하면:-
shouldSoftUpdate가 true이면, registration을 사용하여 소프트 업데이트 알고리즘을 병렬로 실행한다.
-
timingInfo의 워커 캐시 조회 시작을 useHighResPerformanceTimers가 주어졌을 때의 정밀도가 낮아진 공유 현재 시간으로 설정한다.
-
environment를 null로 둔다.
-
request가 비하위 리소스 요청이면:
-
environment를 reservedClient로 설정한다.
-
-
그렇지 않으면:
-
environment를 client로 설정한다.
-
-
caches를 environment와 "
caches"를 사용하여 로컬 스토리지 보틀 맵을 얻는 알고리즘을 실행한 결과로 둔다. -
caches의 각 cacheName → cache에 대해 반복한다.
-
source["
cacheName"]이 존재하고 source["cacheName"]이 cacheName이 아니면, 계속한다. -
requestResponses를 request, 새로운
CacheQueryOptions, 그리고 cache를 사용하여 캐시 조회를 실행한 결과로 둔다. -
requestResponses가 빈 리스트이면, timingInfo를 반환한다.
-
그렇지 않으면:
-
requestResponse를 requestResponses의 첫 번째 요소로 둔다.
-
response를 requestResponse의 응답으로 둔다.
-
globalObject를 activeWorker의 전역 객체로 둔다.
-
globalObject가 null이면:
-
globalObject를 activeWorker를 사용하여 ServiceWorkerGlobalScope 설정을 실행한 결과로 설정한다.
-
-
globalObject가 null이면, timingInfo를 반환한다.
참고: 이는 CORS 검사에 필요하기 때문에 ServiceWorkerGlobalScope만 생성한다. 구현이 실제로 여기서 ServiceWorkerGlobalScope를 생성할 것으로 예상되지는 않는다.
-
response의 유형이 "
opaque"이고, globalObject의 출처, globalObject, "", 그리고 response의 내부 응답을 사용한 교차 출처 리소스 정책 검사가 blocked를 반환하면, timingInfo를 반환한다. -
timingInfo의 워커 최종 라우터 소스를
"cache"로 설정한다. -
result의 서비스 워커 타이밍 정보를 timingInfo로 설정한다.
-
response를 반환한다.
-
-
-
timingInfo를 반환한다.
-
-
그렇지 않고 source가
"race-network-and-fetch-handler"이고, request의 메서드가 `GET`이면:-
shouldSoftUpdate가 true이면, registration을 사용하여 소프트 업데이트 알고리즘을 병렬로 실행한다.
-
raceFetchController를 null로 둔다.
-
다음 하위 단계를 병렬로 실행한다.
-
fetchController의 상태가 "
terminated" 또는 "aborted"이면, raceResponse를 값이 null인 경쟁 응답으로 설정하고 이 단계를 중단한다. -
raceFetchController를 request가 주어졌을 때 가져오기를 호출한 결과로 설정하되, processResponse는 응답 raceNetworkRequestResponse가 주어졌을 때 다음 단계로 설정한다.
-
-
preloadResponse를 undefined로 이행한다.
-
다음 하위 단계를 병렬로 실행한다.
-
fetchHandlerResponse를 request, registration, useHighResPerformanceTimers, timingInfo, workerRealm, reservedClient, preloadResponse 및 raceResponse를 사용하여 가져오기 이벤트 생성 및 디스패치를 실행한 결과로 둔다.
-
fetchHandlerResponse가 null이 아니고 네트워크 오류도 아니며, raceFetchController가 null이 아니면, raceFetchController를 중단한다.
-
raceFetchHandlerResult를 라우팅된 응답이 fetchHandlerResponse이고 사용된 경로가
"fetch-event"인 경쟁 결과로 둔다. -
raceFetchHandlerResult를 queue에 큐에 넣는다.
-
-
queue가 비어 있지 않을 때까지 기다린다.
-
result를 queue에서 큐에서 꺼낸 결과로 둔다.
-
routedResponse를 result의 라우팅된 응답으로 둔다.
-
routedResponse가 null이면:
-
timingInfo를 반환한다.
-
-
-
routedResponse의 서비스 워커 타이밍 정보를 timingInfo로 설정한다.
-
-
routedResponse의 서비스 워커 타이밍 정보의 워커 최종 라우터 소스를 result의 사용된 경로로 설정한다.
-
routedResponse를 반환한다.
-
-
단언: source는 "
fetch-event"이다.
-
-
-
responseForAutoPreload를 null로 둔다.
-
request가 탐색 요청이고, request의 메서드가 `
GET`이며, registration의 활성 워커의 처리할 이벤트 유형 집합에fetch가 포함되어 있고, registration의 활성 워커의 모든 가져오기 리스너가 비어 있음 플래그가 설정되어 있지 않으면:-
registration의 탐색 미리 로드 활성화 플래그가 설정되어 있으면:
참고: 위 조건 중 registration의 활성 워커의 처리할 이벤트 유형 집합에
fetch가 포함되지 않는다는 점만 제외하고 모두 true이면, 개발자의 의도가 명확하지 않으므로 사용자 에이전트는 콘솔 경고를 표시할 수 있다.-
preloadRequest를 요청 request를 복제한 결과로 둔다.
-
preloadRequestHeaders를 preloadRequest의 헤더 리스트로 둔다.
-
preloadResponseObject를 가드가 "
immutable"인 새로운Headers객체와 연결된 새로운Response객체로 둔다. -
preloadRequestHeaders에 이름이 `
Service-Worker-Navigation-Preload`이고 값이 registration의 탐색 미리 로드 헤더 값인 새로운 헤더를 추가한다. -
preloadRequest의 서비스 워커 모드를 "
none"으로 설정한다. -
preloadFetchController를 null로 둔다.
-
다음 하위 단계를 병렬로 실행하되, fetchController의 상태가 "
terminated" 또는 "aborted"이면 중단한다.-
preloadFetchController를 preloadRequest를 가져온 결과로 설정한다.
navigationPreloadResponse에 대한 processResponse로서 다음 하위 단계를 실행한다.
-
navigationPreloadResponse의 유형이 "
error"이면, preloadResponse를TypeError로 거부하고 이 하위 단계를 종료한다. -
preloadResponseObject를 navigationPreloadResponse와 연결한다.
-
preloadResponse를 preloadResponseObject로 이행한다.
-
-
-
-
deserializedError를 null과 workerRealm이 주어졌을 때 직렬화된 중단 이유를 역직렬화한 결과로 둔다.
-
deserializedError를 사용하여 preloadFetchController를 중단한다.
-
-
-
그렇지 않고 timingInfo의 워커와 일치한 라우터 소스가 "
fetch-event"가 아니면, 사용자 에이전트는 다음 하위 단계를 실행할 수 있다.참고: 사용자 에이전트는 부트스트랩 비용을 최소화하기 위해 가져오기 이벤트를 생성하는 작업과 병렬로 네트워크 요청을 추측적으로 디스패치할 수 있다.
-
단언: timingInfo의 워커와 일치한 라우터 소스는 null이다.
-
autoPreloadFetchController를 null로 둔다.
-
다음 하위 단계를 병렬로 실행하되, fetchController의 상태가 "
terminated" 또는 "aborted"이면 중단한다.-
autoPreloadFetchController를 request가 주어졌을 때 가져오기를 호출한 결과로 설정하되, processResponse는 응답 autoPreloadRequestResponse가 주어졌을 때 다음 단계로 설정한다.
-
responseForAutoPreload의 값을 autoPreloadRequestResponse로 설정한다.
-
-
-
중단되었고 autoPreloadFetchController가 null이 아니면:
-
preloadResponse를 undefined로 이행한다.
-
-
-
그렇지 않으면, preloadResponse를 undefined로 이행한다.
-
fetchResult를 request, registration, useHighResPerformanceTimers, timingInfo, workerRealm, reservedClient, preloadResponse 및 responseForAutoPreload를 사용하여 가져오기 이벤트 생성 및 디스패치를 실행한 결과로 둔다.
-
timingInfo의 워커 최종 라우터 소스가 빈 문자열이 아니면:
-
timingInfo의 워커 최종 라우터 소스가
"network"임을 단언한다. -
fetchResult가 null이면, timingInfo를 반환한다.
-
그렇지 않으면:
-
fetchResult의 서비스 워커 타이밍 정보의 워커 최종 라우터 소스가
"network"임을 단언한다. -
fetchResult의 서비스 워커 타이밍 정보의 워커 최종 라우터 소스를
"fetch-event"로 설정한다.
-
-
-
fetchResult를 반환한다.
Fetch 이벤트 생성 및 디스패치
- 입력
-
request, 요청
registration, 서비스 워커 등록
useHighResPerformanceTimers, 불리언
timingInfo, 서비스 워커 타이밍 정보
reservedClient, 예약된 클라이언트
preloadResponse, 프로미스
raceResponse, 경쟁 응답 또는 null
- 출력
-
응답 또는 null
-
response를 null로 둔다.
-
eventCanceled를 false로 둔다.
-
client를 request의 클라이언트로 둔다.
-
activeWorker를 registration의 활성 워커로 둔다.
-
eventHandled를 null로 둔다.
-
handleFetchFailed를 false로 둔다.
-
respondWithEntered를 false로 둔다.
-
networkError를 네트워크 오류로 둔다.
-
raceResponse가 null이 아니면:
-
networkError의 서비스 워커 타이밍 정보를 timingInfo로 설정한다.
-
-
다음 중 하나라도 true이면 shouldSoftUpdate를 true로, 그렇지 않으면 false로 둔다.
-
request가 비하위 리소스 요청이다.
-
-
"fetch"와 activeWorker를 사용하여 이벤트를 건너뛰어야 하는지 판단 알고리즘을 실행한 결과가 true이면:
-
activeWorker의 모든 가져오기 리스너가 비어 있음 플래그가 설정되어 있으면:
-
useHighResPerformanceTimers가 true이면, useHighResPerformanceTimers를 activeWorker의 전역 객체의 교차 출처 격리 기능으로 설정한다.
-
timingInfo의 시작 시간을 useHighResPerformanceTimers가 주어졌을 때의 정밀도가 낮아진 공유 현재 시간으로 둔다.
-
activeWorker의 상태가 "
activating"이면, activeWorker의 상태가 "activated"가 될 때까지 기다린다. -
activeWorker를 사용하여 서비스 워커 실행 알고리즘을 실행한 결과가 실패이면, handleFetchFailed를 true로 설정한다.
-
그렇지 않으면:
-
eventHandled를 workerRealm의 새 프로미스로 설정한다.
-
raceResponse가 null이 아니면, activeWorker의 전역 객체의 경쟁 응답 맵[request]을 raceResponse로 설정한다.
-
다음 하위 단계를 실행하는 task 태스크를 큐에 넣는다.
-
e를
FetchEvent로 이벤트를 생성한 결과로 둔다. -
abortController를 workerRealm을 사용하는 새
AbortController객체로 둔다. -
requestObject를 request, 가드가 "
immutable"인 새Headers객체, abortController의 신호, 그리고 workerRealm이 주어졌을 때Request객체를 생성한 결과로 둔다. -
e의
cancelable속성을 true로 초기화한다. -
e의
request속성을 requestObject로 초기화한다. -
e의
preloadResponse를 preloadResponse로 초기화한다. -
request가 비하위 리소스 요청이고, request의 대상이
"report"가 아니며, reservedClient가 null이 아니면, e의resultingClientId속성을 reservedClient의 ID로 초기화한다. -
request가 탐색 요청이면, e의
replacesClientId속성을 request의 대체하는 클라이언트 ID로 초기화한다. -
e의
handled를 eventHandled로 초기화한다. -
timingInfo의 가져오기 이벤트 디스패치 시간을 useHighResPerformanceTimers가 주어졌을 때의 정밀도가 낮아진 공유 현재 시간으로 둔다.
-
activeWorker와 e를 사용하여 서비스 워커 연장 이벤트 집합 업데이트를 호출한다.
-
e의 respond-with 진입 플래그가 설정되어 있으면, respondWithEntered를 true로 설정한다.
-
e의 응답 대기 플래그가 설정되어 있으면:
-
e의 응답 대기 플래그가 해제될 때까지 기다린다.
-
e의 respond-with 오류 플래그가 설정되어 있으면, handleFetchFailed를 true로 설정한다.
-
그렇지 않으면, response를 e의 잠재적 응답으로 설정한다.
-
-
response가 null이고, request의 본문이 null이 아니며, request의 본문의 소스가 null이면:
-
response가 null이 아니면, response의 서비스 워커 타이밍 정보를 timingInfo로 설정한다.
-
e의 취소됨 플래그가 설정되어 있으면, eventCanceled를 true로 설정한다.
-
fetchController의 상태가 "
terminated" 또는 "aborted"이면:-
deserializedError를 fetchController의 직렬화된 중단 이유와 workerRealm이 주어졌을 때 직렬화된 중단 이유를 역직렬화한 결과로 둔다.
-
deserializedError를 사용하여 abortController에서 중단을 신호하도록 태스크를 큐에 넣는다.
-
task가 폐기되면, handleFetchFailed를 true로 설정한다.
task는 activeWorker의 이벤트 루프와 가져오기 처리 태스크 소스를 사용해야 한다.
-
-
task가 실행되거나 handleFetchFailed가 true가 될 때까지 기다린다.
-
shouldSoftUpdate가 true이면, registration을 사용하여 소프트 업데이트 알고리즘을 병렬로 실행한다.
-
activeWorker의 전역 객체의 경쟁 응답 맵[request]이 존재하면, activeWorker의 전역 객체의 경쟁 응답 맵[request]을 제거한다.
-
respondWithEntered가 false이면:
-
eventCanceled가 true이면:
-
eventHandled가 null이 아니면, workerRealm에서 "
NetworkError"DOMException으로 eventHandled를 거부한다. -
networkError를 반환한다.
-
-
eventHandled가 null이 아니면, eventHandled를 이행한다.
-
raceResponse가 null이 아니고, raceResponse의 값이 null이 아니면:
-
null을 반환한다.
-
-
handleFetchFailed가 true이면:
-
eventHandled가 null이 아니면, workerRealm에서 "
NetworkError"DOMException으로 eventHandled를 거부한다. -
networkError를 반환한다.
-
-
eventHandled가 null이 아니면, eventHandled를 이행한다.
-
response를 반환한다.
URL 패턴 파싱
- 입력
-
rawPattern,
URLPatternCompatibleserviceWorker, 서비스 워커
- 출력
-
baseURL을 serviceWorker의 스크립트 URL로 둔다.
-
rawPattern과 baseURL을 인자로 하여 Web IDL 값으로부터 URL 패턴 생성 알고리즘을 실행한 결과를 반환한다.
라우터 조건 검증
- 입력
-
condition,
RouterConditionserviceWorker, 서비스 워커
- 출력
-
불리언 값
-
hasCondition을 false로 둔다.
-
condition["
urlPattern"] 존재하면:-
rawPattern을 condition["
urlPattern"]로 둔다. -
pattern을 URL 패턴 파싱 알고리즘을 rawPattern, serviceWorker로 실행한 결과로 둔다. 만약 예외가 발생하면 false를 반환한다.
-
pattern이 정규식 그룹을 포함하면 false를 반환한다.
참고: 사용자 정의 정규식을 실행하는 것은 보안상 문제이므로 금지된다.
-
hasCondition을 true로 설정한다.
-
-
condition["
requestMethod"] 존재하면:-
method을 condition["
requestMethod"]로 둔다. -
method가 method가 아니면 false를 반환한다.
-
method가 금지된 method이면 false를 반환한다.
-
hasCondition을 true로 설정한다.
-
-
condition["
requestMode"] 존재하면 hasCondition을 true로 설정한다. -
condition["
requestDestination"] 존재하면 hasCondition을 true로 설정한다. -
condition["
runningStatus"] 존재하면 hasCondition을 true로 설정한다. -
hasCondition을 반환한다.
라우터 조건 매칭
- 입력
-
condition,
RouterConditionserviceWorker, 서비스 워커
request, request
- 출력
-
불리언 값
참고: 여러 조건(e.g. urlPattern,
runningStatus, requestMethod 등이 설정된 경우), 모든 조건이 일치해야 true를 반환한다.
-
그 외에는:
참고: 라우터 조건 검증 알고리즘이
or,not과 다른 조건이 상호 배타적임을 보장한다.-
condition["
urlPattern"] 존재하면:-
rawPattern을 condition["
urlPattern"]로 둔다. -
pattern을 URL 패턴 파싱 알고리즘을 rawPattern, serviceWorker로 실행한 결과로 둔다.
-
match 알고리즘을 pattern, request의 URL로 실행한 결과가 null이면 false를 반환한다.
-
-
condition["
requestMethod"] 존재하면:-
method을 condition["
requestMethod"]로 둔다. -
method 정규화를 method로 실행한다.
-
request의 method가 method와 다르면 false를 반환한다.
-
-
condition["
requestMode"] 존재하면:-
mode을 condition["
requestMode"]로 둔다. -
request의 mode가 mode와 다르면 false를 반환한다.
-
-
condition["
requestDestination"] 존재하면:-
destination을 condition["
requestDestination"]로 둔다. -
request의 destination이 destination과 다르면 false를 반환한다.
-
-
condition["
runningStatus"] 존재하면:-
runningStatus을 condition["
runningStatus"]로 둔다. -
runningStatus가
"running"이고, serviceWorker가 실행 중이 아니면 false를 반환한다. -
runningStatus가
"not-running"이고, serviceWorker가 실행 중이면 false를 반환한다.
-
-
true를 반환한다.
-
라우터 등록 제한 검사
- 입력
-
routerRules, 라우터 규칙 리스트
- 출력
-
불리언 값
참고: 라우터 조건은 _or와
not을
사용하여 복잡하게 중첩될 수 있습니다.
과도한 처리를 방지하기 위해, 이 알고리즘은 두 가지 제한을 둡니다. 첫째, 중첩된 모든 조건을 합한 총 조건 수는 1024를 초과할 수 없습니다. 둘째, 중첩 깊이는 10단계로
제한하여 계산량이 지수적으로 증가하는 것을 막습니다.
-
result를 라우터 조건 카운트 결과로 둔다.
-
result의 condition count를 1024로 설정한다.
-
result의 quota exceeded를 false로 설정한다.
-
각 rule을 routerRules에서 반복하여:
-
result를 내부 라우터 조건 카운트 알고리즘을 rule["
condition"], result, 10으로 실행한 결과로 둔다. -
result의 quota exceeded가 true면 false를 반환한다.
-
-
true를 반환한다.
내부 라우터 조건 카운트
- 입력
-
condition,
RouterConditionresult, 라우터 조건 카운트 결과
depth, 숫자
- 출력
-
result, 라우터 조건 카운트 결과
-
result의 condition count를 1 감소시킨다.
-
result의 condition count가 0이거나, depth가 0이면:
-
result의 quota exceeded를 true로 설정한다.
-
result를 반환한다.
-
-
-
depth를 1 감소시킨다.
-
condition["
_or"]의 각 orCondition에 대해:-
result를 내부 라우터 조건 카운트 알고리즘을 orCondition, result, depth로 실행한 결과로 둔다.
-
result의 quota exceeded가 true면 result를 반환한다.
-
-
-
-
depth를 1 감소시킨다.
-
result를 내부 라우터 조건 카운트 알고리즘을 condition["
not"], result, depth로 실행한 결과로 둔다. -
result의 quota exceeded가 true면 result를 반환한다.
-
-
result를 반환한다.
라우터 소스 확인
- 입력
-
serviceWorker, 서비스 워커
request, request
- 출력
-
RouterSource또는 null
-
각 rule을 serviceWorker의 라우터 규칙 리스트에서 반복하여:
-
null을 반환한다.
이벤트 생략 여부
- 입력
-
eventName, 문자열
serviceWorker, 서비스 워커
- 출력
-
불리언 값
참고: 불필요한 지연을 피하기 위해, 이 표준은 서비스 워커의 글로벌에서 이벤트 리스너가 최초 스크립트 실행 시 결정적으로 추가되지 않은 경우 이벤트 디스패치를 생략할 수 있도록 허용합니다.
-
serviceWorker의 처리할 이벤트 타입 집합에 eventName이 포함되지 않으면, 사용자 에이전트는 true를 반환할 수 있습니다.
-
false를 반환한다.
Fire Functional Event
- 입력
-
eventName, 문자열
eventConstructor,
ExtendableEvent를 확장하는 이벤트 생성자registration, service worker registration
initialization, 선택적 event 속성 초기화, eventConstructor로부터 생성됨
postDispatchSteps, active worker의 이벤트 루프에서 실행할 선택적 단계들, 이때 dispatchedEvent는 eventConstructor의 인스턴스로 dispatched된 것
- 출력
-
없음
-
명제: registration의 active worker는 null이 아니다.
-
activeWorker를 registration의 active worker로 둔다.
-
If eventName와 activeWorker로 Should Skip Event를 실행한 결과가 true이면:
-
만약 registration이 stale라면, 병렬로 Soft Update 알고리즘을 registration에 대해 실행한다.
-
반환한다.
-
-
만약 activeWorker의 state가 "
activating"이면, activeWorker의 state가 "activated"가 될 때까지 기다린다. -
Run Service Worker 알고리즘을 activeWorker로 실행한 결과가 failure이면:
-
만약 registration이 stale라면, 병렬로 Soft Update 알고리즘을 registration에 대해 실행한다.
-
반환한다.
-
-
Task를 큐하여 다음 하위 단계를 실행하도록 한다:
-
event를 이벤트 생성의 결과로, eventConstructor와 activeWorker의 global object의 relevant realm을 사용해 생성한다.
-
만약 initialization가 null이 아니면, event를 initialization으로 초기화한다.
-
Dispatch event를 activeWorker의 global object에서 실행한다.
-
Update Service Worker Extended Events Set를 activeWorker와 event에 대해 호출한다.
-
만약 postDispatchSteps가 null이 아니면, postDispatchSteps를 event를 dispatchedEvent로 하여 실행한다.
이 task는 반드시 activeWorker의 event loop와 handle functional event task source를 사용해야 한다.
-
-
task가 실행되었거나 폐기될 때까지 기다린다.
-
만약 registration가 stale라면, 병렬로 Soft Update 알고리즘을 registration에 대해 실행한다.
amazingthing" 이벤트(타입은
AmazingThingEvent)를 발동하고 이벤트 객체의 속성을 초기화하려면, 절차는 다음과 같다:
-
Fire Functional Event "
amazingthing"를AmazingThingEvent를 사용하여 serviceWorkerRegistration에 대해 다음 속성으로 실행한다:- propertyName
-
value
- anotherPropertyName
-
anotherValue
그런 다음 dispatchedEvent로 다음 단계를 실행한다:
-
dispatchedEvent로 서비스 워커의 이벤트 루프에서 필요한 작업을 수행한다.
초기화 단계와 포스트 디스패치 단계는 선택 사항이다. 필요하지 않다면, 절차는 다음과 같다:
-
Fire Functional Event "
whatever"를ExtendableEvent를 사용하여 serviceWorkerRegistration에 대해 실행한다.
Handle Service Worker Client Unload
사용자 에이전트는 서비스 워커 클라이언트가 문서 언로드 정리 단계 또는 종료를 통해 언로드될 때의 일부로 이 단계를 실행해야 한다.
- 입력
-
client, 서비스 워커 클라이언트
- 출력
-
없음
Handle User Agent Shutdown
- 입력
-
없음
- 출력
-
없음
-
For each registration of registration map’s values:
-
만약 registration의 installing worker가 null이 아니면:
-
만약 registration의 waiting worker가 null이고 registration의 active worker가 null이면, Clear Registration을 registration에 대해 호출하고 루프의 다음 반복으로 계속한다.
-
그렇지 않으면 registration의 installing worker를 null로 설정한다.
-
-
만약 registration의 waiting worker가 null이 아니면, 병렬로:
-
Activate를 registration에 대해 호출한다.
-
-
Update Service Worker Extended Events Set
- 입력
-
worker, service worker입니다.
event,
ExtendableEvent입니다. - 출력
-
없음
-
명제: event의 dispatch flag가 unset이다.
-
각 item에 대해 worker의 set of extended events:
-
만약 item이 active가 아니면, remove item를 worker의 set of extended events에서 제거한다.
-
-
만약 event가 active이면, append event를 worker의 set of extended events에 추가한다.
Unregister
- 입력
-
job은 작업이다.
- 출력
-
없음
-
registration이 null이면:
-
작업 프로미스 해결을 job과 false로 호출한다.
-
작업 완료를 job과 함께 호출하고, 여기서 이 과정을 중단한다.
-
-
작업 프로미스 해결을 job과 true로 호출한다.
-
등록 비우기 시도를 registration과 함께 호출한다.
참고: 등록 비우기 시도가 여기서 등록 비우기를 트리거하지 않으면, 마지막 클라이언트가 등록을 사용하다가 언로드되거나 등록의 서비스 워커에 대한 수명 연장 프로미스가 완료될 때 다시 시도된다.
-
작업 완료를 job과 함께 호출한다.
Set Registration
- 입력
-
storage key, storage key
scope, URL
updateViaCache, update via cache mode
- 출력
-
registration, service worker registration
-
다음 단계를 원자적으로 실행한다.
-
scopeString를 serialized scope로, exclude fragment flag를 설정한 상태로 둔다.
-
registration를 새로운 service worker registration로 생성한다. 이 객체의 storage key는 storage key, scope url는 scope, update via cache mode는 updateViaCache로 설정한다.
-
Set registration map[(storage key, scopeString)]을 registration로 설정한다.
-
반환한다: registration.
Clear Registration
- 입력
-
registration, service worker registration
- 출력
-
없음
-
다음 단계를 원자적으로 실행한다.
-
만약 registration의 installing worker가 null이 아니면:
-
Terminate registration의 installing worker를 실행한다.
-
Update Worker State 알고리즘을 registration의 installing worker와 "
redundant"로 실행한다. -
Update Registration State 알고리즘을 registration, "
installing", null로 실행한다.
-
-
만약 registration의 waiting worker가 null이 아니면:
-
Terminate registration의 waiting worker를 실행한다.
-
Update Worker State 알고리즘을 registration의 waiting worker와 "
redundant"로 실행한다. -
Update Registration State 알고리즘을 registration, "
waiting", null로 실행한다.
-
-
만약 registration의 active worker가 null이 아니면:
-
Terminate registration의 active worker를 실행한다.
-
Update Worker State 알고리즘을 registration의 active worker와 "
redundant"로 실행한다. -
Update Registration State 알고리즘을 registration, "
active", null로 실행한다.
-
Try Clear Registration
- 입력
-
registration, service worker registration
- 출력
-
없음
-
Clear Registration을 registration에 대해 호출하라 단, 어떠한 service worker client도 registration를 사용하고 있지 않고 아래 모든 조건이 참일 때:
-
registration의 installing worker가 null이거나, Service Worker Has No Pending Events를 registration의 installing worker로 실행한 결과가 true일 것.
-
registration의 waiting worker가 null이거나, Service Worker Has No Pending Events를 registration의 waiting worker로 실행한 결과가 true일 것.
-
registration의 active worker가 null이거나, Service Worker Has No Pending Events를 registration의 active worker로 실행한 결과가 true일 것.
-
Update Registration State
- 입력
-
registration, service worker registration
target, 문자열 ( "
installing", "waiting", "active" 중 하나)source, service worker 또는 null
- 출력
-
없음
-
registrationObjects를 registration과 연결된 모든
ServiceWorkerRegistration객체를 포함하는 배열로 설정한다. -
target이 "
installing"이면, 다음을 수행한다:-
registration의 설치 중인 워커를 source로 설정한다.
-
registrationObjects의 각 registrationObject에 대해:
-
registration의 설치 중인 워커가 null이면 registrationObject의
installing속성을 null로 설정하고, 그렇지 않으면 registrationObject의 관련 설정 객체에서 registration의 설치 중인 워커를 나타내는 서비스 워커 객체를 가져온 결과로 설정하도록 태스크를 큐에 넣는다.
-
-
-
그렇지 않고 target이 "
waiting"이면:-
registration의 대기 중인 워커를 source로 설정한다.
-
registrationObjects의 각 registrationObject에 대해:
-
태스크를 큐에 추가하여, registration의 대기 중인 워커가 null이면 registrationObject의
waiting속성을 null로 설정하고, 그렇지 않으면 registrationObject의 관련 설정 객체에서 registration의 대기 중인 워커를 나타내는 서비스 워커 객체를 가져온 결과로 설정한다.
-
-
-
그렇지 않고 target이 "
active"이면:-
registration의 활성 워커를 source로 설정한다.
-
registrationObjects의 각 registrationObject에 대해:
-
태스크를 큐에 추가하여, registration의 활성 워커가 null이면 registrationObject의
active속성을 null로 설정하고, 그렇지 않으면 registrationObject의 관련 설정 객체에서 registration의 활성 워커를 나타내는 서비스 워커 객체를 가져온 결과로 설정한다.
-
태스크는 반드시 registrationObject의 관련 설정 객체의 담당 이벤트 루프와 DOM 조작 태스크 소스를 사용해야 한다.
-
Update Worker State
- 입력
-
worker, service worker
state, service worker의 state
- 출력
-
없음
-
단언: state는 "
parsed"가 아니다.참고: "
parsed"는 초기 상태이다. 서비스 워커는 이 상태로 업데이트되는 일이 없다. -
worker의 상태를 state로 설정한다.
-
settingsObjects를 환경 설정 객체 중 그 출처가 worker의 스크립트 URL의 출처인 모든 객체로 둔다.
-
settingsObjects의 각 settingsObject에 대해, settingsObject의 담당 이벤트 루프에서 DOM 조작 태스크 소스를 사용하여 다음 단계를 실행하도록 태스크를 큐에 추가한다:
-
objectMap을 settingsObject의 서비스 워커 객체 맵으로 둔다.
-
objectMap[worker]이 존재하지 않으면, 이 단계들을 중단한다.
-
workerObj를 objectMap[worker]으로 둔다.
-
workerObj의
state를 state로 설정한다. -
workerObj에서
statechange라는 이름의 이벤트를 발생시킨다.
-
Notify Controller Change
- 입력
-
client, 서비스 워커 클라이언트
- 출력
-
없음
-
단언: client는 null이 아니다.
-
client가 환경 설정 객체이면, client가 연결된
ServiceWorkerContainer객체에서controllerchange라는 이름의 이벤트를 발생시키도록 태스크를 큐에 추가한다.
태스크는 반드시 client의 담당 이벤트 루프와 DOM 조작 태스크 소스를 사용해야 한다.
Match Service Worker Registration
- 입력
-
storage key, storage key
clientURL, URL
- 출력
-
다음 단계를 원자적으로 실행한다.
-
clientURLString를 serialized clientURL로 둔다.
-
matchingScopeString를 빈 문자열로 둔다.
-
scopeStringSet를 빈 목록으로 둔다.
-
For each (entry storage key, entry scope) of registration map’s keys:
-
matchingScopeString를 scopeStringSet 중 clientURLString이 시작하는 가장 긴 값으로 설정한다(존재하면).
참고: 이 단계의 URL 문자열 매칭은 경로 구조 기반이 아닌 접두사 기반이다. 예: 클라이언트 URL 문자열 "https://example.com/prefix-of/resource.html"은 "https://example.com/prefix"로 설정된 scope와 매치된다. URL 문자열 비교는 동일 출처 보안에 안전하다: HTTP(S) URL은 항상 origin 부분 끝에 슬래시가 붙은 형태로 serialized된다.
-
matchingScope를 null로 둔다.
-
만약 matchingScopeString가 빈 문자열이 아니면:
-
matchingScope를 parsing matchingScopeString의 결과로 둔다.
-
명제: matchingScope의 origin과 clientURL의 origin는 same origin이다.
-
-
Get Registration를 storage key와 matchingScope로 실행한 결과를 반환한다.
Get Registration
- 입력
-
storage key, storage key
scope, URL
- 출력
-
다음 단계를 원자적으로 실행한다.
-
scopeString를 빈 문자열로 둔다.
-
만약 scope가 null이 아니면, scopeString를 serialized scope로, exclude fragment flag를 설정한 상태로 둔다.
-
For each (entry storage key, entry scope) → registration of registration map:
-
만약 storage key가 entry storage key와 equals하고 scopeString가 entry scope와 매치되면, registration을 반환한다.
-
-
null을 반환한다.
Get Newest Worker
- 입력
-
registration, service worker registration
- 출력
-
newestWorker, service worker
-
다음 단계를 원자적으로 실행한다.
-
newestWorker를 null로 둔다.
-
만약 registration의 installing worker가 null이 아니면 newestWorker를 그 installing worker로 설정한다.
-
그렇지 않으면 만약 registration의 waiting worker가 null이 아니면 newestWorker를 그 waiting worker로 설정한다.
-
그렇지 않으면 만약 registration의 active worker가 null이 아니면 newestWorker를 그 active worker로 설정한다.
-
newestWorker를 반환한다.
Service Worker Has No Pending Events
- 입력
-
worker, service worker
- 출력
-
True 또는 False, 불리언
-
worker의 set of extended events의 각 event에 대해:
-
만약 event가 active이면 false를 반환한다.
-
-
true를 반환한다.
Create Client
- 입력
-
client, service worker client
- 출력
-
clientObject,
Client객체
-
clientObject를 새로운
Client객체로 둔다. -
clientObject의 service worker client를 client로 설정한다.
-
clientObject를 반환한다.
Create Window Client
- 입력
-
client, service worker client
frameType, 문자열
visibilityState, 문자열
focusState, 불리언
ancestorOriginsList, 목록
- 출력
-
windowClient,
WindowClient객체
-
windowClient를 새로운
WindowClient객체로 둔다. -
windowClient의 service worker client를 client로 설정한다.
-
windowClient의 frame type을 frameType으로 설정한다.
-
windowClient의 visibility state를 visibilityState로 설정한다.
-
windowClient의 focus state를 focusState로 설정한다.
-
windowClient의 ancestor origins array를 ancestorOriginsList로부터 생성된 frozen array로 설정한다.
-
반환한다: windowClient.
Get Frame Type
- 입력
-
navigable, navigable
- 출력
-
frameType, 문자열
-
만약 navigable의 parent가 null이 아니면, "
nested"를 반환한다. -
만약 navigable의 active browsing context가 auxiliary browsing context이면 "
auxiliary"를 반환한다. -
"
top-level"를 반환한다.
Resolve Get Client Promise
- 입력
-
client, service worker client
promise, promise
- 출력
-
없음
-
client가 환경 설정 객체이면:
-
client가 보안 컨텍스트가 아니면, promise의 관련 설정 객체의 담당 이벤트 루프에서 DOM 조작 태스크 소스를 사용하여 promise를 "
SecurityError"DOMException으로 거부하도록 태스크를 큐에 추가하고, 이 단계들을 중단한다.
-
-
그렇지 않으면:
-
client의 생성 URL이 잠재적으로 신뢰할 수 있는 URL이 아니면, promise의 관련 설정 객체의 담당 이벤트 루프에서 DOM 조작 태스크 소스를 사용하여 promise를 "
SecurityError"DOMException으로 거부하도록 태스크를 큐에 추가하고, 이 단계들을 중단한다.
-
-
client가 환경 설정 객체이고 윈도우 클라이언트가 아니면:
-
clientObject를 client를 인수로 사용하여 클라이언트 생성 알고리즘을 실행한 결과로 둔다.
-
promise의 관련 설정 객체의 담당 이벤트 루프에서 DOM 조작 태스크 소스를 사용하여 promise를 clientObject로 이행하도록 태스크를 큐에 추가하고, 이 단계들을 중단한다.
-
-
그렇지 않으면:
-
browsingContext를 null로 둔다.
-
client가 환경 설정 객체이면, browsingContext를 client의 전역 객체의 브라우징 컨텍스트로 설정한다.
-
그렇지 않으면, browsingContext를 client의 대상 브라우징 컨텍스트로 설정한다.
-
navigable을 browsingContext를 활성 브라우징 컨텍스트로 갖는 내비게이터블로 둔다.
-
browsingContext의 이벤트 루프에서 사용자 상호작용 태스크 소스를 사용하여 다음 단계를 실행하도록 태스크를 큐에 추가한다:
-
frameType을 navigable을 사용하여 프레임 유형 가져오기를 실행한 결과로 둔다.
-
visibilityState를 browsingContext의 활성 문서의
visibilityState속성 값으로 둔다. -
focusState를 browsingContext의 활성 문서를 인수로 사용하여 포커스 보유 단계를 실행한 결과로 둔다.
-
ancestorOriginsList를 빈 목록으로 둔다.
-
client가 윈도우 클라이언트이면, ancestorOriginsList를 browsingContext의 활성 문서의 상위 출처 목록에 연결된 목록으로 설정한다.
-
promise의 관련 설정 객체의 담당 이벤트 루프에서 DOM 조작 태스크 소스를 사용하여 다음 단계를 실행하도록 태스크를 큐에 추가한다:
-
client의 폐기됨 플래그가 설정되어 있으면, promise를 undefined로 이행하고 이 단계들을 중단한다.
-
windowClient를 client, frameType, visibilityState, focusState, ancestorOriginsList를 사용하여 윈도우 클라이언트 생성을 실행한 결과로 둔다.
-
promise를 windowClient로 이행한다.
-
-
-
Query Cache
- 입력
-
requestQuery, request
options, 선택적
CacheQueryOptions객체targetStorage, 선택적 request response list
- 출력
-
resultList, request response list
-
resultList를 빈 list로 둔다.
-
storage를 null로 둔다.
-
만약 선택 인자 targetStorage가 생략되었으면 storage를 relevant request response list로 설정한다.
-
그렇지 않으면 storage를 targetStorage로 설정한다.
-
For each requestResponse of storage:
-
cachedRequest를 requestResponse의 request로 둔다.
-
cachedResponse를 requestResponse의 response로 둔다.
-
만약 Request Matches Cached Item를 requestQuery, cachedRequest, cachedResponse, options로 실행한 결과가 true이면:
-
requestCopy를 cachedRequest의 복사로 둔다.
-
responseCopy를 cachedResponse의 복사로 둔다.
-
requestCopy/responseCopy를 resultList에 추가한다.
-
-
-
resultList를 반환한다.
Request Matches Cached Item
- 입력
-
requestQuery, 요청
request, 요청
response, 응답 또는 null, 선택 사항, 기본값은 null
options,
CacheQueryOptions객체, 선택 사항 - 출력
-
불리언
-
만약 options["
ignoreMethod"] 가 false이고 request의 method가 `GET`이 아니면 false를 반환한다. -
queryURL를 requestQuery의 url로 둔다.
-
cachedURL를 request의 url로 둔다.
-
만약 options["
ignoreSearch"] 가 true이면: -
만약 queryURL가 equal하지 않으면( exclude fragment flag를 설정한 상태에서 ) false를 반환한다.
-
만약 response가 null이거나, options["
ignoreVary"] 가 true이거나, response의 header list가 `Vary`를 포함하지 않으면 true를 반환한다. -
fieldValues를 list로, response의 `
Vary` 헤더의 field-values에 해당하는 요소들로 채운다. -
fieldValues의 각 fieldValue에 대해:
-
만약 fieldValue가 "
*"와 매치되거나, fieldValue로부터 계산된 combined value가 request의 header list와 매치되지 않거나, requestQuery의 header list로부터 계산된 combined value와 일치하지 않으면 false를 반환한다.
-
-
true를 반환한다.
Batch Cache Operations
- 입력
-
operations, list of cache batch operation 객체들
- 출력
-
resultList, request response list
-
cache를 relevant request response list로 둔다.
-
backupCache를 request response list의 새 복사본으로 둔다.
-
addedItems를 빈 list로 둔다.
-
다음 하위 단계를 원자적으로 시도한다:
-
resultList를 빈 list로 둔다.
-
For each operation in operations:
-
만약 operation의 type이 "
delete"도 "put"도 아니면, throwTypeError를 발생시킨다. -
만약 operation의 type이 "
delete"이고 operation의 response가 null이 아니면, throwTypeError를 발생시킨다. -
Query Cache를 operation의 request, operation의 options, 그리고 addedItems로 실행한 결과가 비어 있지 않으면, throw "
InvalidStateError"DOMException를 발생시킨다. -
requestResponses를 빈 list로 둔다.
-
만약 operation의 type이 "
delete"이면: -
그렇지 않으면 만약 operation의 type이 "
put"이면:-
만약 r의 url의 scheme이 "
http" 또는 "https"가 아니면, throwTypeError를 발생시킨다. -
requestResponses를 Query Cache를 operation의 request로 실행한 결과로 둔다.
-
For each requestResponse of requestResponses:
-
만약 이전 두 단계의 캐시 쓰기 작업이 할당된 쿼터 한도를 초과하여 실패하면, throw
QuotaExceededError를 발생시킨다. -
Append operation의 request/operation의 response를 addedItems에 추가한다.
-
Append operation의 request/operation의 response를 resultList에 추가한다.
-
-
resultList를 반환한다.
-
-
만약 위에서 예외가 thrown되었다면, 다음을 실행한다:
-
Remove items을 모두 relevant request response list에서 제거한다.
-
For each requestResponse of backupCache:
-
Append requestResponse를 relevant request response list에 추가한다.
-
-
Throw 예외를 다시 던진다.
참고: 예외가 thrown될 때, 구현은 배치 작업 중에 캐시 저장소에 대해 수행한 변경 사항을 되돌린다(롤백)한다.
-
Is Async Module
- 입력
-
record, Module Record
moduleMap, module map
base, URL
- 출력
-
불리언
-
만약 record가 Cyclic Module Record가 아니면:
-
false를 반환한다.
-
-
만약 record.[[Async]]가 true이면:
-
true를 반환한다.
-
-
For each 문자열 requested of record.[[RequestedModules]]에 대해:
-
url를 resolving a module specifier를 base와 requested로 실행한 결과로 둔다.
-
명제: url는 절대 failure가 아니다. 왜냐하면 동일한 두 인자로 이미 모듈 스페시파이어 해석이 성공적이었기 때문이다.
-
만약 seen이 url을 포함하지 않으면:
-
Append url을 seen에 추가한다.
-
만약 moduleMap[url]에 record가 없으면:
-
false를 반환한다.
-
-
만약 Is Async Module를 moduleMap[url]'s record, moduleMap, base, seen로 실행한 결과가 true이면:
-
true를 반환한다.
-
-
-
-
false를 반환한다.
Lookup Race Response
-
registration을 null로 둔다.
-
request가 비하위 리소스 요청이면:
-
request의 예약된 클라이언트가 null이면, null을 반환한다.
-
storage key를 request의 예약된 클라이언트가 주어졌을 때 스토리지 키를 얻는 알고리즘을 실행한 결과로 둔다.
-
registration을 storage key와 request의 URL이 주어졌을 때 서비스 워커 등록 일치시키기를 실행한 결과로 설정한다.
-
-
그렇지 않고 request가 하위 리소스 요청이면:
-
client를 request의 클라이언트로 둔다.
-
client의 활성 서비스 워커가 null이면, null을 반환한다.
-
registration을 client의 활성 서비스 워커의 포함 서비스 워커 등록으로 설정한다.
-
-
그렇지 않으면, null을 반환한다.
-
activeWorker를 registration의 활성 워커로 둔다.
-
map[request]이 존재하면:
-
null을 반환한다.
부록 B: 확장된 HTTP 헤더
서비스 워커 스크립트 요청
서비스 워커 스크립트 응답
서비스 워커의 스크립트 리소스 요청에 대한 HTTP 응답에는 다음 헤더가 포함될 수 있습니다:
- `
Service-Worker-Allowed` -
사용자 에이전트가 경로 제한(스크립트가 scope url을 제어할 수 있는 최대 경로)을 주어진 값으로 재정의함을 나타냅니다.
참고: 값은 URL입니다. 상대 URL이 주어지면, 스크립트의 URL을 기준으로 파싱됩니다.
// 최대 허용 범위는 기본적으로 스크립트가 위치한 경로로 설정됩니다 // 이 예시에서는 "/js/"입니다 navigator. serviceWorker. register( "/js/sw.js" ). then(() => { console. log( "기본 scope '/js/'로 설치 성공." ); });
// 스크립트 위치보다 상위 경로로 scope 설정 // 응답에 Service-Worker-Allowed 헤더 없음 navigator. serviceWorker. register( "/js/sw.js" , { scope: "/" }). catch (() => { console. error( "경로 제한 위반으로 설치 실패." ); });
문법
ABNF는 서비스 워커의 스크립트 리소스 요청 및 응답에서 사용되는 헤더 값에 대해 정의합니다:
Service-Worker = %x73.63.72.69.70.74 ; "script", 대소문자 구분
참고: Service-Worker-Allowed 헤더 값의 유효성 검사는 ABNF 대신 URL 파싱 알고리즘(갱신 알고리즘)으로 수행됩니다.
8. 감사의 글
Andrew Betts에게 동료들과 함께하는 작은 워크숍을 조직하고 진행해주신 데 깊이 감사드립니다. 참석자: Jake Archibald, Jackson Gabbard, Tobie Langel, Robin Berjon, Patrick Lauke, Christian Heilmann. 논의의 명확성과 그날 제시된 사용 사례들 덕분에 많은 것이 가능해졌습니다. 또한 오프라인 문제의 중요성을 일깨워준 Andrew에게 다시 한번 감사드립니다. 그가 EdgeConf를 조직하고 오프라인을 지속적인 주제로 삼은 덕분에 본 작업의 진전에 여러 기회와 연결이 생겼습니다.
Anne van Kesteren은 서비스 워커 개발 과정에서 웹 플랫폼의 심오한 지식과 표준화 경험을 아낌없이 공유해주셨습니다. URL, HTTP Fetch, Promises, DOM의 실제 동작을 기술한 그의 이전 작업 없이는 이 규격이 완성될 수 없었을 것입니다. Ian Hickson의 엄밀한 Web Worker 규격 역시 본 규격의 기반이 되었습니다. 그에게 깊은 감사를 전합니다.
순서는 없지만, 설계 방향과 논의에 깊이 감사드릴 분들: Jungkee Song, Alec Flett, David Barrett-Kahn, Aaron Boodman, Michael Nordman, Tom Ashworth, Kinuko Yasuda, Darin Fisher, Jonas Sicking, Jesús Leganés Combarro, Mark Christian, Dave Hermann, Yehuda Katz, François Remy, Ilya Grigorik, Will Chan, Domenic Denicola, Nikhil Marathe, Yves Lafon, Adam Barth, Greg Simon, Devdatta Akhawe, Dominic Cooney, Jeffrey Yasskin, Joshua Bell, Boris Zbarsky, Matt Falkenhagen, Tobie Langel, Gavin Peters, Ben Kelly, Hiroki Nakagawa, Jake Archibald, Josh Soref, Jinho Bang, Yutaka Hirano, Michael(tm) Smith, isonmad, Ali Alabbas, Philip Jägenstedt, Mike Pennisi, Eric Willigers.
Jason Weber, Chris Wilson, Paul Kinlan, Ehsan Akhgari, Daniel Austin은 요구사항과 표준화 과정에서 귀중한 피드백을 제공해주셨습니다.
저자들은 Dimitri Glazkov의 스크립트 및 포맷팅 도구에도 감사드립니다. 이 규격 제작에 필수적이었으며 많은 가르침도 받았습니다.
Vivian Cromwell, Greg Simon, Alex Komoroske, Wonsuk Lee, Seojin Kim에게도 전문적인 지원에 깊이 감사드립니다.