1. 7.5 Document lifecycle
      1. 7.5.1 Shared document creation infrastructure
      2. 7.5.2 Loading HTML documents
      3. 7.5.3 Loading XML documents
      4. 7.5.4 Loading text documents
      5. 7.5.5 Loading multipart/x-mixed-replace documents
      6. 7.5.6 Loading media documents
      7. 7.5.7 Loading a document for inline content that doesn't have a DOM
      8. 7.5.8 Finishing the loading process
      9. 7.5.9 Unloading documents
      10. 7.5.10 Destroying documents
      11. 7.5.11 Aborting a document load
    2. 7.6 The `X-Frame-Options` header
    3. 7.7 The `Refresh` header
    4. 7.8 Browser user interface considerations

7.5 Document lifecycle

7.5.1 Shared document creation infrastructure

When loading a document using one of the below algorithms, we use the following steps to create and initialize a Document object, given a type type, content type contentType, and navigation params navigationParams:

Document objects are also created when creating a new browsing context and document; such initial about:blank Document are never created by this algorithm. Also, browsing context-less Document objects can be created via various APIs, such as document.implementation.createHTMLDocument().

  1. Let browsingContext be navigationParams's navigable's active browsing context.

  2. Set browsingContext to the result of the obtaining a browsing context to use for a navigation response given browsingContext, navigationParams's final sandboxing flag set, navigationParams's cross-origin opener policy, and navigationParams's COOP enforcement result.

    This can result in a browsing context group switch, in which case browsingContext will be a newly-created browsing context instead of being navigationParams's navigable's active browsing context. In such a case, the created Window, Document, and agent will not end up being used; because the created Document's origin is opaque, we will end up creating a new agent and Window later in this algorithm to go along with the new Document.

  3. Let permissionsPolicy be the result of creating a permissions policy from a response given navigationParams's navigable's container, navigationParams's origin, and navigationParams's response. [PERMISSIONSPOLICY]

    The creating a permissions policy from a response algorithm makes use of the passed origin. If document.domain has been used for navigationParams's navigable's container document, then its origin cannot be same origin-domain with the passed origin, because these steps run before the document is created, so it cannot itself yet have used document.domain. Note that this means that Permissions Policy checks are less permissive compared to doing a same origin check instead.

    See below for some examples of this in action.

  4. Let creationURL be navigationParams's response's URL.

  5. If navigationParams's request is non-null, then set creationURL to navigationParams's request's current URL.

  6. Let window be null.

  7. If browsingContext's active document's is initial about:blank is true, and browsingContext's active document's origin is same origin-domain with navigationParams's origin, then set window to browsingContext's active window.

    This means that both the initial about:blank Document, and the new Document that is about to be created, will share the same Window object.

  8. Otherwise:

    1. Let oacHeader be the result of getting a structured field value given `Origin-Agent-Cluster` and "item" from navigationParams's response's header list.

    2. Let requestsOAC be true if oacHeader is not null and oacHeader[0] is the boolean true; otherwise false.

    3. If navigationParams's reserved environment is a non-secure context, then set requestsOAC to false.

    4. Let agent be the result of obtaining a similar-origin window agent given navigationParams's origin, browsingContext's group, and requestsOAC.

    5. Let realmExecutionContext be the result of creating a new realm given agent and the following customizations:

      • For the global object, create a new Window object.

      • For the global this binding, use browsingContext's WindowProxy object.

    6. Set window to the global object of realmExecutionContext's Realm component.

    7. Let topLevelCreationURL be creationURL.

    8. Let topLevelOrigin be navigationParams's origin.

    9. If navigable's container is not null, then:

      1. Let parentEnvironment be navigable's container's relevant settings object.

      2. Set topLevelCreationURL to parentEnvironment's top-level creation URL.

      3. Set topLevelOrigin to parentEnvironment's top-level origin.

    10. Set up a window environment settings object with creationURL, realmExecutionContext, navigationParams's reserved environment, topLevelCreationURL, and topLevelOrigin.

    This is the usual case, where the new Document we're about to create gets a new Window to go along with it.

  9. Let loadTimingInfo be a new document load timing info with its navigation start time set to navigationParams's response's timing info's start time.

  10. Let document be a new Document, with

    type
    type
    content type
    contentType
    origin
    navigationParams's origin
    browsing context
    browsingContext
    policy container
    navigationParams's policy container
    permissions policy
    permissionsPolicy
    active sandboxing flag set
    navigationParams's final sandboxing flag set
    opener policy
    navigationParams's cross-origin opener policy
    load timing info
    loadTimingInfo
    was created via cross-origin redirects
    navigationParams's response's has cross-origin redirects
    during-loading navigation ID for WebDriver BiDi
    navigationParams's id
    URL
    creationURL
    current document readiness
    "loading"
    about base URL
    navigationParams's about base URL
    allow declarative shadow roots
    true
  11. Set window's associated Document to document.

  12. Run CSP initialization for a Document given document. [CSP]

  13. If navigationParams's request is non-null, then:

    1. Set document's referrer to the empty string.

    2. Let referrer be navigationParams's request's referrer.

    3. If referrer is a URL record, then set document's referrer to the serialization of referrer.

      Per Fetch, referrer will be either a URL record or "no-referrer" at this point.

  14. If navigationParams's fetch controller is not null, then:

    1. Let fullTimingInfo be the result of extracting the full timing info from navigationParams's fetch controller.

    2. Let redirectCount be 0 if navigationParams's response's has cross-origin redirects is true; otherwise navigationParams's request's redirect count.

    3. Create the navigation timing entry for document, given fullTimingInfo, redirectCount, navigationTimingType, navigationParams's response's service worker timing info, and navigationParams's response's body info.

  15. Create the navigation timing entry for document, with navigationParams's response's timing info, redirectCount, navigationParams's navigation timing type, and navigationParams's response's service worker timing info.

  16. If navigationParams's response has a `Refresh` header, then:

    1. Let value be the isomorphic decoding of the value of the header.

    2. Run the shared declarative refresh steps with document and value.

    We do not currently have a spec for how to handle multiple `Refresh` headers. This is tracked as issue #2900.

  17. If navigationParams's commit early hints is not null, then call navigationParams's commit early hints with document.

  18. Process link headers given document, navigationParams's response, and "pre-media".

  19. Return document.

