1. 導入
このセクションは非規範的である。
Web アプリケーションは、信頼性の低いネットワーク(例:携帯電話)や未知の 有効期間(ブラウザーが終了される、またはユーザーが移動する可能性がある)を持つ環境で実行されることが多い。 これにより、Web アプリからのクライアントデータ(写真のアップロード、文書の変更、作成済みメールなど)を サーバーと同期することが難しくなる。同期が完了する前にブラウザーが閉じられたりユーザーが移動したりした場合、 アプリはユーザーがページを再訪するまで再試行を待たなければならない。この仕様は、 最初に要求されたときの悪条件にもかかわらず同期の試行を継続できるように、 service worker の新しい onsync イベントを提供する。このイベントは バックグラウンドで 発火できる。この API は、 コンテンツの作成からサーバーとのコンテンツ同期までの時間を短縮することを意図している。
この API は service workers に依存しているため、この API によって提供される機能は 安全なコンテキストでのみ利用可能である。
function sendChatMessage( message) { return addChatMessageToOutbox( message). then(() => { // Wait for the scoped service worker registration to get a // service worker with an active state return navigator. serviceWorker. ready; }). then( reg=> { return reg. sync. register( 'send-chats' ); }). then(() => { console. log( 'Sync registered!' ); }). catch (() => { console. log( 'Sync registration failed :(' ); }); }
上の例では、addChatMessageToOutbox は開発者定義の関数である。
service worker 内で sync イベントに反応する:
self. addEventListener( 'sync' , event=> { if ( event. tag== 'send-chats' ) { event. waitUntil( getMessagesFromOutbox(). then( messages=> { // Post the messages to the server return fetch( '/send' , { method: 'POST' , body: JSON. stringify( messages), headers: { 'Content-Type' : 'application/json' } }). then(() => { // Success! Remove them from the outbox return removeMessagesFromOutbox( messages); }); }). then(() => { // Tell pages of your success so they can update UI return clients. matchAll({ includeUncontrolled: true }); }). then( clients=> { clients. forEach( client=> client. postMessage( 'outbox-processed' )) }) ); } });
上の例では、getMessagesFromOutbox と removeMessagesFromOutbox は
開発者定義の関数である。
2. 概念
sync イベントは、対応する service worker registration の origin について、 service worker clients のうち、その frame type が top-level または auxiliary であるものが存在しない場合、 バックグラウンドで実行されていると見なされる。
ユーザーエージェントは、ネットワーク接続を確立している場合、 online であると見なされる。ユーザーエージェントは、 online であることについて、より厳格な定義を使用してもよい。 そのようなより厳格な定義では、service worker または sync registration が関連付けられる origin を 考慮してもよい。
3. 構成要素
service worker registration は、要素型が sync registration である、関連付けられた sync registrations のリストを持つ。sync registration は、tag と state から成るタプルである。
sync registration は、関連付けられた DOMString である tag を持つ。
sync registration は、関連付けられた registration state を持つ。これは pending, waiting, firing, または reregisteredWhileFiring のいずれかである。 これは初期状態で pending に設定される。
sync registration は、関連付けられた service worker registration を持つ。これは初期状態で null に設定される。
1 つの sync registrations のリスト内では、各 sync registration は一意の tag を持たなければならない。
4. Permissions との統合
Web Background Synchronization API は、既定の強力な機能であり、name "background-sync" によって識別される。5. プライバシー上の考慮事項
5.1. 許可
ユーザーエージェントは、ユーザーが background sync を無効にする手段を提供してもよい。注: Background sync は既定で有効にされるべきである。 許可が拒否されていることは例外的な場合と見なされる。
5.2. 位置トラッキング
バックグラウンドで の間に onsync イベント内で行われる fetch 要求は、 ユーザーがページを離れた後にクライアントの IP アドレスをサーバーに明らかにする可能性がある。 ユーザーエージェントは、再試行回数および sync イベントの継続時間に上限を設けることで トラッキングを制限するべきである。5.3. 履歴漏えい
バックグラウンドで の間に onsync イベント内で行われる fetch 要求は、 受動的な盗聴者にクライアントのナビゲーション履歴に関する何かを明らかにする可能性がある。 たとえば、クライアントがサイト https://example.com を訪問し、それが sync イベントを登録するが、 ユーザーがページから移動しネットワークを変更するまで発火しない場合がある。新しいネットワーク上の受動的な盗聴者は、 onsync イベントが行う fetch 要求を見る可能性がある。fetch 要求は HTTPS であるため要求内容は 漏えいしないが、ドメインは(DNS ルックアップおよび要求先の IP アドレスを介して)漏えいする可能性がある。6. API の説明
6.1. ServiceWorkerRegistration
インターフェイスへの拡張
ServiceWorkerRegistration/sync
現在のエンジン 1 つだけで利用可能。
Opera36+Edge79+
Edge (Legacy)なしIEなし
Firefox for AndroidなしiOS SafariなしChrome for Android49+Android WebView49+Samsung Internet4.0+Opera Mobile36+
partial interface ServiceWorkerRegistration {readonly attribute SyncManager ; };sync
属性は、syncSyncManager
を公開する。
これは、その属性が公開されている
ServiceWorkerRegistration
によって表される、関連付けられた
service worker registration を持つ。
6.2.
SyncManager
インターフェイス
現在のエンジン 1 つだけで利用可能。
OperaなしEdge79+
Edge (Legacy)なしIEなし
Firefox for AndroidなしiOS SafariなしChrome for Android49+Android WebView49+Samsung Internet5.0+Opera Mobileなし
[Exposed =(Window ,Worker )]interface {SyncManager Promise <undefined >register (DOMString );tag Promise <sequence <DOMString >>getTags (); };
現在のエンジン 1 つだけで利用可能。
OperaなしEdge79+
Edge (Legacy)なしIEなし
Firefox for AndroidなしiOS SafariなしChrome for Android49+Android WebView49+Samsung Internet5.0+Opera Mobileなし
メソッドは、呼び出されたとき、
新しい promise promise を返し、次の手順を 並列で実行しなければならない:
register(tag)
- serviceWorkerRegistration を、
SyncManagerの 関連付けられた service worker registration とする。 - serviceWorkerRegistration の active worker が null の場合、promise を
InvalidStateErrorで reject し、これらの手順を中止する。 - ユーザーが background sync を無効にしている場合、promise を
NotAllowedErrorで reject し、これらの手順を中止する。 - isBackground を true とする。
-
serviceWorkerRegistration の origin に対する
service worker clients 内の
client それぞれについて:
- client の frame type が top-level または auxiliary である場合、isBackground を false に設定する。
- isBackground が true の場合、promise を
InvalidAccessErrorで reject し、これらの手順を中止する。 - currentRegistration を、存在する場合は serviceWorkerRegistration の sync registrations のリスト内の、 tag が tag に等しい registration とし、そうでなければ null とする。
-
currentRegistration が null でない場合:
- currentRegistration の registration state が waiting である場合、 currentRegistration の registration state を pending に設定する。
- currentRegistration の registration state が firing である場合、 currentRegistration の registration state を reregisteredWhileFiring に設定する。
- promise を Resolve する。
- ユーザーエージェントが現在 online であり、かつ currentRegistration の registration state が pending である場合、 currentRegistration に対して sync event を発火する。
-
そうでない場合:
- newRegistration を新しい sync registration とする。
- newRegistration の関連付けられた tag を tag に設定する。
- newRegistration の関連付けられた service worker registration を serviceWorkerRegistration に設定する。
- newRegistration を serviceWorkerRegistration の sync registrations のリストに追加する。
- promise を Resolve する。
- ユーザーエージェントが現在 online である場合、 newRegistration に対して sync event を発火する。
現在のエンジン 1 つだけで利用可能。
OperaなしEdge79+
Edge (Legacy)なしIEなし
Firefox for AndroidなしiOS SafariなしChrome for Android49+Android WebView49+Samsung Internet5.0+Opera Mobileなし
メソッドは、呼び出されたとき、新しい promise promise を返し、次の手順を
並列で実行しなければならない:
getTags()
- serviceWorkerRegistration を、
SyncManagerの 関連付けられた service worker registration とする。 - currentTags を新しい
sequenceとする。 - serviceWorkerRegistration の sync registrations のリスト内の registration それぞれについて、registration の関連付けられた tag を currentTags に追加する。
- promise を currentTags で Resolve する。
6.3. sync イベント
現在のエンジン 1 つだけで利用可能。
Opera?Edge79+
Edge (Legacy)なしIEなし
Firefox for AndroidなしiOS SafariなしChrome for Android49+Android WebViewなしSamsung Internet5.0+Opera Mobile?
ServiceWorkerGlobalScope/onsync
すべての現在のエンジンで利用可能。
Opera24+Edge79+
Edge (Legacy)なしIEなし
Firefox for Android44+iOS Safari11.3+Chrome for Android49+Android WebView49+Samsung Internet5.0+Opera Mobile24+
現在のエンジン 1 つだけで利用可能。
Opera?Edge79+
Edge (Legacy)なしIEなし
Firefox for AndroidなしiOS SafariなしChrome for Android49+Android WebViewなしSamsung Internet5.0+Opera Mobile?
partial interface ServiceWorkerGlobalScope {attribute EventHandler ; }; [onsync Exposed =ServiceWorker ]interface :SyncEvent ExtendableEvent {(constructor DOMString ,type SyncEventInit );init readonly attribute DOMString ;tag readonly attribute boolean ; };lastChance dictionary :SyncEventInit ExtendableEventInit {required DOMString ;tag boolean =lastChance false ; };
注: SyncEvent
インターフェイスは、発火中の sync registration を表す。イベントを登録したページ(または worker)が
実行中である場合、ユーザーエージェントはネットワーク接続が利用可能になり次第 sync イベントを発火する。
そうでない場合、ユーザーエージェントは都合がつき次第イベントを実行するべきである。sync イベントが失敗した場合、
ユーザーエージェントは任意の時点で再試行することを決定してもよい。lastChance
属性は、ユーザーエージェントが現在の試行後にこの sync のさらなる試行を行わない場合に true である。
lastChance
に反応する:
self. addEventListener( 'sync' , event=> { if ( event. tag== 'important-thing' ) { event. waitUntil( doImportantThing(). catch ( err=> { if ( event. lastChance) { self. registration. showNotification( "Important thing failed" ); } throw err; }) ); } });
上の例は、ユーザーに
notification を表示することで、
lastChance
に反応する。これには、その origin が
notifications を表示する許可を
持つ必要がある。
上の例では、doImportantThing は開発者定義の関数である。
ユーザーエージェントが online に変わるたびに、ユーザーエージェントは sync event を発火するべきである。 これは、sync registration のうち、その registration state が pending であるものそれぞれについて行う。 イベントは任意の順序で発火されてもよい。
sync registration registration に対して sync event を発火するには、ユーザーエージェントは次の手順を実行しなければならない:
- Assert: registration の registration state は pending である。
- serviceWorkerRegistration を、registration に関連付けられた service worker registration とする。
- Assert: registration は serviceWorkerRegistration に関連付けられた sync registrations のリスト内に存在する。
- registration の registration state を firing に設定する。
-
serviceWorkerRegistration 上で、次のプロパティを持つ
SyncEventを使用して、"sync" Fire Functional Event する:-
現在のエンジン 1 つだけで利用可能。
FirefoxなしSafariなしChrome49+
Opera?Edge79+
Edge (Legacy)なしIEなし
Firefox for AndroidなしiOS SafariなしChrome for Android49+Android WebViewなしSamsung Internet5.0+Opera Mobile?tag - registration に関連付けられた tag
-
現在のエンジン 1 つだけで利用可能。
FirefoxなしSafariなしChrome49+
Opera?Edge79+
Edge (Legacy)なしIEなし
Firefox for AndroidなしiOS SafariなしChrome for Android49+Android WebViewなしSamsung Internet5.0+Opera Mobile?lastChance - この sync event が失敗した場合にユーザーエージェントが 再試行するなら false、現在の試行後に さらなる試行が行われないなら true。
その後、dispatchedEvent で次の手順を実行する:
- waitUntilPromise を、dispatchedEvent の extended lifetime promises の すべてを待機する結果とする。
-
waitUntilPromise の
充足時に、次の手順をアトミックに実行する:
-
registration の state が
reregisteredWhileFiring である場合:
- registration の state を pending に設定する。
- ユーザーエージェントが現在 online である場合、registration に対して sync event を発火する。
- これらの手順の残りを中止する。
- Assert: registration の registration state は firing である。
- registration を serviceWorkerRegistration の sync registration のリストから削除する。
-
registration の state が
reregisteredWhileFiring である場合:
-
waitUntilPromise の
拒否時、または
service worker の
終了によってスクリプトが中止された場合、
次の手順をアトミックに実行する:
-
registration の state が
reregisteredWhileFiring である場合:
- registration の state を pending に設定する。
- ユーザーエージェントが現在 online である場合、registration に対して sync event を発火する。
- これらの手順の残りを中止する。
-
dispatchedEvent の
lastChance属性が false の場合、registration の registration state を waiting に設定し、 次の手順を 並列で実行する:- ユーザーエージェント定義の時間だけ待つ。
- registration の registration state が waiting でない場合、これらの下位手順を中止する。
- registration の registration state を pending に設定する。
- ユーザーエージェントが現在 online である場合、registration に対して sync event を発火する。
- そうでない場合、registration を serviceWorkerRegistration の sync registrations のリストから削除する。
-
registration の state が
reregisteredWhileFiring である場合:
-
ユーザーエージェントは、SyncEvent
の
lifetime extension および実行時間に対して、一般の
ExtendableEvent
に
課される時間制限よりも厳しい時間制限を課してもよい。特に、
lastChance
が true であるイベントは、大幅に短縮された時間制限を持ってもよい。
ユーザーエージェントは、何らかのユーザーエージェント定義のヒューリスティックに基づき、 sync event を 再試行する。