1. 概念
ストレージ分割を踏まえ、本仕様は同じパーティション内で発生するナビゲーション(例:同じサイト内のトップレベルナビゲーション)および別パーティションで発生するナビゲーション(例:異なるサイトへのトップレベルナビゲーション)のためのプレフェッチを定義します。
-
hypotheticalEnvironmentを予約されたクライアントの作成により、navigable、responseのURL、nullを用いて得る。
-
hypotheticalPartitionKeyをネットワークパーティションキーの決定によりhypotheticalEnvironmentから得る。
-
hypotheticalPartitionKeyがsourcePartitionKeyと等しい場合、または認証情報がURLおよびhypotheticalPartitionKeyに関連付けられていない場合、falseを返す。
-
trueを返す。
-
redirectChainの最後の項目のリクエストに、requestのクローンをセットする。
クローンすることで、リダイレクトの間でrequestが修正されても保存されたリクエストには影響しません。これは活性化時(prefetch recordからナビゲーションパラメータを作成)に元のリダイレクトチェーンの全体像を取得するために参照されます。現時点で唯一既知の、リクエストフィールドがミューテートされ、活性化時に参照されるケースはreferrerフィールドですが、仕様の堅牢性のため、リクエスト全体をクローンしています。
プレフェッチは
`GET`リクエストのみで実行されるため、リクエストのbodyは常にnullとなり、クローンは比較的簡単です。 -
redirectChainの最後の項目のレスポンスにresponseをセットする。
各Documentは、prefetchレコードを持ち、これはリスト形式のprefetchレコードです。
-
URL:URL
-
匿名化ポリシー:prefetch IP匿名化ポリシー
-
referrerポリシー:referrerポリシー
-
No-Vary-Searchヒント:URL検索バリアンス
-
ソース:文字列
これは仕様や実装定義の機能が、どのプレフェッチが生成したかの識別や他データの関連付けに利用できます。 -
prerendering traversable:prerendering traversable、 "
to be created"またはnull(デフォルトはnull) -
prerendering対象ナビゲーション名ヒント:有効なナビゲーションターゲット名またはキーワード、またはnull(デフォルトはnull)
-
状態:"
ongoing"(デフォルト)、"completed"、"canceled""canceled"は、プレフェッチが著者・ユーザーにより中断されたか、ユーザーエージェントにより終了したことを示します。 -
フェッチコントローラー:フェッチコントローラー(デフォルトは新規のフェッチコントローラー)
-
リダイレクトチェーン:リダイレクトチェーン(デフォルトは空)
-
開始時刻:
DOMHighResTimeStamp(デフォルトは0.0) -
有効期限:
DOMHighResTimeStamp(デフォルトは0.0) -
ソースパーティションキー:ネットワークパーティションキーまたはnull(デフォルト)
-
分離パーティションキー:ネットワークパーティションキーで、最初の項目が不透明オリジンであり、一時的にクロスパーティション状態を保管できる別パーティションを表すか、null(デフォルト)
-
矛盾する認証情報があった:ブール値(初期値はfalse)
通常は認証情報付きリクエストでも、クロスパーティションプレフェッチのため認証情報を送れない場合、プレフェッチは中止されます。
prefetch recordのresponseは、そのredirect chainの最後の要素のresponse、もしくはそのリストが空の場合はnullである。
ユーザーエージェントは、キャンセル・廃棄を、未失効でも(資源制約等により)prefetchレコードから行う場合があります。一致するプレフェッチレコードの待機対象外となった過去の有効期限レコードは、観測上の影響なく削除可能です。
-
prefetchRecordのURLとurlが等しければtrueを返す。
-
prefetchRecordのレスポンスがnullでなければ:
-
searchVariance を URL検索バリアンスの取得を prefetchRecordのリダイレクトチェーン[0]のレスポンスに対して行う。
0番目のレスポンスを確認することが重要です(最後ではなく)、 URLが最初のリクエスト/レスポンスペアのため、No-Vary-Searchヘッダーも最初だけが判定に影響します。
-
-
それ以外はfalseを返す。
-
prefetchRecordがURLに一致する場合、trueを返す。
-
prefetchRecordのレスポンスがnullの場合:
-
searchVarianceをNo-Vary-Searchヒントより取得。
-
-
それ以外はfalseを返す。
Document
documentに対して、以下の手順を行います:
-
アサート:prefetchRecordがdocumentのprefetchレコードに存在する。
-
prefetchRecordの状態を"
canceled"にセット。 -
Abort prefetchRecordのフェッチコントローラー。これにより進行中のフェッチを中断し、ネットワークエラーとなります。
-
prefetchRecordのprerendering traversableがtraversable navigableなら、破棄する。
-
削除:prefetchRecordをdocumentのprefetchレコードから除去。
-
prefetchステータス更新イベントの発火:documentのノードナビゲーブル、prefetchRecord、"
失敗" ステータスを与える。
完了済みのprefetchやprerenderであっても、これを活性化することはありません。ただしプレフェッチやprerenderの過程でHTTPキャッシュが更新され、以降のナビゲーションが高速化される場合があります。
Document
documentに対して、以下の手順で処理されます:
-
currentTimeを現在の高精度時刻(documentの関連グローバルオブジェクト)として取得。
-
expiryTimeをcurrentTime+300,000(5分)とする。
-
削除:documentのprefetchレコードから、prefetchRecordと同じURLかつ状態が"
completed"の要素を全部除去。 -
prefetchステータス更新イベントの発火:documentのノードナビゲーブル、prefetchRecord、"
ready" ステータスを与える。
-
exactRecordをnullとする。
-
inexactRecordをnullとする。
-
各 record(sourceSnapshotParamsのprefetchレコード)について:
-
recordToUseは、exactRecordがnullでなければexactRecord、nullならinexactRecord。
-
recordToUseがnullでなければ:
-
currentTimeを現在の高精度時刻(navigableのアクティブドキュメント)として取得。
-
recordToUseの有効期限がcurrentTimeより小さければ:
-
prefetchステータス更新イベントの発火:navigable、recordToUse、"
失敗"ステータスを与える。 -
nullを返す。
-
-
各 exchangeRecord(recordToUseのリダイレクトチェーン)について:
-
矛盾する認証情報が存在するなら、exchangeRecordのレスポンスに対してnavigable、recordToUseのソースパーティションキーを与える:
-
prefetchステータス更新イベントの発火:navigable、recordToUse、"
失敗" ステータス。 -
nullを返す。
-
開始時にクロスパーティション認証情報がなくても、途中で付与される場合を扱います。ユーザーエージェントは、URLに関連するクッキーの変更監視やハッシュ・タイムスタンプ・リビジョン番号での管理など、より粗いアルゴリズムも可能です。 -
-
recordToUseを返す。
-
-
nullを返す。
実際には、prefetchで完全なボディ受信を必要とせず、応答ヘッダーのみでよい点に注意。ナビゲーションによってprefetch応答を使っても即時ロードとは限りません。
キャッシュレスポンスヘッダーで複数回利用できるタイミングを判断できるかもしれませんが、prefetchバッファの寿命短さで有効性は不明です。
-
timeoutをnullとする。
-
実装依存の最大待機時間をtimeoutとする場合も任意。
適切なtimeout選択は難しく、ナビゲーションやprefetchの発起者(推測ルールの積極性・prerender用途等)による場合もありうる。一般にはタイムアウトは回避推奨ですが、非prefetchで再開した方が良い結果のケースはまれ。実装によっては数秒程度のtimeoutが好結果となる場合もあります。
-
startTimeを未保護共有現在時刻とする。
-
次を実行。ただし、中断はtimeoutがnullでなく、未保護共有現在時刻−startTimeがtimeoutを超えた場合:
-
while(true):
-
completeRecordを一致する完了プレフェッチレコードの検索の結果(navigable、sourceSnapshotParams、url)とする。
-
completeRecordがnullでなければ、それを返す。
-
potentialRecordsを空のリストとする。
-
各 record(sourceSnapshotParamsのprefetchレコード)について:
-
次のすべてがtrueなら:
-
recordの状態が"
ongoing" -
recordがURLに一致する見込み
-
recordの有効期限が現在の高精度時刻(navigableのアクティブウィンドウ)より大きい
-
ループごとにpotentialRecordsが再計算され、次回イテレーションのpotentialRecordsは前イテレーションの部分集合となる。prefetchレコードが静的スナップショットで、条件がfalse→trueに変化しないためです。
一度初期potentialRecordsを構築し、条件から外れたら除去する戦略でも同等。
-
-
potentialRecordsが空ならnullを返す。
-
いずれかの状態が変更されるまで(sourceSnapshotParamsのprefetchレコード)待機。
-
-
-
nullを返す。
sourceSnapshotParamsのprefetchレコードがスナップショットなので、ナビゲーション後に開始したprefetchは活性化できません。
-
各 candidate(candidates)について:
-
candidateがprefetch候補で、 prefetchRecordの匿名化ポリシーが candidateの匿名化ポリシーと等しくない場合は、continue。
-
candidateがprerender候補で、 prefetchRecordのprerendering traversable がnullなら、continue。
-
trueを返す。
-
falseを返す。
Document
documentが一致するprefetchレコードを持つかどうかは、prefetchレコード
recordUnderConsiderationとオプションのboolean checkPrerender(デフォルトfalse)を与え、以下アルゴリズムがtrueを返す場合とする:
-
各 record(documentのprefetchレコード)について:
-
checkPrerenderがtrueの場合:
-
recordのprerendering traversableがnullなら、continue。
-
recordのprerenderingターゲットナビゲーブル名ヒントが recordUnderConsiderationのprerenderingターゲットナビゲーブル名ヒントと等しくなければ、ユーザーエージェントはcontinueしてよい。
ユーザーエージェントがprerendering traversableを prerenderingターゲットナビゲーブル名ヒントごとに分けて管理している場合はここでcontinueし、 それらを区別する。一方、既存のprerendering traversableを名ヒントに関わらず活性化できる場合は同等とみなす。
-
-
recordNVSをnullとする。
-
recordのレスポンスがnullでなければ、 recordNVSをURL検索バリアンス取得(recordのレスポンスで)で得る。
-
それ以外はrecordのNo-Vary-SearchヒントをrecordNVSにセットする。
-
recordUnderConsiderationのNo-Vary-SearchヒントとrecordNVSが等しくなければ、continue。
-
recordUnderConsiderationのURLと recordのURLが 検索バリアンス無視で同等(recordUnderConsiderationのNo-Vary-Searchヒントを用いる)ならtrueを返す。
-
falseを返す。
No-Vary-Search比較の議論はHTML標準内の比較も参照。
NavigationTimingType
navTimingType、request request、prefetchレコード record、target snapshot params targetSnapshotParams、source snapshot params
sourceSnapshotParamsを与え、次の手順で処理される:
-
responseOrigin=null。
-
responseCOOP=null。
-
coopEnforcementResultをクロスオリジンオープナーポリシー検証結果生成 (navigableのアクティブドキュメント、documentStateのinitiator origin)で取得。
-
finalSandboxFlagsを空のサンドボックスフラグセットとする。
-
responsePolicyContainer=null。
-
urlListを空のリストとする。
-
responseはrecordのレスポンス。
-
各 exchangeRecord(recordのリダイレクトチェーン)について:
-
redirectChainRequest=exchangeRecordのリクエスト。
-
redirectChainResponse=exchangeRecordのレスポンス。
-
responsePolicyContainerをfetchレスポンスからのポリシーコンテナ作成 (redirectChainResponse、redirectChainRequestの予約クライアント)で設定。
-
finalSandboxFlagsにtargetSnapshotParamsのサンドボックスフラグとresponsePolicyContainerのCSPリストのCSP由来サンドボックスフラグの和集合を設定。
-
responseOriginをオリジン決定 (redirectChainResponseのURL、finalSandboxFlags、documentStateのinitiator origin、null)で設定。
-
responseCOOPをCOOP取得 (redirectChainResponse、redirectChainRequestの予約クライアント)で設定。
-
coopEnforcementResultを レスポンスCOOP強制処理 (navigableのアクティブ閲覧コンテキスト、redirectChainResponseのURL、responseOrigin、responseCOOP、coopEnforcementResult、redirectChainRequestのreferrer)で設定。
-
finalSandboxFlagsが空でなく、responseCOOPのvalueが"
unsafe-none"なら responseに適切なネットワークエラーを設定し、break。
-
-
requestのURLがurlList[0]と等しくなければ、requestのURLをurlListの0番目の項目の後に挿入。
この場合はrequestのURLへナビゲートするが、プレフェッチは最初のレスポンスURL(urlList[0])が由来となる。No-Vary-Searchのためで、これは0番目レスポンスから
URLへのリダイレクトとして扱われる。挿入後にurlListのサイズが2なら、生成されるDocumentがナビゲート先のURLを使う。それより大なら影響なし。 -
requestのURLリストにurlListを設定。
-
requestの予約クライアントを予約クライアント作成(navigable、requestのURL)で設定。
これは生成される
Documentと環境設定オブジェクト用の環境となる。 consume毎に個別環境が必要。recordのリダイレクトチェーン の最後のリクエストの 予約クライアント を使い回すと複数ナビゲーションでidを共有してしまうため(clients.get()APIなどで可視化されてしまう)。 -
requestの予約クライアントのアクティブServiceWorkerを recordのリダイレクトチェーンの最後のリクエストの予約クライアントのアクティブServiceWorkerに設定。
-
resultPolicyContainerにナビゲーションパラメータ用ポリシーコンテナ決定 (recordのレスポンスのURL、documentStateの履歴ポリシーコンテナ、sourceSnapshotParamsのソースポリシーコンテナ、null、responsePolicyContainer)をセット。
-
responseがネットワークエラーでなければ:
-
任意でresponseをクローンに置き換えてよい。
複数回consumeされる場合(将来prerenderで利用され、prerendering traversableが破棄されても、クローンすれば再利用できる等)、実装はこの手順を行うことがある。
-
上記任意手順を行わなかった場合、recordをnavigableのアクティブドキュメントのprefetchレコードから除去。
-
-
新しいナビゲーションパラメータを次の値で返す:
- id
-
navigationId
- request
-
request
- response
-
response
- origin
-
responseOrigin
- policy container
-
resultPolicyContainer
- final sandboxing flag set
-
finalSandboxFlags
- cross-origin opener policy
-
responseCOOP
- COOP enforcement result
-
coopEnforcementResult
- reserved environment
-
requestの予約クライアント
- navigable
-
navigable
- navigation timing type
-
navTimingType
- fetch controller
-
recordのfetch controller
上記任意手順で複数回ナビゲーションパラメータ生成される場合でも、同じfetch controllerを共有して問題ない。これはナビゲーションタイミング情報計算のみで参照されるため。
- commit early hints
-
null
prefetchされたドキュメントのearly hintsは処理されない(見直し可能性はある)。現状prefetchはヘッダー到着まで提供されないため、early hintsは本応答ヘッダーとほぼ同時になる。将来の仕様で何らかの利用法を提案可能。
- delivery type
-
"
navigational-prefetch"
-
policyがクロスオリジンプレフェッチIP匿名化ポリシーであれば:
-
アサート:policyはnull。
-
falseを返す。
2. HTMLパッチ
この節は[HTML]へのパッチを含みます。
以下のようにenvironmentへ追加項目を加えます:
- is navigational prefetch client
-
boolean型(デフォルト: false)
以下のようにnavigation paramsへ追加項目を加えます:
- delivery type
全ての生成箇所で空文字列を供給するよう更新します(ただし本仕様で異なる値が供給される記述がある場合は除きます。prefetch recordからナビゲーションパラメータを作成など)。
以下のようにsource snapshot paramsへ追加項目を加えます:
- prefetch records
-
list型、 prefetch recordのリストです。
snapshot source snapshot paramsアルゴリズムを修正し、 戻り値のprefetch recordsに sourceDocumentのprefetch recordsのcloneをセット。
予約クライアント作成( navigable navigable、URL url、 opaque originまたはnull isolationOrigin )アルゴリズム:
-
topLevelCreationURL = url
-
topLevelOrigin = null
-
isolationOriginがnullでなければ:
-
topLevelCreationURL =
about:blank -
topLevelOrigin = isolationOrigin
-
-
それ以外でnavigableが トップレベル traversable でない場合:
-
parentEnvironment = navigableの親のアクティブドキュメントのrelevant settings object
-
topLevelCreationURL = parentEnvironmentのtop-level creation URL
-
topLevelOrigin = parentEnvironmentのtop-level origin
-
-
新しいenvironmentを返す。idはユニークな不透明文字列、 target browsing contextは navigableのアクティブブラウジングコンテキスト、 creation URLはurl、 top-level creation URLは topLevelCreationURL、 top-level originは topLevelOrigin
ナビゲーション用クロスオリジンオープナーポリシー検証結果の作成
Document
activeDocumentとorigin initiatorOriginを与えて、
新しいcross-origin opener policy enforcement resultを返します
- url
-
activeDocumentのURL
- origin
-
activeDocumentのorigin
- cross-origin opener policy
-
activeDocumentのcross-origin opener policy
- current context is navigation source
-
activeDocumentのoriginがinitiatorOriginと same originならtrue、それ以外はfalse
ナビゲーションリクエスト作成 session history entry entry、 environment settings object fetchClient、 navigable containerまたはnull container、 boolean hasTransientActivationを与え、以下の手順を行う
-
documentResource = entryのdocument stateのresource
-
request = 新しいrequest(以下をセット)
- url
-
entryのURL
- policy container
- client
-
fetchClient
- destination
-
"
document" - credentials mode
-
"
include" - use-URL-credentials flag
-
set
- redirect mode
-
"
manual" - mode
-
"
navigate" - referrer
- referrer policy
-
documentResourceがPOST resourceなら:
-
requestのmethodに
`POST`をセット -
requestのbodyにdocumentResourceのrequest bodyをセット
-
セット:
`Content-Type`を documentResourceのrequest content-typeに requestのheader listで
-
-
entryのdocument stateの reload pendingがtrueなら requestのreload-navigation flagをセット
-
それ以外でentryのdocument stateの ever populatedがtrueなら requestのhistory-navigation flagをセット
-
hasTransientActivationがtrueならrequestのuser-activationにtrueをセット
-
containerが非nullなら:
-
containerにbrowsing context scope originがある場合、 requestのoriginにそれをセット
-
requestのdestinationおよび initiator type をcontainerのlocal nameにセット
-
-
requestを返す
-
次の両方がtrueなら:
-
entryのURLのschemeがfetch schemeである
-
documentResourceがnull、もしくはallowPOSTがtrueかつ documentResourceのrequest bodyがfailureでない
ならば:
-
request = ナビゲーションリクエスト作成結果 (entry, sourceSnapshotParamsのfetch client, navigableの container, sourceSnapshotParamsのhas transient activationを与えて)
-
requestのreplaces client idを navigableのactive documentの relevant settings objectの idにセット
-
prefetched = false の初期化
-
documentResourceがnullかつnavigableが トップレベル traversableなら:
-
prefetchRecord = 一致するprefetch recordの待機結果 (navigable, sourceSnapshotParams, entryの URL)
-
prefetchRecordがnullでなければ:
-
navigationParams = prefetch recordからナビゲーションパラメータ作成結果 (navigable, entryのdocument state, navigationId, navTimingType, request, prefetchRecord, targetSnapshotParams, sourceSnapshotParams)
-
prefetchクッキーのコピー (prefetchRecordのisolated partition key、navigationParamsのreserved environment)
このコピーは以後、サブリソースフェッチやdocument.cookie等で クッキーが観測可能になるまで完了。クロスサイトURLに到達していなければコピーされるクッキーはありません。 -
prefetchedをtrueにセット
-
prefetchステータス更新イベント発火 (navigable, prefetchRecord,"
success" ステータス)
この条件はprefetchを `
GET`リクエストのみで満たすこと、 かつ トップレベル traversablesだけで起動することを保証。 -
-
-
prefetchedがfalseならnavigationParams = fetchによるナビゲーションパラメータ作成結果 (request, entry, navigable, sourceSnapshotParams, targetSnapshotParams, cspNavigationType, navigationId, navTimingType)
-
fetchによるナビゲーションパラメータ作成は、request
request、session history entry entry、navigable
navigable、source snapshot params sourceSnapshotParams、target snapshot params
targetSnapshotParams、string cspNavigationType、navigation IDまたはnull navigationId、NavigationTimingType
navTimingType、およびオプションのprefetch record prefetchRecordを与え、以下の手順を実行する。
-
アサート:requestのredirect modeは"
manual"である。 -
アサート:requestのreserved clientはnullである。
-
responseをnullとする。
-
responseOriginをnullとする。
-
fetchControllerをnullとする。
-
coopEnforcementResultをナビゲーション用クロスオリジンオープナーポリシー検証結果作成(navigableのアクティブドキュメント、entryのdocument stateのinitiator origin)で取得。
-
finalSandboxFlagsを空のサンドボックスフラグセットとする。
-
responsePolicyContainerをnullとする。
-
responseCOOPを新しいcross-origin opener policyにする。
-
locationURLをnullとする。
-
currentURLをrequestのcurrent URLとする。
-
commitEarlyHintsをnullとする。
-
isolationOriginをnullとする。
-
prefetchRecordが与えられていれば:
-
isolationSite = prefetchRecordのisolated partition key[0]。
-
アサート:isolationSiteはopaque originである。
-
isolationOrigin = isolationSiteとする。
-
-
while true:
-
requestのreserved clientがnullでなく、 currentURLのoriginがrequestのreserved clientのcreation URLのoriginと異なる場合:
-
環境廃棄手順(requestのreserved clientに対して)を実行。
-
requestのreserved clientをnullにする。
-
commitEarlyHintsをnullにする。
-
-
requestのreserved clientがnullの場合:
-
requestのreserved clientを 予約クライアント作成 (navigable、currentURL、isolationOrigin)で設定。
-
prefetchRecordが与えられていれば、requestのreserved clientのis navigational prefetch clientをtrueにする。
-
-
should navigation request of type be blocked by Content Security Policy?(request、cspNavigationType)が"
Blocked"ならresponseにnetwork errorをセットし、break。 -
prefetchRecordが与えられていれば:
-
prefetchRecordのanonymization policyが、匿名性を要求する場合(requestに対して):
-
prefetchトークンに、キー"anonymous-client-ip"、値trueのパラメータを追加。 -
ユーザーエージェントは、requestフェッチ時にクライアントIPアドレスを匿名化するconnection(例:プロキシ経由)を使用するか、responseにnetwork errorをセットし、breakとする。
現状IP匿名化の方法は未定義。実装依存(プロキシやリレー等)で処理される見込み。理想的にはfetch connection取得へ伝搬する形式で標準化したい。
-
-
prefetchRecordのprerendering traversableがnullでなければ、キー"
prerender"、値trueのパラメータを追加。 -
structured field値セット ( `
Sec-Purpose`, purpose)をrequestのheader listに設定。実装では互換性維持のためベンダー独自ヘッダー(Chromium:`Purpose`/`prefetch`、Mozilla:`X-moz`/`prefetch`、WebKit:`X-Purpose`/`preview`等)も送る場合あり。今後は共通ヘッダーへの移行を希望。 -
requestのcurrent URLのoriginが、prefetchRecordのURLのoriginと同一サイトなら:
-
tagsをListとし、prefetchRecordのtagsの各itemを、文字列はStrings、nullは
nullトークンにマッピング。 -
structured field値セット ( `
Sec-Speculation-Tags`, tagsをrequestのheader listへ設定。
-
-
requestのcurrent URLが信頼できる可能性があるURLでなければ、responseにnetwork errorをセットし、break。
これはprefetchトラフィックが中間者等に可視化されるリスク低減と、暗号化方式使用促進の意図。 -
proposedPartitionKeyをネットワークパーティションキー決定 (requestのreserved client)で取得。
-
proposedPartitionKeyがprefetchRecordのsource partition keyと異なり、requestのreferrer policy が十分厳格な推測ナビゲーションreferrerポリシー一覧に含まれない場合、responseにnetwork errorをセットし、break。
実際にはクロスサイトprefetchは、referrer URLがoriginより広い情報を漏らさないよう破棄される形となる。 -
requestはanonymization policyによりフェッチできない場合(実装依存)、 responseにnetwork errorをセットし、break。
これは実装毎に、匿名化アクセス不可能なホストや、private prefetch拒否アドバイスされたホスト等追加制限がありうることへの配慮。 -
追加:新規交換レコード (requestはrequest、 responseはnull)をprefetchRecordのredirect chainへ追加。
-
responseをnullにする。
-
fetchControllerがnullなら、以下を指定してrequestをfetch実行 ・processEarlyHintsResponse:下記定義 ・processResponse:下記定義 ・useParallelQueue:true
processEarlyHintsResponseは、response earlyResponseを受け、 prefetchRecordが与えられていてcommitEarlyHintsがnullなら、early hint headers処理 (earlyResponse、requestのreserved client)結果をcommitEarlyHintsにセット。
processResponseは、response fetchedResponseを受け、 responseにfetchedResponseをセット。
-
それ以外の場合はfetchControllerで次のmanualリダイレクトを処理。
-
responseがnullになるか、navigableのongoing navigationがnavigationIdと一致しなくなるまで待つ。
後者の場合はfetchControllerのabortとし、終了。 それ以外は継続。ナビゲーション開始時にprefetchが即時abortされるが、これは望ましくない場合も。
-
requestのbodyがnullなら、entryのdocument stateのresourceをnullにセット。
-
responsePolicyContainerをfetchレスポンスからのポリシーコンテナ作成 (response、requestのreserved client)で設定。
-
finalSandboxFlagsに、targetSnapshotParamsのsandboxing flagsとresponsePolicyContainerのCSPリストのCSP由来サンドボックスフラグの和集合をセット。
-
responseOriginをオリジン決定 (responseのURL、finalSandboxFlags、entryのdocument stateのinitiator origin、null)で設定。
-
navigableがトップレベル traversableでprefetchRecordが与えられていなければ:
-
responseCOOPをCOOP取得(response、requestのreserved client)でセット。
-
coopEnforcementResultをCOOP強制処理 (navigableのブラウジングコンテキスト、requestのURL、responseOrigin、responseCOOP、coopEnforcementResult、requestのreferrer)でセット。
-
もしfinalSandboxFlagsが空でなく、 responseCOOPのvalueが"
unsafe-none"でなければ、 responseにnetwork errorをセットし、break。
-
-
responseがnetwork errorでなく、navigableが子navigableで、CORP判定の結果がblockedの場合は、 responseにnetwork errorをセットし、break。
-
prefetchRecordが与えられていれば:
-
リダイレクトチェーン更新(prefetchRecordのredirect chain、request、response)を実行。
-
矛盾する認証情報が存在する (response、navigable、prefetchRecordのsource partition key)の場合、 prefetchRecordのhad conflicting credentialsをtrue。
これはprefetchを直ちにabortせず、リダイレクト追従も止めない。ユーザーがナビゲーション前に外部ストレージ状態保有有無を観測されないよう。prefetchは矛盾認証情報状態でも続行されるが実利用は不可。ユーザーエージェントはコンソールで警告出力等推奨可。
-
-
locationURLをresponseのlocation URL(currentURLのfragment付き)でセット。
-
locationURLがfailureまたはnullならbreak。
-
entryのserialized stateにStructuredSerializeForStorage(null)をセット。
-
oldDocStateをentryのdocument stateとする。
-
entryのdocument stateを新しいdocument state(以下の値)でセット:
- history policy container
-
oldDocStateのhistory policy containerのclone
- request referrer
-
oldDocStateのrequest referrer
- request referrer policy
-
oldDocStateのrequest referrer policy
- origin
-
oldDocStateのorigin
- resource
-
oldDocStateのresource
- ever populated
-
oldDocStateのever populated
- navigable target name
-
oldDocStateのnavigable target name
-
locationURLのschemeがHTTP(S) schemeでなければ:
-
entryのdocument stateのresourceをnullにする。
-
-
currentURL = locationURL。
-
entryのURLをcurrentURLにセット。
-
-
locationURLがURLで、schemeがfetch schemeでない場合、新しいnon-fetch scheme navigation paramsを返す(以下の値):
- initiator origin
-
requestのcurrent URLのorigin
-
以下のいずれかがtrueなら:
-
responseがnetwork errorである
-
locationURLがfailureである
-
locationURLがURLで、そのschemeがfetch schemeである
-
-
resultPolicyContainer = ナビゲーションパラメータ用ポリシーコンテナ決定 (responseのURL、entryのdocument stateのhistory policy container、sourceSnapshotParamsのsource policy container、null、responsePolicyContainer)
-
新しいnavigation paramsを以下の値で返す:
- id
-
navigationId
- request
-
request
- response
-
response
- origin
-
responseOrigin
- policy container
-
resultPolicyContainer
- final sandboxing flag set
-
finalSandboxFlags
- cross-origin opener policy
-
responseCOOP
- COOP enforcement result
-
coopEnforcementResult
- reserved environment
-
requestのreserved client
- navigable
-
navigable
- navigation timing type
-
navTimingType
- fetch controller
-
fetchController
- commit early hints
-
commitEarlyHints
-
navigationParamsのdelivery typeが"
prefetch"なら、任意でswapGroupをtrueにセットする。これにより参照元サイトがロードタイミングを計測してprefetchが使われたかどうか判別しづらくなる。宛先サイト情報のリーク防止効果あり。
3. ナビゲーションタイミングパッチ
この節は[NAVIGATION-TIMING]へのパッチを含みます。
4. Service Workerパッチ
この節は[SERVICE-WORKERS]へのパッチを含みます。
resultingClientId
を設定する手順を以下のように変更:
requestが非サブリソースリクエストで、 requestのdestinationが "report"以外 かつ reservedClientのis navigational prefetch clientが false の場合はeのresultingClientId属性にreservedClientのidを設定し、そうでなければ空文字列にする。
prefetchの場合は、requestにreserved clientが一時的に存在するが、
実際のクライアント生成は活性化時なので、
FetchEvent
の発火後。例えばclients.matchAll()
などで観測可能な本物のクライアントではありません。
5. Clear Site Dataパッチ
Clear Site Data § 3.1 The Clear-Site-Data HTTP Response Header Fieldの記述値に追加のヘッダー値を加える:
- "
prefetchCache" -
"
prefetchCache"タイプは、サーバーが特定originのresponseのURLで開始されたprefetchを削除したい意思を示す。このタイプは"
cache"タイプの部分集合です。実装詳細は下記のとおり。
parse response’s Clear-Site-Data headerのパース手順を修正:
-
`"cache"`または`"*"`が出現した場合、typesに "prefetchCache"を(既存追加分に加えて)追加する -
`"prefetchCache"`が出現した場合、typesに "prefetchCache"を追加する。
clear site data for
responseのswitch記述に、"prefetchCache"を扱うケースを追加し、clear
prefetch cache(origin対象)を呼び出すよう修正。
-
全ての トップレベル traversable traversable(ユーザーエージェントのトップレベル traversable セット内)について:
-
navigablesをtraversableの包含するナビゲーブル集合(traversableのアクティブドキュメントから取得)とする。
-
各 navigable(navigables内)について:
-
activeDocument = navigableのアクティブドキュメント。
-
activeDocumentのoriginがoriginとsame originでなければ、continue。
-
各 prefetchRecord(activeDocumentのprefetch records内)について:
-
prefetchRecordのprerendering traversableがnullでなければ、continue。
-
キャンセル・廃棄 prefetchRecord(activeDocument対象)を実行。
-
-
-
6. プレフェッチアルゴリズム
十分に厳格な推測ナビゲーションのreferrerポリシーのリストは、以下を含むリストとする:
"",
"strict-origin-when-cross-origin", "strict-origin", "same-origin",
"no-referrer"。
Document
document, prefetchRecord prefetchRecord):
-
アサート:documentのnode navigableはトップレベル traversableである。
-
documentが一致するprefetch recordを持つならprefetchRecordを与えてreturn。
-
sourceSnapshotParams = source snapshot paramsのスナップショット化(document)
-
targetSnapshotParams = target snapshot paramsのスナップショット化(documentのnode navigable)
-
prefetchRecordのsource partition keyを network partition keyの決定 (documentのrelevant settings object)でセット
-
アサート:prefetchRecordのURLのschemeはHTTP(S) schemeである。
-
追加:prefetchRecordをdocumentのprefetch recordsに追加。
-
prefetchRecordのstart timeを現在の高精度時刻 (documentのrelevant global object)でセット
-
prefetchステータス更新イベントの発火(documentのnode navigable、prefetchRecord、"
pending" ステータス) -
referrerPolicy = prefetchRecordのreferrer policy が空文字列でなければそれ、そうでなければdocumentのpolicy containerのreferrer policy
-
documentState = 新規document state(以下をセット)
- request referrer policy
-
referrerPolicy
- initiator origin
-
documentのorigin
-
entry = 新規session history entry(以下をセット)
- URL
-
prefetchRecordのURL
- document state
-
documentState
-
request = ナビゲーションリクエスト作成 (entry, documentのrelevant settings object, documentのnode navigableのcontainer, false)
-
global = documentのrelevant global object
-
並列で:
-
navigationParams = fetchによるナビゲーションパラメータ作成 (request, entry, documentのnode navigable, sourceSnapshotParams, targetSnapshotParams, "
other", null (navigationId), "navigate", prefetchRecordを与えて) -
navigationParamsのresponseがprefetch非対応ならnavigationParamsをnullにする。
-
prefetchRecordのhad conflicting credentials がtrueならnavigationParamsをnullにする。
リダイレクトチェーンにクロスパーティションoriginで認証情報があれば、そのprefetchは廃棄される。これによりログイン状態のユーザーがログアウトページを誤って観測する可能性を低減。 -
グローバルタスクのキュー(networking task source、global)で:
-
navigationParamsがnavigation paramsでなければ キャンセル・廃棄 (documentでprefetchRecord)して、残り手順を中止。
-
アサート:navigationParamsのresponseが prefetchRecordのredirect chainの 最終要素のresponseと一致すること。
-
完了(prefetchRecord、document)の実行。
-
-
-
status = responseのstatus
-
アサート:statusがリダイレクトステータスでない
-
statusがokステータスでなければ falseを返す
つまり、エラー応答は保存されず、ナビゲーション時再試行される。エラーが一時的 or prefetch用リクエストで生じた場合にナビゲーション成功可能性を高める。サーバーも `Sec-Purpose` リクエストヘッダー入りリクエストに応答拒否も可能。 -
trueを返す
103はokステータスでないが、early hintsはprefetchを妨げない。 このprefetch対応 判定は本応答(1xxステータスのないレスポンスのみに適用)。
なお、他記載の通りearly hintsは現状prefetch時無視される。
7. クッキー
[COOKIES]
は、`Set-Cookie`
レスポンスヘッダーフィールドを使って設定できる「クッキー」を定義しています。"uncredentialed"というパーティショニング方式が別個のネットワークパーティションキーの使用を強制するため、これらのクッキーはナビゲーション時に受信されたかのように通常のパーティションへコピーする必要があります。
-
isolatedCookieStoreを、isolatedPartitionKeyに紐付くクッキーストアとする。
-
isolatedCookieStoreに含まれる各cookie cookieについて:
-
cookieをisolatedCookieStoreから削除する。
-
ユーザーエージェントは特定のクッキーを丸ごと無視してよい。もし無視するなら続行する。
-
topLevelSiteをnullとする。
-
もしenvironmentのtarget browsing contextがトップレベルブラウジングコンテキストである場合:
-
topLevelSiteを、サイトの取得(tuple origin("
https", cookieのdomain, null, null)を与えて得られる値)に設定する。ここで"https"スキームとnullポートを使っているのは便宜上のもので、クッキーは通常の同一オリジンポリシーと異なりスキームやポートを越えて可視であるためです。したがってユーザーエージェントのクッキーストア選択はこれらに敏感であってはなりません。
トップレベルブラウジングコンテキストでプレフェッチを行う場合、リクエスト(リダイレクトを含む)はトップレベルナビゲーションの準備です。environmentのトップレベルサイトはリダイレクトに従って変わることがあり、リダイレクトがクロスサイトであれば、あるクッキーが受信された時点と現在でトップレベルサイトが変わっている可能性があります。しかしナビゲーションはトップレベルで行われるため、そのクッキーを配信したオリジンは当時のトップレベルサイトであったはずです。クッキーのdomainはそれを配信したオリジンとsame-siteである必要があるため、クッキーのdomainを用いて正しいトップレベルサイトを決定できます。 -
-
そうでなければ:
-
topLevelOriginをenvironmentのtop-level originとする。
-
もしtopLevelOriginがnullであれば、topLevelOriginにenvironmentのtop-level creation URLのoriginを設定する。
-
topLevelSiteを、サイトの取得(topLevelOriginを与えて)で得られる値に設定する。
子ナビゲーブルでプレフェッチを行う場合、トップレベルサイトはそれを包含するトップレベル traversableで決まります。それはリダイレクトに従って変わらないため、environmentを使ってトップレベルサイトを特定できます。 -
-
secondKeyをnullまたは実装依存の値とする。
secondKeyは、このレスポンスがenvironmentのターゲットブラウジングコンテキストで通常のナビゲーションの一部として処理された場合に持つであろう値と一致することが期待されます。 -
destinationPartitionKeyを(topLevelSite, secondKey)とする。
-
cookieStoreを、destinationPartitionKeyに紐付くクッキーストアとする。
-
newCookieをcookieのコピーとする。
-
newCookieの作成時刻および最終アクセス時刻を現在日時に設定する。
-
もしcookieStoreに、新規作成するクッキーと同じ名前・ドメイン・パスを持つクッキーexistingCookieが存在する場合:
-
newCookieの作成時刻をexistingCookieの作成時刻に設定する。
-
existingCookieをcookieStoreから削除する。
-
-
newCookieをcookieStoreに挿入する。
この削除して挿入するパターンは、クッキー受信時の振る舞いと一致します。
-
8. `Sec-Purpose`
HTTPリクエストヘッダー
この節は[FETCH]で定義される`Sec-Purpose`
HTTPリクエストヘッダーの定義を上書きします。
`Sec-Purpose`
HTTPリクエストヘッダーは、リクエストがユーザーによる即時利用以外の目的を持つことを示します。
このヘッダーフィールドは[RFC9651]のStructured Headerであり、その値はListでなければなりません。
このヘッダーは、Itemとしてprefetchトークン(Token)を含むことができます。もし含まれるなら、そのリクエストの目的は間もなく取得されると見込まれるリソースをダウンロードすることであることを示します。
以下はprefetchトークンのために定義されたパラメータです:
-
キーが"
anonymous-client-ip"のパラメータ。このパラメータがフィールド値でboolean false(
`?0`)以外の値で存在する場合、そのプレフェッチリクエストは匿名化されたクライアントIPを用いて実行されていることを示します。したがってサーバーは、その値が非プレフェッチリクエスト時のクライアントIPと一致する、あるいは地理的位置やネットワーク事業者を共有することを前提にしてはなりません。例えばリソースがクライアントの地理的位置に依存し、他に位置を特定する手段(例:Geohash client hint)もなく、位置に依存しない応答も用意できない場合、サーバーは適切なHTTPステータスコードとともにキャッシュに適さないことを示す応答ヘッダーで応答すべきです。
将来の仕様では非boolean値によりより具体的な意味を与える可能性がありますが、現時点ではそれらはtrueと同様に扱われます。実装はそのような値を送信しないことが推奨されます。本仕様はこの助言に従います;referrer起点のナビゲーションプレフェッチ開始アルゴリズムは非boolean値を出力しません。
-
キーが"
prerender"のパラメータ。このパラメータがフィールド値でboolean false(
`?0`)以外の値で存在する場合、そのプレフェッチリクエストはprerenderを見越して行われていることを示します。これは活性化前のprerendering navigable内から行われるリソース取得でも設定されます。将来の仕様では非boolean値に対してより具体的な意味付けがされる可能性がありますが、現状ではtrueと同等に扱われます。実装者はそのような値を出力しないことが推奨されます。本仕様はこの助言に従います;referrer起点のナビゲーションプレフェッチ開始アルゴリズムは非boolean値を出力しません。
9. 自動テスト
ユーザーエージェントの自動化およびアプリケーションテストの目的のために、本書は[WebDriver-BiDi] 仕様への拡張を定義します。
9.1. speculationモジュール
speculationモジュールは、prefetch、prerender、およびspeculationルールのリモート側の挙動を管理するコマンドを含みます。
9.1.1. 定義
speculation.PreloadingStatus = "pending" / "ready" / "success" / "failure"
speculation.PreloadingStatus型は、prefetchやprerenderで共有される様々なプリロード状態を表します。
- "
pending" - prefetch record prefetchRecordがreferrer起点のナビゲーションプレフェッチを開始する状態を表します。
- "
ready" - prefetch record prefetchRecordが完了している状態を表します。
- "
success" - prefetch record prefetchRecordがユーザーエージェントのナビゲーション等により活性化された状態を表します。
- "
failure" - prefetch record prefetchRecordが期限切れなどで失敗した状態を表します。
9.1.2. イベント
SpeculationEvent = ( speculation.PrefetchStatusUpdated )
9.1.2.1. speculation.prefetchStatusUpdated イベント
speculation.PrefetchStatusUpdated = ( method : "speculation.prefetchStatusUpdated" , params : speculation.PrefetchStatusUpdatedParameters ) speculation.PrefetchStatusUpdatedParameters = { context : text, url : text, status : speculation.PreloadingStatus }
speculation.PreloadingStatus
preloadingStatus:
-
paramsを、
speculation.PrefetchStatusUpdatedParametersに対応するmapとして作り、contextフィールドをnavigableのtop-level traversableのnavigable idに、urlフィールドをprefetchRecordのURLに、statusフィールドをpreloadingStatusに設定する。 -
bodyを、
speculation.PrefetchStatusUpdatedParametersに対応するmapとして作り、paramsフィールドに上のparamsを設定する。 -
relatedNavigablesを、setとして作り、navigableを含める。
-
"
speculation.prefetchStatusUpdated"およびrelatedNavigablesに対してイベントが有効になっているセッション群(set of sessions for which an event is enabled)の各sessionについて:-
イベントを発行する(引数はsessionとbody)。
-
10. セキュリティ考慮事項
詳細は HTML § 7.6.5 Security considerations を参照してください。
11. プライバシー考慮事項
詳細は HTML § 7.6.6 Privacy considerations を参照してください。