In this example, the child document is not allowed to use PaymentRequest, despite being same origin-domain at the time the child document tries to use it. At the time the child document is initialized, only the parent document has set document.domain, and the child document has not.

<!-- https://foo.example.com/a.html -->
<!doctype html>
<script>
document.domain = 'example.com';
</script>
<iframe src=b.html></iframe>
<!-- https://bar.example.com/b.html -->
<!doctype html>
<script>
document.domain = 'example.com'; // This happens after the document is initialized
new PaymentRequest(); // Not allowed to use
</script>

In this example, the child document is allowed to use PaymentRequest, despite not being same origin-domain at the time the child document tries to use it. At the time the child document is initialized, none of the documents have set document.domain yet so same origin-domain falls back to a normal same origin check.

<!-- https://example.com/a.html -->
<!doctype html>
<iframe src=b.html></iframe>
<!-- The child document is now initialized, before the script below is run. -->
<script>
document.domain = 'example.com';
</script>
<!-- https://example.com/b.html -->
<!doctype html>
<script>
new PaymentRequest(); // Allowed to use
</script>

To populate with html/head/body given a Document document:

  1. Let html be the result of creating an element given document, html, and the HTML namespace.

  2. Let head be the result of creating an element given document, head, and the HTML namespace.

  3. Let body be the result of creating an element given document, body, and the HTML namespace.

  4. Append html to document.

  5. Append head to html.

  6. Append body to html.

7.5.2 Loading HTML documents

