1. Concepts
In light of storage partitioning, this specification defines prefetch for navigations which would occur within the same partition (for example, top-level navigations within the same site) and for navigations which would occur in a separate partition (for example, top-level navigations to a different site).
-
Let hypotheticalEnvironment be the result of creating a reserved client given navigable, response’s URL, and null.
-
Let hypotheticalPartitionKey be the result of determining the network partition key given hypotheticalEnvironment.
-
If hypotheticalPartitionKey is equal to sourcePartitionKey or there are no credentials associated with URL and hypotheticalPartitionKey, then return false.
-
Let loadingModes be the result of getting the supported loading modes for response.
-
If loadingModes contains `
uncredentialed-prefetch
` then return true. -
Return false.
An exchange record is a struct with the following items:
A redirect chain is a list of exchange records.
Each Document
has prefetch records, which is a list of prefetch records.
A prefetch record is a struct with the following items:
-
URL, a URL
-
anonymization policy, a prefetch IP anonymization policy
-
referrer policy, a referrer policy
-
No-Vary-Search hint, a URL search variance
-
label, a string
This is intended for use by a specification or implementation-defined feature to identify which prefetches it created. It might also associate other data with this struct. -
state, which is "
ongoing
" (the default), "completed
", or "canceled
""canceled
" indicates that the prefetch was aborted by the author or user, or terminated by the user agent. -
fetch controller, a fetch controller (a new fetch controller by default)
-
sandboxing flag set, a sandboxing flag set
-
redirect chain, a redirect chain (empty by default)
-
start time, a
DOMHighResTimeStamp
(0.0 by default) -
expiry time, a
DOMHighResTimeStamp
(0.0 by default) -
source partition key, a network partition key or null (the default)
-
isolated partition key, a network partition key whose first item is an opaque origin and which represents a separate partition in which cross-partition state can be temporarily stored, or null (the default)
-
had conflicting credentials, a boolean (initially false)
Unless the response indicates otherwise using `Supports-Loading-Mode
`, a request which would have ordinarily sent credentials but could not due to cross-partition prefetch causes a prefetch to be abandoned.
A prefetch record's response is the response of the last element of its redirect chain, or null if that list is empty.
The user agent may cancel and discard records from the prefetch records even if they are not expired, e.g., due to resource constraints. Since completed records with expiry times in the past will never be matching prefetch records, they can be removed with no observable consequences.
-
If prefetchRecord’s URL is equal to url, return true.
-
If prefetchRecord’s response is not null:
-
Let searchVariance be the result of obtaining a URL search variance given prefetchRecord’s response.
-
If prefetchRecord’s URL and url are equivalent modulo search variance given searchVariance, return true.
-
-
Otherwise, return false.
-
If prefetchRecord matches a URL given url, return true.
-
If prefetchRecord’s response is null:
-
Let searchVariance be prefetchRecord’s No-Vary-Search hint.
-
If prefetchRecord’s URL and url are equivalent modulo search variance given searchVariance, return true.
-
-
Otherwise, return false.
Document
document, perform the following steps.
-
Assert: prefetchRecord is in document’s prefetch records.
-
Set prefetchRecord’s state to "
canceled
". -
Abort prefetchRecord’s fetch controller. This will cause any ongoing fetch to be canceled and yield a network error.
-
Remove prefetchRecord from document’s prefetch records.
Document
document, perform the following steps.
-
Assert: document is fully active.
-
Let currentTime be the current high resolution time for the relevant global object of document.
-
Let expiryTime be currentTime + 300000 (i.e., five minutes).
-
Remove all elements of document’s prefetch records which have the same URL as prefetchRecord and whose state equals "
completed
". -
Set prefetchRecord’s state to "
completed
" and expiry time to expiryTime.
Document
document, URL url, and sandboxing flag set sandboxFlags, perform the following steps.
-
Assert: document is fully active.
-
Let exactRecord be null.
-
Let inexactRecord be null.
-
For each record of document’s prefetch records:
-
If record’s sandboxing flag set is empty and sandboxFlags is not empty, then continue.
Strictly speaking, it would still be possible for this to be valid if sandbox flags have been added to the container since prefetch but those flags would not cause an error due to cross origin opener policy. This is expected to be rare and so isn’t handled. -
If record’s URL is equal to url:
-
Set exactRecord to record.
-
-
If inexactRecord is null and record matches a URL given url:
-
Set inexactRecord to record.
-
-
Let recordToUse be exactRecord if exactRecord is not null, otherwise inexactRecord.
-
If recordToUse is not null:
-
Let currentTime be the current high resolution time for the relevant global object of document.
-
If recordToUse’s expiry time is less than currentTime, return null.
-
For each exchangeRecord of recordToUse’s redirect chain:
-
If conflicting credentials exist for exchangeRecord’s response given document’s node navigable and recordToUse’s source partition key, return null.
This handles the case where there were no cross-partition credentials initially, but there are now. User agents could use a slightly coarser algorithm, such as monitoring whether the cookies for the URL have been modified at all, or storing a hash, timestamp or revision number. -
-
Return recordToUse.
-
-
Return null.
It’s not obvious, but this doesn’t actually require that the prefetch have received the complete body, just the response headers. In particular, a navigation to a prefetched response might nonetheless not load instantaneously.
It might be possible to use cache response headers to determine when a response can be used multiple times, but given the short lifetime of the prefetch buffer it’s unclear whether this is worthwhile.
Document
document, URL url, and sandboxing flag set sandboxFlags, perform the following steps.
-
Assert: this is running in parallel.
-
Let cutoffTime be null.
-
While true:
-
Let completeRecord be the result of finding a matching complete prefetch record given document, url, and sandboxFlags.
-
If completeRecord is not null, return completeRecord.
-
Let potentialRecords be an empty list.
-
For each record of document’s prefetch records:
-
If all of the following are true, then append record to potentialRecords:
-
record’s state is "
ongoing
". -
record is expected to match a URL given url.
-
record’s sandboxing flag set is not empty or sandboxFlags is empty.
-
record’s expiry time is greater than the current high resolution time for the relevant global object of document.
-
cutoffTime is null or record’s start time is less than cutoffTime.
-
-
-
If potentialRecords is empty, return null.
-
Wait until the state of any element of document’s prefetch records changes.
-
If cutoffTime is null and any element of potentialRecords has a state that is not "
ongoing
", set cutoffTime to the current high resolution time for the relevant global object of document.
-
The reasoning for setting the cutoff time after waiting for a prefetch record to finish is to allow for flexibility in selecting a prefetch to serve the navigation while still guaranteeing falling back to a non-prefetched navigation in the case of repeated prefetch failures. We allow blocking on prefetch attempts which started before we see an attempt fail, but we don’t block on subsequent attempts. Notably, this approach: does not finalize the set of prefetches to block on at the start of the navigation; allows a prefetch which started and completed after the navigation started to serve the navigation; avoids the use of a fixed timeout, which would be arbitrary and detrimental to the use of prefetch with slower servers; and blocks on, at most, two nearly-consecutive prefetches before falling back to a conventional navigation.
NavigationTimingType
navTimingType, a request request, a prefetch record record, a target snapshot params targetSnapshotParams, and a source snapshot params sourceSnapshotParams, perform the following steps.
-
Let responseOrigin be null.
-
Let responseCOOP be null.
-
Let coopEnforcementResult be the result of creating a cross-origin opener policy enforcement result for navigation given navigable’s active document and documentState’s initiator origin.
-
Let finalSandboxFlags be an empty sandboxing flag set.
-
Let responsePolicyContainer be null.
-
Let urlList be an empty list.
-
For each exchangeRecord in record’s redirect chain:
-
Let response be exchangeRecord’s response.
-
Set responsePolicyContainer to the result of creating a policy container from a fetch response given response and request’s reserved client.
-
Set finalSandboxFlags to the union of targetSnapshotParams’s sandboxing flags and responsePolicyContainer’s CSP list's CSP-derived sandboxing flags.
-
Set responseOrigin to the result of determining the origin given response’s URL, finalSandboxFlags, documentState’s initiator origin, and null.
-
If navigable is a top-level traversable, then:
-
Set responseCOOP to the result of obtaining a cross-origin opener policy given response and request’s reserved client.
-
Assert: If finalSandboxFlags is not empty, then responseCOOP’s value is "
unsafe-none
".This is guaranteed since the sandboxing flags of the document cannot change to become non-empty since this was prefetched, and the check was not done for a different window. If this changes, this will need to be able to handle failure of this check.
-
Set coopEnforcementResult to the result of enforcing a response’s cross-origin opener policy given navigable’s active browsing context, response’s URL, responseOrigin, responseCOOP, coopEnforcementResult, and exchangeRecord’s request's referrer.
-
-
-
Set request’s URL list to urlList.
-
Let resultPolicyContainer be the result of determining navigation params policy container given record’s response's URL, documentState’s history policy container, sourceSnapshotParams’s source policy container, null, and responsePolicyContainer.
-
Let response be record’s response.
-
Optionally, set response to a clone of response.
An implementation might wish to do this if it believes that the prefetch will be consumed more than once. For example, if in the future the response is consumed by a prerender, that prerendering traversable might be destroyed through various means. Normally that would mean the response is discarded, but if the implementation performs this step, then the prefetched response will still be available to serve a future navigation. [PRERENDERING-REVAMPED]
-
If the user agent did not perform the previous optional step, then it must remove record from navigable’s active document's prefetch records.
-
Return a new navigation params, with:
- 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’s reserved client
- navigable
-
navigable
- navigation timing type
-
navTimingType
- fetch controller
-
record’s fetch controller
In the case where the above optional step is taken, and thus record could end up generating multiple navigation params via multiple calls to this algorithm, it is OK that all such navigation params share the same fetch controller. This is because the only use of a navigation params's fetch controller is to calculate navigation timing information, which we want to be the same for any reuses.
- commit early hints
-
null
- delivery type
-
"
navigational-prefetch
"This implies that early hints delivered for prefetched documents won’t be processed. This could be revised in the future if it is common for there to be useful resource hints which are not repeated in the main response headers. Since prefetches aren’t currently served until the response headers arrive, early hints would not be processed any earlier than ordinary response headers. It might be possible for a future specification to allow early hints found during prefetching to be used in some way.
A prefetch IP anonymization policy is either null or a cross-origin prefetch IP anonymization policy.
A cross-origin prefetch IP anonymization policy has an origin, which is an origin.
2. HTML Patches
This section contains patches to [HTML].
Add an additional item to navigation params as follows:
- delivery type
-
a string (corresponding to
PerformanceResourceTiming
delivery type)
Update all creation sites to supply an empty string, except for any in this document which supply a different value (in create navigation params from a prefetch record).
To create a reserved client given a navigable navigable, a URL url and an opaque origin or null isolationOrigin:
-
Let topLevelCreationURL be url.
-
Let topLevelOrigin be null.
-
If isolationOrigin is not null, then:
-
Set topLevelCreationURL to
about:blank
. -
Set topLevelOrigin to isolationOrigin.
-
-
Otherwise, if navigable is not a top-level traversable, then:
-
Let parentEnvironment be navigable’s parent's active document's relevant settings object.
-
Set topLevelCreationURL to parentEnvironment’s top-level creation URL.
-
Set topLevelOrigin to parentEnvironment’s top-level origin.
-
-
Return a new environment whose id is a unique opaque string, target browsing context is navigable’s active browsing context, creation URL is url, top-level creation URL is topLevelCreationURL, and top-level origin is topLevelOrigin.
To create a cross-origin opener policy enforcement result for navigation given a Document
activeDocument and an origin initiatorOrigin, return a new cross-origin opener policy enforcement result with
- url
-
activeDocument’s URL
- origin
-
activeDocument’s origin
- cross-origin opener policy
-
activeDocument’s cross-origin opener policy
- current context is navigation source
-
true if activeDocument’s origin is same origin with initiatorOrigin; otherwise false
To create a navigation request given a session history entry entry, an environment settings object fetchClient, a navigable container or null container, and a boolean hasTransientActivation, perform the following steps.
-
Let documentResource be entry’s document state's resource.
-
Let request be a new request, with
- url
-
entry’s URL
- policy container
-
entry’s document state's history policy container
- client
-
fetchClient
- destination
-
"
document
" - credentials mode
-
"
include
" - use-URL-credentials flag
-
set
- redirect mode
-
"
manual
" - mode
-
"
navigate
" - referrer
-
entry’s document state's request referrer
- referrer policy
-
entry’s document state's request referrer policy
-
If documentResource is a POST resource, then:
-
Set request’s method to
`POST`
. -
Set request’s body to documentResource’s request body.
-
Set
`Content-Type`
to documentResource’s request content-type in request’s header list.
-
-
If entry’s document state's reload pending is true, then set request’s reload-navigation flag.
-
Otherwise, if entry’s document state's ever populated is true, then set request’s history-navigation flag.
-
If hasTransientActivation is true, then set request’s user-activation to true.
-
If container is non-null:
-
If container has a browsing context scope origin, then set request’s origin to that browsing context scope origin.
-
Set request’s destination and initiator type to container’s local name.
-
-
Return request.
-
Otherwise, if both of the following are true:
-
entry’s URL's scheme is a fetch scheme; and
-
documentResource is null, or allowPOST is true and documentResource’s request body is not failure
then:
-
Let request be the result of creating a navigation request given entry, sourceSnapshotParams’s fetch client, navigable’s container, and sourceSnapshotParams’s has transient activation.
-
Set request’s replaces client id to navigable’s active document's relevant settings object's id.
-
Let prefetchRecord be the result of waiting for a matching prefetch record given navigable’s active document, entry’s URL, and targetSnapshotParams’s sandboxing flags.
-
If documentResource is null and prefetchRecord is not null:
-
Set navigationParams to the result of creating navigation params from a prefetch record given navigable, entry’s document state, navigationId, navTimingType, request, prefetchRecord, targetSnapshotParams, and sourceSnapshotParams.
-
Copy prefetch cookies given prefetchRecord’s isolated partition key and navigationParams’s reserved environment.
This copy is complete before continuing, in the sense that subresource fetches,document.cookie
, etc. can observe the cookies. If the prefetch never reached a cross-site URL, there will be no cookies to copy.
-
-
Otherwise:
-
Let coopEnforcementResult be the result of creating a cross-origin opener policy enforcement result for navigation given navigable’s active document and entry’s document state's initiator origin.
-
Set navigationParams to the result of creating navigation params by fetching given request, entry, coopEnforcementResult, navigable, sourceSnapshotParams, targetSnapshotParams, cspNavigationType, navigationId, and navTimingType.
-
-
To create navigation params by fetching given a request request, a session history entry entry, a cross-origin opener policy enforcement result coopEnforcementResult, a navigable navigable, a source snapshot params sourceSnapshotParams, a target snapshot params targetSnapshotParams, a string cspNavigationType, a navigation ID or null navigationId, a NavigationTimingType
navTimingType, and an optional prefetch record prefetchRecord, perform the following steps.
-
Assert: this is running in parallel.
-
Assert: request’s redirect mode is "
manual
". -
Assert: request’s reserved client is null.
-
Let response be null.
-
Let responseOrigin be null.
-
Let fetchController be null.
-
Let finalSandboxFlags be an empty sandboxing flag set.
-
Let responsePolicyContainer be null.
-
Let responseCOOP be a new cross-origin opener policy.
-
Let locationURL be null.
-
Let currentURL be request’s current URL.
-
Let commitEarlyHints be null.
-
Let isolationOrigin be null.
-
If prefetchRecord was given:
-
Let isolationSite be prefetchRecord’s isolated partition key[0].
-
Assert: isolationSite is an opaque origin.
-
Set isolationOrigin to isolationSite.
-
-
While true:
-
If request’s reserved client is not null and currentURL’s origin is not the same as request’s reserved client's creation URL's origin, then:
-
Run the environment discarding steps for request’s reserved client.
-
Set request’s reserved client to null.
-
Set commitEarlyHints to null.
-
-
If request’s reserved client is null, then set request’s reserved client to the result of creating a reserved client given navigable, currentURL and isolationOrigin.
-
If the result of should navigation request of type be blocked by Content Security Policy? given request and cspNavigationType is "
Blocked
", then set response to a network error and break. [CSP] -
If prefetchRecord was given, then:
-
If prefetchRecord’s anonymization policy requires anonymity for request, then:
-
Add a parameter whose key is "
anonymous-client-ip
" and whose value is true to theprefetch
token in purpose. -
The user agent must use a connection which anonymizes the client IP address (e.g., using a proxy) when fetching request, or set response to a network error and break.
At the moment, how IP anonymization is achieved is handwaved. This will probably be done in an implementation-defined manner using some kind of proxy or relay. Ideally this would be plumbed down to obtain a connection, and possibly even the mechanism could be further standardized.
-
-
Set a structured field value given (
`Sec-Purpose`
, purpose) in request’s header list.Implementations might also send vendor-specific headers, like Chromium’s`Purpose`
/`prefetch`
, Mozilla’s`X-moz`
/`prefetch`
, and WebKit’s`X-Purpose`
/`preview`
, for compatibility with existing server software. Over time we hope implementers and server software authors will adopt this common header. -
If request’s current URL is not potentially trustworthy, then set response to a network error and break.
This is intended to both reduce the likelihood of prefetch traffic being visible to an on-path attacker, and to encourage the use of cryptographic schemes over public networks. -
Let proposedPartitionKey be the result of determining the network partition key given request’s reserved client.
-
If proposedPartitionKey is not equal to prefetchRecord’s source partition key and request’s referrer policy is not in the list of sufficiently strict speculative navigation referrer policies, then set response to a network error and break.
In practice, this means that cross-site prefetches will abandon rather than expose more information about the referrer URL than the origin. -
If request cannot be fetched given prefetchRecord’s anonymization policy for an implementation-defined reason, then set response to a network error and break.
This explicitly acknowledges that implementations might have additional restrictions. For instance, anonymized traffic might not be possible to some hosts, such as those that are not publicly routable and those that have traffic advice declining private prefetch traffic. -
Append a new exchange record whose request is request and response is null to prefetchRecord’s redirect chain.
-
Set response to null.
-
If fetchController is null, then set fetchController to the result of fetching request, with processEarlyHintsResponse set to processEarlyHintsResponse as defined below, processResponse set to processResponse as defined below, and useParallelQueue set to true.
Let processEarlyHintsResponse be the following algorithm given a response earlyResponse:
-
If prefetchRecord was given and commitEarlyHints is null, then set commitEarlyHints to the result of processing early hint headers given earlyResponse and request’s reserved client.
Let processResponse be the following algorithm given a response fetchedResponse:
-
Set response to fetchedResponse.
-
-
Otherwise, process the next manual redirect for fetchController.
-
Wait until either response is non-null, or navigable’s ongoing navigation changes to no longer equal navigationId.
If the latter condition occurs, then abort fetchController, and return. Otherwise, proceed onward. This aborts prefetches the moment a navigation starts, which might not be desirable.
-
If request’s body is null, then set entry’s document state's resource to null.
-
Set responsePolicyContainer to the result of creating a policy container from a fetch response given response and request’s reserved client.
-
Set finalSandboxFlags to the union of targetSnapshotParams’s sandboxing flags and responsePolicyContainer’s CSP list's CSP-derived sandboxing flags.
-
Set responseOrigin to the result of determining the origin given response’s URL, finalSandboxFlags, entry’s document state's initiator origin, and null.
-
If navigable is a top-level traversable, then:
-
Set responseCOOP to the result of obtaining a cross-origin opener policy given response and request’s reserved client.
-
If prefetchRecord was given, then set responseCOOP’s reporting endpoint and report-only reporting endpoint to null. This allows COOP violation reports to be suppressed until the prefetch is used.
-
Set coopEnforcementResult to the result of enforcing a response’s cross-origin opener policy given navigable’s active browsing context, request’s URL, responseOrigin, responseCOOP, coopEnforcementResult, and request’s referrer.
-
If finalSandboxFlags is not empty and responseCOOP’s value is not "
unsafe-none
", then set response to an appropriate network error and break.
-
-
If response is not a network error, navigable is a child navigable, and the result of performing a cross-origin resource policy check with navigable’s container document's origin, navigable’s container document's relevant settings object, request’s destination, response, and true is blocked, then set response to a network error and break.
-
If prefetchRecord was given, then:
-
Update the response for its redirect chain given request and response.
-
If conflicting credentials exist for response given navigable and prefetchRecord’s source partition key, then set prefetchRecord’s had conflicting credentials to true.
This does not immediately abort the prefetch or stop following redirects, because doing so might reveal whether or not the user has stored state outside the current partition, before the user navigates. Instead, the prefetch continues as though there were no conflicting credentials, except that the prefetch cannot actually be used. User agents might wish to report a warning to the console or otherwise inform authors that this has happened.
-
-
Set locationURL to response’s location URL given currentURL’s fragment.
-
If locationURL is failure or null, then break.
-
Set entry’s serialized state to StructuredSerializeForStorage(null).
-
Let oldDocState be entry’s document state.
-
Set entry’s document state to a new document state, with:
- history policy container
-
a clone of oldDocState’s history policy container
- request referrer
-
oldDocState’s request referrer
- request referrer policy
-
oldDocState’s request referrer policy
- origin
-
oldDocState’s origin
- resource
-
oldDocState’s resource
- ever populated
-
oldDocState’s ever populated
- navigable target name
-
oldDocState’s navigable target name
-
If locationURL’s scheme is not an HTTP(S) scheme, then:
-
Set entry’s document state's resource to null.
-
-
Set currentURL to locationURL.
-
Set entry’s URL to currentURL.
-
-
If locationURL is a URL whose scheme is not a fetch scheme, then return a new non-fetch scheme navigation params, with:
- initiator origin
-
request’s current URL's origin
-
If any of the following are true:
-
response is a network error;
-
locationURL is failure; or
-
locationURL is a URL whose scheme is a fetch scheme
-
-
Let resultPolicyContainer be the result of determining navigation params policy container given response’s URL, entry’s document state's history policy container, sourceSnapshotParams’s source policy container, null, and responsePolicyContainer.
-
Return a new navigation params, with:
- 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’s reserved client
- navigable
-
navigable
- navigation timing type
-
navTimingType
- fetch controller
-
fetchController
- commit early hints
-
commitEarlyHints
3. Navigation Timing Patches
This section contains patches to [NAVIGATION-TIMING].
4. Prefetch algorithms
Check Service Worker integration
The list of sufficiently strict speculative navigation referrer policies is a list containing the following: "", "strict-origin-when-cross-origin
", "strict-origin
", "same-origin
", "no-referrer
".
Document
document and a prefetch record prefetchRecord, perform the following steps.
-
Let sourceSnapshotParams be the result of snapshotting source snapshot params given document.
-
Let targetSnapshotParams be the result of snapshotting target snapshot params given document’s node navigable.
-
Set prefetchRecord’s source partition key to the result of determining the network partition key given document’s relevant settings object.
-
Assert: prefetchRecord’s URL's scheme is an HTTP(S) scheme.
-
Append prefetchRecord to document’s prefetch records
-
Set prefetchRecord’s start time to the current high resolution time for the relevant global object of document.
-
Set prefetchRecord’s sandboxing flag set to the result of determining the creation sandboxing flags for document’s browsing context given document’s node navigable's container.
-
Let referrerPolicy be prefetchRecord’s referrer policy if prefetchRecord’s referrer policy is not the empty string, and document’s policy container's referrer policy otherwise.
-
Let documentState be a new document state with
- request referrer policy
-
referrerPolicy
- initiator origin
-
document’s origin
-
Let entry be a new session history entry with
- URL
-
prefetchRecord’s URL
- document state
-
documentState
-
Let request be the result of creating a navigation request given entry, document’s relevant settings object, document’s node navigable's container, and false.
-
Let coopEnforcementResult be the result of creating a cross-origin opener policy enforcement result for navigation given document and document’s origin.
-
Let global be document’s relevant global object.
-
-
Let navigationParams be the result of creating navigation params by fetching given request, entry, coopEnforcementResult, document’s node navigable, sourceSnapshotParams, targetSnapshotParams, "
other
", null (navigationId), "navigate
", and prefetchRecord prefetchRecord. -
If navigationParams’s response does not support prefetch, then set navigationParams to null.
-
If prefetchRecord’s had conflicting credentials is true, then set navigationParams to null.
This means that if any cross-partition origin along the redirect chain had credentials (and did not override this behavior using `Supports-Loading-Mode
`), the prefetch is discarded. This reduces the chance of the user observing a logged-out page when they are logged in. -
Queue a global task on the networking task source, given global, to:
-
If navigationParams is not a navigation params, then cancel and discard prefetchRecord given document and abort these steps.
-
Assert: navigationParams’s response is the response of prefetchRecord’s redirect chain's last element.
-
Complete prefetchRecord given document.
-
-
-
Let status be response’s status.
-
Assert: status is not a redirect status.
-
If status is not an ok status, then return false.
In particular, this means that error responses aren’t stored and will be retried when a navigation occurs. This increases the likelihood of navigations succeeding if the error was transient or due to the request being for prefetch. It also gives server software a simple way to refuse to handle requests which carry a`Sec-Purpose`
request header indicating prefetch. -
Return true.
5. Cookies
[COOKIES] defines "cookies" which can be set using the `Set-Cookie`
response header field. Because the "uncredentialed
" partitioning scheme forces a separate network partition key to be used, it’s necessary to copy these cookies into the ordinary partition as though they had been received at the time of navigation.
-
Let isolatedCookieStore be the cookie store associated with isolatedPartitionKey.
-
For each cookie cookie in isolatedCookieStore.
-
Remove cookie from isolatedCookieStore.
-
A user agent may ignore a cookie in its entirety. If so, continue.
This is consistent with [COOKIES] expressly permitting this when receiving a cookie. -
Let topLevelSite be null.
-
If environment’s target browsing context is a top-level browsing context:
-
Set topLevelSite to the result of obtaining a site given tuple origin ("
https
", cookie’s domain, null, null).The use of the "https
" scheme and null port here is arbitrary because cookies are visible across schemes and ports, in contrast to the usual same origin policy. The user agent’s choice of associated cookie store, therefore, cannot be sensitive to either.
When performing a prefetch in a top-level browsing context, the request (including all redirects) is preparing for a top-level navigation. environment’s top-level site changes as redirects are followed, and since a redirect might be cross-site, environment’s top-level site might have changed since a given cookie was received. However, since the navigation is top-level, the origin delivering the cookie would have been the top-level site at the time. Since the cookie’s domain has to be same-site with an origin delivering it, the cookie’s domain can be used to determine the correct top-level site. -
-
Otherwise:
-
Let topLevelOrigin be environment’s top-level origin.
-
If topLevelOrigin is null, then set topLevelOrigin to environment’s top-level creation URL's origin.
-
Set topLevelSite be the result of obtaining a site given topLevelOrigin.
When performing a prefetch in a child navigable, the top-level site is determined by the top-level traversable that contains it. Since that doesn’t change as redirects are followed, environment can be used to establish the top-level site. -
-
Let secondKey be null or an implementation-defined value.
secondKey is expected to match the value it would have had if this response had been processed as part of an ordinary navigation in environment’s target browsing context. -
Let destinationPartitionKey be (topLevelSite, secondKey).
-
Let cookieStore be the cookie store associated with destinationPartitionKey.
-
Let newCookie be a copy of cookie.
-
Set newCookie’s creation-time and last-access-time to the current date and time.
-
If cookieStore contains a cookie existingCookie with the same name, domain and path as the newly created cookie:
-
Set the creation-time of newCookie to existingCookie’s creation-time.
-
Remove existingCookie from cookieStore.
-
-
Insert newCookie into cookieStore.
This remove-and-insert pattern is consistent with what happens when receiving a cookie.
-
6. The Sec-Purpose
HTTP request header
The `Sec-Purpose`
HTTP request header specifies that the request serves one or more purposes other than requesting the resource for immediate use by the user.
The header field is an [RFC9651] Structured Header whose value must be a List. Its ABNF is:
Sec-Purpose = sf-list
It may contain an Item member which is the Token "prefetch
". If so, this indicates the request’s purpose is to download a resource it is anticipated will be fetched shortly.
The following parameters are defined for the "prefetch
" token:
-
A parameter whose key is "
anonymous-client-ip
".If present with a value other than boolean false (
`?0`
in the field value), this parameter indicates that the prefetch request is being made using an anonymous client IP. Consequently, servers should not rely on it matching, or sharing a geographic location or network operator with, the client’s IP address from which a non-prefetch request would have been made.If a suitable response is not possible, for example because the resource depends on the client’s geographic location, there is no other means of determining the location (e.g., the Geohash client hint), and no location-agnostic response is available, then the server should respond with an appropriate HTTP status code and response headers which mark the response as not suitable for caching.
A future specification might define assign more specific meaning to non-boolean values. For now, they are treated the same as true. Implementations are advised not to emit such values.This specification conforms to this advice; the prefetch algorithm does not emit non-boolean values.
7. Security considerations
See Security considerations (Speculation Rules).
For the integration of this spec with No-Vary-Search, see No-Vary-Search Security considerations.
8. Privacy considerations
See Privacy considerations (Speculation Rules).
For the integration of this spec with No-Vary-Search, see No-Vary-Search Privacy considerations.