← Cross-origin redirect timing opt-in
v151 · fetch · internal state
navigation timing allow values list
The fetch bookkeeping that carries each redirect's Timing-Allow-Origin values through a navigation: a list (of lists of strings) on the request, populated per redirect by the append algorithm, and delivered to the final response as a clone. This page documents the request state, the response state, the append algorithm, and the cloning flow.
Syntax
// Fetch Standard — request bookkeeping (normative)
// A request has an associated
// navigation timing allow values list
// (a list of lists of strings), initially « ».
// A response has an associated
// navigation timing allow values list
// (a list of lists of strings), initially « ».
// Append step (runs for each redirect-status response of a
// navigation request, inside HTTP-redirect fetch):
// append to a request's navigation timing allow values list
// given request and internalResponse
Source: Fetch Standard — request navigation timing allow values list; Fetch Standard — append algorithm
Inputs
The append algorithm takes the navigation request and one redirect response. From that response it reads the Timing-Allow-Origin header using fetch's “get, decode, and split” header processing — producing a list of strings (serialized origins and/or *). A redirect response with no such header yields null from the header read, which the algorithm normalizes to an empty list before appending.
Outputs
Each item of the list holds one redirect's values, in chain order. The final internal response of the navigation receives a clone of the request's list (set during fetch's response handling for navigation requests), so that downstream callers — the HTML navigation steps — can evaluate the completed chain once the destination origin is known. This is state, not a page-observable value: no JavaScript API exposes it.
Source: Fetch Standard — request/response bookkeeping; whatwg/fetch PR #1931 (the cloning flow)Errors
The algorithms define no exception paths. The notable edge cases are normalization rules: a missing header becomes an empty list (which will fail the later navigation TAO check unless it contains * or the destination origin — an empty list contains neither), and the append asserts the request is a navigation request, so subresource fetches never populate this state.
Context
Where it lives: internal to the fetch machinery — request bookkeeping during the redirect chain, response bookkeeping on the final internal response. It is not web-exposed; it exists so that the navigation TAO check can run after the chain completes.
Trigger: the append runs inside HTTP-redirect fetch for each response whose status is a redirect status, but only when the request is a navigation request.
Availability: Chrome 151 per the milestone listing; runtime feature NavigationTimingRedirectTimingViaTAO (status stable at trunk).
Lifecycle
Flow, end to end: (1) navigation starts with an empty list; (2) each 3xx response appends its decoded Timing-Allow-Origin values (empty list if absent); (3) the final internal response is given a clone of the completed request list; (4) the HTML navigation steps read the response's clone and run the navigation TAO check with the destination origin. The list is per-navigation — it does not persist, and a new navigation starts empty.
Examples
// Chain: A.example → B.example → C.example (destination)
// Redirect 1 (A.example) sends: Timing-Allow-Origin: https://c.example
// Redirect 2 (B.example) sends: (no header)
//
// Request's navigation timing allow values list after the chain:
// « « "https://c.example" », « » »
// ^ redirect 1 ^ redirect 2 (empty — no header)
//
// The final response carries a clone of that list; the navigation
// TAO check over it will FAIL (redirect 2's entry contains neither
// "*" nor the destination origin) → redirect timing stays hidden.
Source: Fetch Standard — append algorithm; WPT navigation-timing/redirect-tao.html (withheld-header case)
Compatibility
| Engine / runtime | Support | Notes |
|---|---|---|
| Chrome | 151 | Milestone listing: Enabled by default (desktop, Android, WebView per the feature detail); runtime feature stable at trunk |
| Edge | Not separately reported | No Edge position recorded on ChromeStatus |
| Firefox | No signal | Vendor signal recorded on the ChromeStatus entry |
| Safari | Recorded positive signal | A recorded signal, not an official WebKit standards position |
Internal fetch state has no BCD entry of its own; feature signals per the ChromeStatus API feature record.
Source: ChromeStatus API feature recordSecurity and privacy
The list exists precisely to make disclosure consensual and auditable: it records what each redirect operator declared, so the browser can enforce that no redirect timing is exposed unless every hop allowed the destination. Because the collection is mechanical (decode/split per redirect, clone to the final response), a redirect cannot retroactively alter or revoke another hop's values, and the destination cannot read the list itself — only the boolean outcome, via the timing fields.
Source: whatwg/fetch PR #1931; Fetch Standard — navigation TAO check