To load an HTML document, given navigation params navigationParams:

  1. Let document be the result of creating and initializing a Document object given "html", "text/html", and navigationParams.

  2. If document's URL is about:blank, then populate with html/head/body given document.

    This special case, where even non-initial about:blank Documents are synchronously given their element nodes, is necessary for compatible with deployed content. In other words, it is not compatible to instead go down the "otherwise" branch and feed the empty byte sequence into an HTML parser to asynchronously populate document.

  3. Otherwise, create an HTML parser and associate it with the document. Each task that the networking task source places on the task queue while fetching runs must then fill the parser's input byte stream with the fetched bytes and cause the HTML parser to perform the appropriate processing of the input stream.

    The first task that the networking task source places on the task queue while fetching runs must process link headers given document, navigationParams's response, and "media", after the task has been processed by the HTML parser.

    Before any script execution occurs, the user agent must wait for scripts may run for the newly-created document to be true for document.

    The input byte stream converts bytes into characters for use in the tokenizer. This process relies, in part, on character encoding information found in the real Content-Type metadata of the resource; the computed type is not used for this purpose.

    When no more bytes are available, the user agent must queue a global task on the networking task source given document's relevant global object to have the parser process the implied EOF character, which eventually causes a load event to be fired.

  4. Return document.

7.5.3 Loading XML documents

When faced with displaying an XML file inline, provided navigation params navigationParams and a string type, user agents must follow the requirements defined in XML and Namespaces in XML, XML Media Types, DOM, and other relevant specifications to create and initialize a Document object document, given "xml", type, and navigationParams, and return that Document. They must also create a corresponding XML parser. [XML] [XMLNS] [RFC7303] [DOM]

At the time of writing, the XML specification community had not actually yet specified how XML and the DOM interact.

The first task that the networking task source places on the task queue while fetching runs must process link headers given document, navigationParams's response, and "media", after the task has been processed by the XML parser.

The actual HTTP headers and other metadata, not the headers as mutated or implied by the algorithms given in this specification, are the ones that must be used when determining the character encoding according to the rules given in the above specifications. Once the character encoding is established, the document's character encoding must be set to that character encoding.

Before any script execution occurs, the user agent must wait for scripts may run for the newly-created document to be true for the newly-created Document.

Once parsing is complete, the user agent must set document's during-loading navigation ID for WebDriver BiDi to null.

For HTML documents this is reset when parsing is complete, after firing the load event.

Error messages from the parse process (e.g., XML namespace well-formedness errors) may be reported inline by mutating the Document.

7.5.4 Loading text documents

To load a text document, given a navigation params navigationParams and a string type:

  1. Let document be the result of creating and initializing a Document object given "html", type, and navigationParams.

  2. Set document's parser cannot change the mode flag to true.

  3. Set document's mode to "no-quirks".

  4. Create an HTML parser and associate it with the document. Act as if the tokenizer had emitted a start tag token with the tag name "pre" followed by a single U+000A LINE FEED (LF) character, and switch the HTML parser's tokenizer to the PLAINTEXT state. Each task that the networking task source places on the task queue while fetching runs must then fill the parser's input byte stream with the fetched bytes and cause the HTML parser to perform the appropriate processing of the input stream.

    document's encoding must be set to the character encoding used to decode the document during parsing.

    The first task that the networking task source places on the task queue while fetching runs must process link headers given document, navigationParams's response, and "media", after the task has been processed by the HTML parser.

    Before any script execution occurs, the user agent must wait for scripts may run for the newly-created document to be true for document.

    When no more bytes are available, the user agent must queue a global task on the networking task source given document's relevant global object to have the parser process the implied EOF character, which eventually causes a load event to be fired.

  5. User agents may add content to the head element of document, e.g., linking to a style sheet, providing script, or giving the document a title.

    In particular, if the user agent supports the Format=Flowed feature of RFC 3676 then the user agent would need to apply extra styling to cause the text to wrap correctly and to handle the quoting feature. This could be performed using, e.g., a CSS extension.

  6. Return document.

The rules for how to convert the bytes of the plain text document into actual characters, and the rules for actually rendering the text to the user, are defined by the specifications for the computed MIME type of the resource (i.e., type).

7.5.5 Loading multipart/x-mixed-replace documents

To load a multipart/x-mixed-replace document, given navigation params navigationParams, source snapshot params sourceSnapshotParams, and origin initiatorOrigin:

  1. Parse navigationParams's response's body using the rules for multipart types. [RFC2046]

  2. Let firstPartNavigationParams be a copy of navigationParams.

  3. Set firstPartNavigationParams's response to a new response representing the first part of navigationParams's response's body's multipart stream.

  4. Let document be the result of loading a document given firstPartNavigationParams, sourceSnapshotParams, and initiatorOrigin.

    For each additional body part obtained from navigationParams's response, the user agent must navigate document's node navigable to navigationParams's request's URL, using document, with response set to navigationParams's response and historyHandling set to "replace".

  5. Return document.

For the purposes of algorithms processing these body parts as if they were complete stand-alone resources, the user agent must act as if there were no more bytes for those resources whenever the boundary following the body part is reached.

Thus, load events (and for that matter unload events) do fire for each body part loaded.

7.5.6 Loading media documents

To load a media document, given navigationParams and a string type:

  1. Let document be the result of creating and initializing a Document object given "html", type, and navigationParams.

  2. Set document's mode to "no-quirks".

  3. Populate with html/head/body given document.

  4. Append an element host element for the media, as described below, to the body element.

  5. Set the appropriate attribute of the element host element, as described below, to the address of the image, video, or audio resource.

  6. User agents may add content to the head element of document, or attributes to host element, e.g., to link to a style sheet, to provide a script, to give the document a title, or to make the media autoplay.

  7. Process link headers given document, navigationParams's response, and "media".

  8. Act as if the user agent had stopped parsing document.

  9. Return document.

The element host element to create for the media is the element given in the table below in the second cell of the row whose first cell describes the media. The appropriate attribute to set is the one given by the third cell in that same row.

Type of media Element for the media Appropriate attribute
Image img src
Video video src
Audio audio src

Before any script execution occurs, the user agent must wait for scripts may run for the newly-created document to be true for the Document.

7.5.7 Loading a document for inline content that doesn't have a DOM

When the user agent is to create a document to display a user agent page or PDF viewer inline, provided a navigable navigable, a navigation ID navigationId, a NavigationTimingType navTimingType, the user agent should:

  1. Let origin be a new opaque origin.

  2. Let coop be a new opener policy.

  3. Let coopEnforcementResult be a new opener policy enforcement result with

    url
    response's URL
    origin
    origin
    opener policy
    coop
  4. Let navigationParams be a new navigation params with

    id
    navigationId
    navigable
    navigable
    request
    null
    response
    a new response
    origin
    origin
    fetch controller
    null
    commit early hints
    null
    COOP enforcement result
    coopEnforcementResult
    reserved environment
    null
    policy container
    a new policy container
    final sandboxing flag set
    an empty set
    opener policy
    coop
    navigation timing type
    navTimingType
    about base URL
    null
  5. Let document be the result of creating and initializing a Document object given "html", "text/html", and navigationParams.

  6. Either associate document with a custom rendering that is not rendered using the normal Document rendering rules, or mutate document until it represents the content the user agent wants to render.

  7. Return document.

Because we ensure the resulting Document's origin is opaque, and the resulting Document cannot run script with access to the DOM, the existence and properties of this Document are not observable to web developer code. This means that most of the above values, e.g., the text/html type, do not matter. Similarly, most of the items in navigationParams don't have any observable effect, besides preventing the Document-creation algorithm from getting confused, and so are set to default values.

Once the page has been set up, the user agent must act as if it had stopped parsing.

7.5.8 Finishing the loading process

A Document has a completely loaded time (a time or null), which is initially null.

A Document is considered completely loaded if its completely loaded time is non-null.

To completely finish loading a Document document:

  1. Assert: document's browsing context is non-null.

  2. Set document's completely loaded time to the current time.

  3. Let container be document's node navigable's container.

    This will be null in the case where document is the initial about:blank Document in a frame or iframe, since at the point of browsing context creation which calls this algorithm, the container relationship has not yet been established. (That happens in a subsequent step of create a new child navigable.)

    The consequence of this is that the following steps do nothing, i.e., we do not fire an asynchronous load event on the container element for such cases. Instead, a synchronous load event is fired in a special initial-insertion case when processing the iframe attributes.

  4. If container is an iframe element, then queue an element task on the DOM manipulation task source given container to run the iframe load event steps given container.

  5. Otherwise, if container is non-null, then queue an element task on the DOM manipulation task source given container to fire an event named load at container.

7.5.9 Unloading documents

A Document has a salvageable state, which must initially be true, and a page showing flag, which must initially be false. The page showing flag is used to ensure that scripts receive pageshow and pagehide events in a consistent manner (e.g. that they never receive two pagehide events in a row without an intervening pageshow, or vice versa).

A Document has a DOMHighResTimeStamp suspension time, initially 0.

A Document has a list of suspended timer handles, initially empty.

Event loops have a termination nesting level counter, which must initially be 0.

Document objects have an unload counter, which is used to ignore certain operations while the below algorithms run. Initially, the counter must be set to zero.

To unload a Document oldDocument, given an optional Document newDocument:

  1. Assert: this is running as part of a task queued on oldDocument's relevant agent's event loop.

  2. Let unloadTimingInfo be a new document unload timing info.

  3. If newDocument is not given, then set unloadTimingInfo to null.

    In this case there is no new document that needs to know about how long it took oldDocument to unload.

  4. Otherwise, if newDocument's event loop is not oldDocument's event loop, then the user agent may be unloading oldDocument in parallel. In that case, the user agent should set unloadTimingInfo to null.

    In this case newDocument's loading is not impacted by how long it takes to unload oldDocument, so it would be meaningless to communicate that timing info.

  5. Let intendToKeepInBfcache be true if the user agent intends to keep oldDocument alive in a session history entry, such that it can later be used for history traversal.

    This must be false if oldDocument is not salvageable, or if there are any descendants of oldDocument which the user agent does not intend to keep alive in the same way (including due to their lack of salvageability).

  6. Let eventLoop be oldDocument's relevant agent's event loop.

  7. Increase eventLoop's termination nesting level by 1.

  8. Increase oldDocument's unload counter by 1.

  9. If intendToKeepInBfcache is false, then set oldDocument's salvageable state to false.

  10. If oldDocument's page showing is true:

    1. Set oldDocument's page showing to false.

    2. Fire a page transition event named pagehide at oldDocument's relevant global object with oldDocument's salvageable state.

    3. Update the visibility state of oldDocument to "hidden".

  11. If unloadTimingInfo is not null, then set unloadTimingInfo's unload event start time to the current high resolution time given newDocument's relevant global object, coarsened given oldDocument's relevant settings object's cross-origin isolated capability.

  12. If oldDocument's salvageable state is false, then fire an event named unload at oldDocument's relevant global object, with legacy target override flag set.

  13. If unloadTimingInfo is not null, then set unloadTimingInfo's unload event end time to the current high resolution time given newDocument's relevant global object, coarsened given oldDocument's relevant settings object's cross-origin isolated capability.

  14. Decrease eventLoop's termination nesting level by 1.

  15. Set oldDocument's suspension time to the current high resolution time given document's relevant global object.

  16. Set oldDocument's suspended timer handles to the result of getting the keys for the map of active timers.

  17. Set oldDocument's has been scrolled by the user to false.

  18. Run any unloading document cleanup steps for oldDocument that are defined by this specification and other applicable specifications.

  19. If oldDocument's node navigable is a top-level traversable, build not restored reasons for a top-level traversable and its descendants given oldDocument's node navigable.

  20. If oldDocument's salvageable state is false, then destroy oldDocument.

  21. Decrease oldDocument's unload counter by 1.

  22. If newDocument is given, newDocument's was created via cross-origin redirects is false, and newDocument's origin is the same as oldDocument's origin, then set newDocument's previous document unload timing to unloadTimingInfo.

To unload a document and its descendants, given a Document document, an optional Document-or-null newDocument (default null), an optional set of steps afterAllUnloads, and an optional set of steps firePageSwapSteps:

  1. Assert: this is running within document's node navigable's traversable navigable's session history traversal queue.

  2. Let childNavigables be document's child navigables.

  3. Let numberUnloaded be 0.

  4. For each childNavigable of childNavigable's in what order?, queue a global task on the navigation and traversal task source given childNavigable's active window to perform the following steps:

    1. Let incrementUnloaded be an algorithm step which increments numberUnloaded.

    2. Unload a document and its descendants given childNavigable's active document, null, and incrementUnloaded.

  5. Wait until numberUnloaded equals childNavigable's size.

  6. Queue a global task on the navigation and traversal task source given document's relevant global object to perform the following steps:

    1. If firePageSwapSteps is given, then run firePageSwapSteps.

    2. Unload document, passing along newDocument if it is not null.

    3. If afterAllUnloads was given, then run it.

This specification defines the following unloading document cleanup steps. Other specifications can define more. Given a Document document:

  1. Let window be document's relevant global object.

  2. For each WebSocket object webSocket whose relevant global object is window, make disappear webSocket.

    If this affected any WebSocket objects, then make document unsalvageable given document and "websocket".

  3. For each WebTransport object transport whose relevant global object is window, run the context cleanup steps given transport.

  4. If document's salvageable state is false, then:

    1. For each EventSource object eventSource whose relevant global object is equal to window, forcibly close eventSource.

    2. Clear window's map of active timers.

It would be better if specification authors sent a pull request to add calls from here into their specifications directly, instead of using the unloading document cleanup steps hook, to ensure well-defined cross-specification call order. As of the time of this writing the following specifications are known to have unloading document cleanup steps, which will be run in an unspecified order: Fullscreen API, Web NFC, WebDriver BiDi, Compute Pressure, File API, Media Capture and Streams, Picture-in-Picture, Screen Orientation, Service Workers, WebLocks API, WebAudio API, WebRTC. [FULLSCREEN] [WEBNFC] [WEBDRIVERBIDI] [COMPUTEPRESSURE] [FILEAPI] [MEDIASTREAM] [PICTUREINPICTURE] [SCREENORIENTATION] [SW] [WEBLOCKS] [WEBAUDIO] [WEBRTC]

Issue #8906 tracks the work to make the order of these steps clear.

7.5.10 Destroying documents

To destroy a Document document:

  1. Assert: this is running as part of a task queued on document's relevant agent's event loop.

  2. Abort document.

  3. Set document's salvageable state to false.

  4. Let ports be the list of MessagePorts whose relevant global object's associated Document is document.

  5. For each port in ports, disentangle port.

  6. Run any unloading document cleanup steps for document that are defined by this specification and other applicable specifications.

  7. Remove any tasks whose document is document from any task queue (without running those tasks).

  8. Set document's browsing context to null.

  9. Set document's node navigable's active session history entry's document state's document to null.

  10. Remove document from the owner set of each WorkerGlobalScope object whose set contains document.

  11. For each workletGlobalScope in document's worklet global scopes, terminate workletGlobalScope.

Even after destruction, the Document object itself might still be accessible to script, in the case where we are destroying a child navigable.

To destroy a document and its descendants given a Document document and an optional set of steps afterAllDestruction, perform the following steps in parallel:

  1. If document is not fully active, then:

    1. Let reason be a string from user-agent specific blocking reasons. If none apply, then let reason be "masked".

    2. Make document unsalvageable given document and reason.

    3. If document's node navigable is a top-level traversable, build not restored reasons for a top-level traversable and its descendants given document's node navigable.

  2. Let childNavigables be document's child navigables.

  3. Let numberDestroyed be 0.

  4. For each childNavigable of childNavigable's in what order?, queue a global task on the navigation and traversal task source given childNavigable's active window to perform the following steps:

    1. Let incrementDestroyed be an algorithm step which increments numberDestroyed.

    2. Destroy a document and its descendants given childNavigable's active document and incrementDestroyed.

  5. Wait until numberDestroyed equals childNavigable's size.

  6. Queue a global task on the navigation and traversal task source given document's relevant global object to perform the following steps:

    1. Destroy document.

    2. If afterAllDestruction was given, then run it.

7.5.11 Aborting a document load

To abort a Document document:

  1. Assert: this is running as part of a task queued on document's relevant agent's event loop.

  2. Cancel any instances of the fetch algorithm in the context of document, discarding any tasks queued for them, and discarding any further data received from the network for them. If this resulted in any instances of the fetch algorithm being canceled or any queued tasks or any network data getting discarded, then make document unsalvageable given document and "fetch".

  3. If document's during-loading navigation ID for WebDriver BiDi is non-null, then:

    1. Invoke WebDriver BiDi navigation aborted with document's browsing context, and a new WebDriver BiDi navigation status whose id is document's during-loading navigation ID for WebDriver BiDi, status is "canceled", and url is document's URL.

    2. Set document's during-loading navigation ID for WebDriver BiDi to null.

  4. If document has an active parser, then:

    1. Set document's active parser was aborted to true.

    2. Abort that parser.

    3. Set document's salvageable to false.

    4. Make document unsalvageable given document and "parser-aborted".

To abort a document and its descendants given a Document document:

  1. Assert: this is running as part of a task queued on document's relevant agent's event loop.

  2. Let descendantNavigables be document's descendant navigables.

  3. For each descendantNavigable of descendantNavigables in what order?, queue a global task on the navigation and traversal task source given descendantNavigable's active window to perform the following steps:

    1. Abort descendantNavigable's active document.

    2. If descendantNavigable's active document's salvageable is false, then set document's salvageable to false.

  4. Abort document.

To stop loading a navigable navigable:

  1. Let document be navigable's active document.

  2. If document's unload counter is 0, and navigable's ongoing navigation is a navigation ID, then set the ongoing navigation for navigable to null.

    This will have the effect of aborting any ongoing navigations of navigable, since at certain points during navigation, changes to the ongoing navigation will cause further work to be abandoned.

  3. Abort a document and its descendants given document.

Through their user interface, user agents also allow stopping traversals, i.e. cases where the ongoing navigation is "traversal". The above algorithm does not account for this. (On the other hand, user agents do not allow window.stop() to stop traversals, so the above algorithm is correct for that caller.) See issue #6905.

7.6 The `X-Frame-Options` header

Headers/X-Frame-Options

Support in all current engines.

Firefox4+Safari4+Chrome4+
Opera10.5+Edge79+
Edge (Legacy)12+Internet Explorer8+
Firefox AndroidYesSafari iOSYesChrome AndroidYesWebView Android?Samsung Internet?Opera Android?

The `X-Frame-Options` HTTP response header is a legacy way of controlling whether and how a Document may be loaded inside of a child navigable. It is obsoleted by the frame-ancestors CSP directive, which provides more granular control over the same situations. It was originally defined in HTTP Header Field X-Frame-Options, but the definition and processing model here supersedes that document. [CSP] [RFC7034]

In particular, HTTP Header Field X-Frame-Options specified an `ALLOW-FROM` variant of the header, but that is not to be implemented.

Per the below processing model, if both a CSP frame-ancestors directive and an `X-Frame-Options` header are used in the same response, then `X-Frame-Options` is ignored.

For web developers and conformance checkers, its value ABNF is:

X-Frame-Options = "DENY" / "SAMEORIGIN"

To check a navigation response's adherence to `X-Frame-Options`, given a response response, a navigable navigable, a CSP list cspList, and an origin destinationOrigin:

  1. If navigable is not a child navigable, then return true.

  2. For each policy of cspList:

    1. If policy's disposition is not "enforce", then continue.

    2. If policy's directive set contains a frame-ancestors directive, then return true.

  3. Let rawXFrameOptions be the result of getting, decoding, and splitting `X-Frame-Options` from response's header list.

  4. Let xFrameOptions be a new set.

  5. For each value of rawXFrameOptions, append value, converted to ASCII lowercase, to xFrameOptions.

  6. If xFrameOptions's size is greater than 1, and xFrameOptions contains any of "deny", "allowall", or "sameorigin", then return false.

    The intention here is to block any attempts at applying `X-Frame-Options` which were trying to do something valid, but appear confused.

    This is the only impact of the legacy `ALLOWALL` value on the processing model.

  7. If xFrameOptions's size is greater than 1, then return true.

    This means it contains multiple invalid values, which we treat the same way as if the header was omitted entirely.

  8. If xFrameOptions[0] is "deny", then return false.

  9. If xFrameOptions[0] is "sameorigin", then:

    1. Let containerDocument be navigable's container document.

    2. While containerDocument is not null:

      1. If containerDocument's origin is not same origin with destinationOrigin, then return false.

      2. Set containerDocument to containerDocument's container document.

  10. Return true.

    If we've reached this point then we have a lone invalid value (which could potentially be one the legacy `ALLOWALL` or `ALLOW-FROM` forms). These are treated as if the header were omitted entirely.


The following table illustrates the processing of various values for the header, including non-conformant ones:

`X-Frame-Options`ValidResult
`DENY`embedding disallowed
`SAMEORIGIN`same-origin embedding allowed
`INVALID`embedding allowed
`ALLOWALL`embedding allowed
`ALLOW-FROM=https://example.com/`embedding allowed (from anywhere)

The following table illustrates how various non-conformant cases involving multiple values are processed:

`X-Frame-Options`Result
`SAMEORIGIN, SAMEORIGIN`same-origin embedding allowed
`SAMEORIGIN, DENY`embedding disallowed
`SAMEORIGIN,`embedding disallowed
`SAMEORIGIN, ALLOWALL`embedding disallowed
`SAMEORIGIN, INVALID`embedding disallowed
`ALLOWALL, INVALID`embedding disallowed
`ALLOWALL,`embedding disallowed
`INVALID, INVALID`embedding allowed

The same results are obtained whether the values are delivered in a single header whose value is comma-delimited, or in multiple headers.

7.7 The `Refresh` header

The `Refresh` HTTP response header is the HTTP-equivalent to a meta element with an http-equiv attribute in the Refresh state. It takes the same value and works largely the same. Its processing model is detailed in create and initialize a Document object.

Browser user agents should provide the ability to navigate, reload, and stop loading any top-level traversable in their top-level traversable set.

For example, via a location bar and reload/stop button UI.

Browser user agents should provide the ability to traverse by a delta any top-level traversable in their top-level traversable set.

For example, via back and forward buttons, possibly including long-press abilities to change the delta.

It is suggested that such user agents allow traversal by deltas greater than one, to avoid letting a page "trap" the user by stuffing the session history with spurious entries. (For example, via repeated calls to history.pushState() or fragment navigations.)

Some user agents have heuristics for translating a single "back" or "forward" button press into a larger delta, specifically to overcome such abuses. We are contemplating specifying these heuristics in issue #7832.

Browser user agents should offer users the ability to create a fresh top-level traversable, given a user-provided or user agent-determined initial URL.

For example, via a "new tab" or "new window" button.

Browser user agents should offer users the ability to arbitrarily close any top-level traversable in their top-level traversable set.

For example, by clicking a "close tab" button.


Browser user agents may provide ways for the user to explicitly cause any navigable (not just a top-level traversable) to navigate, reload, or stop loading.

For example, via a context menu.

Browser user agents may provide the ability for users to destroy a top-level traversable.

For example, by force-closing a window containing one or more such top-level traversables.


When a user requests a reload of a navigable whose active session history entry's document state's resource is a POST resource, the user agent should prompt the user to confirm the operation first, since otherwise transactions (e.g., purchases or database modifications) could be repeated.

When a user requests a reload of a navigable, user agents may provide a mechanism for ignoring any caches when reloading.


All calls to navigate initiated by the mechanisms mentioned above must have the userInvolvement argument set to "browser UI".

All calls to reload initiated by the mechanisms mentioned above must have the userInvolvement argument set to "browser UI".

All calls to traverse the history by a delta initiated by the mechanisms mentioned above must not pass a value for the sourceDocument argument.


The above recommendations, and the data structures in this specification, are not meant to place restrictions on how user agents represent the session history to the user.

For example, although a top-level traversable's session history entries are stored and maintained as a list, and the user agent is recommended to give an interface for traversing that list by a delta, a novel user agent could instead or in addition present a tree-like view, with each page having multiple "forward" pages that the user can choose between.

Similarly, although session history for all descendant navigables is stored in their traversable navigable, user agents could present the user with a more nuanced per-navigable view of the session history.


Browser user agents may use a top-level browsing context's is popup boolean for the following purposes:

In both cases user agents might additionally incorporate user preferences, or present a choice as to whether to go down the popup route.

User agents that provides a minimal user interface for such popups are encouraged to not hide the browser's location bar.