1. 7.5 文档生命周期
      1. 7.5.1 共享文档创建基础设施
      2. 7.5.2 加载 HTML 文档
      3. 7.5.3 加载 XML 文档
      4. 7.5.4 加载文本文档
      5. 7.5.5 加载 multipart/x-mixed-replace 文档
      6. 7.5.6 加载媒体文档
      7. 7.5.7 加载用于不具有 DOM 的内联内容的文档
      8. 7.5.8 完成加载过程
      9. 7.5.9 卸载文档
      10. 7.5.10 销毁文档
      11. 7.5.11 中断文档加载
    2. 7.6 `X-Frame-Options` 头部
    3. 7.7 `Refresh` 头部
    4. 7.8 浏览器用户界面注意事项

7.5 文档生命周期

7.5.1 共享文档创建基础设施

当使用以下算法之一加载文档时,我们使用以下步骤来创建并初始化一个 Document 对象,给定一个类型 type内容类型 contentType导航参数 navigationParams

Document 对象在创建新的浏览上下文和文档时也会被创建;此类初始 about:blank Document 永远不会由此算法创建。此外,可以通过各种 API(例如 document.implementation.createHTMLDocument())创建无浏览上下文Document 对象。

  1. browsingContextnavigationParams可导航对象活动浏览上下文

  2. browsingContext 设置为给定 browsingContextnavigationParams最终沙盒标志集navigationParams跨源打开程序策略navigationParamsCOOP 执行结果获取用于导航响应的浏览上下文 的结果。

    这可能导致浏览上下文组切换,在这种情况下,browsingContext 将是新创建的浏览上下文,而不是 navigationParams可导航对象活动浏览上下文。在这种情况下,创建的 WindowDocument代理 最终将不会被使用;因为创建的 Document不透明的,我们将最终创建新的代理Window 在此算法的后面 以配合新的 Document

  3. permissionsPolicy 为给定 navigationParams可导航对象容器navigationParamsnavigationParams响应从响应创建权限策略 的结果。[PERMISSIONSPOLICY]

    从响应创建权限策略 算法使用了传递的。如果 document.domain 已用于 navigationParams可导航对象容器文档,则其 不能与传递的源同源,因为这些步骤在创建 document 之前运行,因此它本身尚无法使用 document.domain。请注意,这意味着与执行同源 检查相比,权限策略检查的许可性较低。

    请参见以下一些实际示例。

  4. creationURLnavigationParams响应URL

  5. 如果 navigationParams请求 不为空,则将 creationURL 设置为 navigationParams请求当前 URL

  6. window 为 null。

  7. 如果 browsingContext活动文档是否为初始 about:blank 为 true,并且 browsingContext活动文档navigationParams同源,则将 window 设置为 browsingContext活动窗口

    这意味着初始 about:blank Document 和即将创建的新 Document 将共享相同的 Window 对象。

  8. 否则

    1. oacHeader 为给定 `Origin-Agent-Cluster` 和 "item" 从 navigationParams响应头部列表获取结构化字段值 的结果。

    2. 如果 oacHeader 不为空且 oacHeader[0] 为布尔值 true,则令 requestsOAC 为 true;否则为 false。

    3. 如果 navigationParams保留环境非安全上下文,则将 requestsOAC 设置为 false。

    4. agent 为给定 navigationParamsbrowsingContextrequestsOAC获取同源窗口代理 的结果。

    5. realmExecutionContext 为给定 agent 和以下自定义项的创建新领域 的结果

      • 对于全局对象,创建一个新的 Window 对象。

      • 对于全局 this 绑定,使用 browsingContextWindowProxy 对象。

    6. window 设置为 realmExecutionContext 的 Realm 组件的全局对象

    7. topLevelCreationURLcreationURL

    8. topLevelOriginnavigationParams

    9. 如果 navigable容器 不为空,则

      1. parentEnvironmentnavigable容器相关设置对象

      2. topLevelCreationURL 设置为 parentEnvironment顶级创建 URL

      3. topLevelOrigin 设置为 parentEnvironment顶级源

    10. 设置窗口环境设置对象,使用 creationURLrealmExecutionContextnavigationParams保留环境topLevelCreationURLtopLevelOrigin

    这是通常的情况,其中我们即将创建的新 Document 会获得一个新的 Window 来配合它。

  9. loadTimingInfo 为一个新的文档加载时间信息,其导航开始时间设置为navigationParams响应时间信息开始时间

  10. document 为一个新的Document,其中包含:

    类型
    类型
    内容类型
    contentType
    来源
    navigationParams来源
    浏览上下文
    browsingContext
    策略容器
    navigationParams策略容器
    权限策略
    permissionsPolicy
    活动沙盒标志集
    navigationParams最终沙盒标志集
    打开程序策略
    navigationParams跨源打开程序策略
    加载时间信息
    loadTimingInfo
    通过跨源重定向创建
    navigationParams响应包含跨源重定向
    用于 WebDriver BiDi 的加载期间导航 ID
    navigationParamsID
    URL
    creationURL
    当前文档就绪状态
    "loading"
    关于基本 URL
    navigationParams关于基本 URL
    允许声明式 Shadow DOM
    true
  11. window关联的Document设置为document

  12. 给定document运行 Document 的 CSP 初始化[CSP]

  13. 如果navigationParams请求非空,则

    1. documentreferrer设置为空字符串。

    2. referrernavigationParams请求referrer

    3. 如果referrer 是一个URL 记录,则将documentreferrer设置为referrer序列化结果。

      根据Fetchreferrer 在此时将是URL 记录或 "no-referrer"。

  14. 如果navigationParamsFetch 控制器非空,则

    1. fullTimingInfo 为从navigationParamsFetch 控制器提取完整时间信息的结果。

    2. 如果navigationParams响应包含跨源重定向为真,则令redirectCount 为 0;否则,令redirectCountnavigationParams请求重定向计数

    3. 给定fullTimingInforedirectCountnavigationTimingTypenavigationParams响应Service Worker 时间信息以及navigationParams响应主体信息创建document的导航时间条目

  15. 给定navigationParams响应时间信息redirectCountnavigationParams导航时间类型以及navigationParams响应Service Worker 时间信息创建document的导航时间条目

  16. 如果navigationParams响应包含`Refresh` 头部,则

    1. value 为头部值的同构解码结果。

    2. 使用documentvalue 运行共享声明式刷新步骤

    我们目前还没有关于如何处理多个`Refresh` 头部的规范。这在issue #2900中进行跟踪。

  17. 如果navigationParams提交早期提示非空,则使用document 调用navigationParams提交早期提示

  18. 给定documentnavigationParams响应以及 "pre-media",处理链接头部

  19. 返回document

在这个例子中,子文档不允许使用PaymentRequest,尽管在子文档尝试使用它时,它是同源域。在子文档初始化时,只有父文档设置了document.domain,而子文档没有。

<!-- 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>

在这个例子中,子文档**允许**使用PaymentRequest,尽管在子文档尝试使用它时,它不是同源域。在子文档初始化时,没有一个文档设置了document.domain,因此同源域回退到正常的同源检查。

<!-- 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>

给定一个Document document使用html/head/body填充

  1. html 为给定documenthtml以及HTML 命名空间创建元素的结果。

  2. head 为给定documenthead以及HTML 命名空间创建元素的结果。

  3. body 为给定documentbody以及HTML 命名空间创建元素的结果。

  4. 追加htmldocument

  5. 追加headhtml

  6. 追加bodyhtml

7.5.2 加载 HTML 文档

给定导航参数navigationParams加载 HTML 文档

  1. document 为给定 "html"、"text/html" 以及navigationParams创建并初始化 Document 对象的结果。

  2. 如果documentURLabout:blank,则给定document使用html/head/body填充

    这种特殊情况,即使非初始about:blankDocument也同步获得其元素节点,对于与已部署内容的兼容性是必要的。换句话说,与其转到“其他”分支并将空字节序列馈送到HTML 解析器以异步填充document,这样做是不兼容的。

  3. 否则,创建一个HTML 解析器并将其与document关联。在获取运行期间,网络任务源放置在任务队列上的每个任务都必须使用获取到的字节填充解析器的输入字节流,并导致HTML 解析器对输入流执行相应的处理。

    在获取运行期间,网络任务源放置在任务队列上的第一个任务必须在任务由HTML 解析器处理后,根据documentnavigationParams响应和“media处理链接头

    在任何脚本执行发生之前,用户代理必须等待脚本是否可以为新创建的文档运行对于document为真。

    输入字节流将字节转换为字符,以便在标记器中使用。此过程部分依赖于在资源的实际Content-Type 元数据中找到的字符编码信息;计算出的类型不用于此目的。

    当不再有字节可用时,用户代理必须根据document相关全局对象网络任务源排队一个全局任务,以使解析器处理隐含的 EOF 字符,这最终会导致触发load事件。

  4. 返回document

7.5.3 加载 XML 文档

当需要内联显示 XML 文件时,在提供导航参数navigationParams和字符串type的情况下,用户代理必须遵循XMLXML 中的命名空间XML 媒体类型DOM以及其他相关规范中定义的要求,以创建和初始化一个Document对象document,给定“xml”、typenavigationParams,并返回该Document。他们还必须创建一个相应的XML 解析器[XML] [XMLNS] [RFC7303] [DOM]

在撰写本文时,XML 规范社区实际上尚未指定 XML 和 DOM 如何交互。

在获取运行期间,网络任务源放置在任务队列上的第一个任务必须在任务由XML 解析器处理后,根据documentnavigationParams响应和“media处理链接头

实际的 HTTP 标头和其他元数据(而不是根据本规范中给出的算法进行修改或隐含的标头)是在根据上述规范中给出的规则确定字符编码时必须使用的。一旦建立了字符编码,则必须将文档的字符编码设置为该字符编码。

在任何脚本执行发生之前,用户代理必须等待脚本是否可以为新创建的文档运行对于新创建的Document为真。

解析完成后,用户代理必须将documentWebDriver BiDi 的加载期间导航 ID设置为 null。

对于 HTML 文档,这在解析完成后,触发 load 事件后重置。

解析过程中的错误消息(例如,XML 命名空间格式良好的错误)可以通过修改Document来内联报告。

7.5.4 加载文本文档

加载文本文档,给定导航参数navigationParams和字符串type

  1. document为根据“html”、typenavigationParams创建和初始化Document对象的结果。

  2. document解析器无法更改模式标志设置为 true。

  3. document模式设置为“no-quirks”。

  4. 创建一个HTML 解析器并将其与document关联。假定标记器已发出一个开始标签标记,其标签名为“pre”,后跟一个 U+000A 换行符 (LF) 字符,并将HTML 解析器的标记器切换到PLAINTEXT 状态。在获取运行期间,网络任务源放置在任务队列上的每个任务都必须使用获取到的字节填充解析器的输入字节流,并导致HTML 解析器对输入流执行相应的处理。

    document编码必须设置为在解析期间用于解码文档的字符编码。

    在获取运行期间,网络任务源放置在任务队列上的第一个任务必须在任务由HTML 解析器处理后,根据documentnavigationParams响应和“media处理链接头

    在任何脚本执行发生之前,用户代理必须等待脚本是否可以为新创建的文档运行对于document为真。

    当不再有字节可用时,用户代理必须根据document相关全局对象网络任务源排队一个全局任务,以使解析器处理隐含的 EOF 字符,这最终会导致触发load事件。

  5. 用户代理可以向documenthead元素添加内容,例如,链接到样式表、提供脚本或为文档提供标题

    特别是,如果用户代理支持 RFC 3676 的Format=Flowed功能,则用户代理需要应用额外的样式以使文本正确换行并处理引用功能。这可以使用例如 CSS 扩展来执行。

  6. 返回document

如何将纯文本文档的字节转换为实际字符的规则,以及如何实际将文本呈现给用户的规则,由资源的计算出的 MIME 类型(即type)的规范定义。

7.5.5 加载multipart/x-mixed-replace文档

加载multipart/x-mixed-replace文档,给定导航参数navigationParams源快照参数sourceSnapshotParams来源initiatorOrigin

  1. 使用多部分类型的规则解析navigationParams响应主体[RFC2046]

  2. firstPartNavigationParamsnavigationParams的副本。

  3. firstPartNavigationParams响应设置为一个新的响应,该响应表示navigationParams响应主体的多部分流中的第一部分。

  4. document为给定firstPartNavigationParamssourceSnapshotParamsinitiatorOrigin加载文档的结果。

    对于从navigationParams响应获得的每个附加主体部分,用户代理必须使用document,将document节点可导航导航到navigationParams请求URL导航,其中响应设置为navigationParams响应,并且历史处理设置为“替换”。

  5. 返回document

为了算法处理这些主体部分,就好像它们是完整的独立资源一样,用户代理必须在每当遇到主体部分之后的边界时,就假定这些资源没有更多字节。

因此,对于加载的每个主体部分,都会触发load事件(以及unload事件)。

7.5.6 加载媒体文档

加载媒体文档,给定navigationParams和字符串type

  1. document为根据“html”、typenavigationParams创建和初始化Document对象的结果。

  2. document模式设置为“no-quirks”。

  3. 使用html/head/body填充给定document

  4. 为媒体附加一个元素 host element,如下所述,到 body 元素。

  5. 将元素 host element 的适当属性(如下所述)设置为图像、视频或音频资源的地址。

  6. 用户代理可以向 documenthead 元素添加内容,或向 host element 添加属性,例如,链接到样式表、提供脚本、为文档提供 title 或使媒体 自动播放

  7. 处理给定 documentnavigationParams响应 和 "media" 的 链接头

  8. 假装用户代理已 停止解析 document

  9. 返回document

要为媒体创建的元素 host element 是下表中第一列描述媒体的那一行的第二列中给出的元素。要设置的适当属性是由同一行中的第三列给出的。

媒体类型媒体的元素适当的属性
图像 img src
视频 video src
音频 audio src

在任何脚本执行发生之前,用户代理必须等待 新创建文档的脚本可能运行Document 为真。

7.5.7 加载没有 DOM 的内联内容的文档

当用户代理需要创建一个文档来显示用户代理页面或 PDF 查看器内联时,提供了一个 可导航的 navigable、一个 导航 ID navigationId、一个 NavigationTimingType navTimingType,用户代理应该

  1. origin 为一个新的 不透明来源

  2. coop 为一个新的 打开程序策略

  3. coopEnforcementResult 为一个新的 打开程序策略执行结果,其中包含

    URL
    responseURL
    来源
    来源
    打开程序策略
    coop
  4. navigationParams 为一个新的 导航参数,其中包含

    ID
    navigationId
    navigable
    navigable
    请求
    null
    响应
    一个新的 响应
    来源
    来源
    获取控制器
    null
    提交早期提示
    null
    COOP 执行结果
    coopEnforcementResult
    保留环境
    null
    策略容器
    一个新的 策略容器
    最终沙盒标志集
    一个空集
    打开程序策略
    coop
    导航时间类型
    navTimingType
    关于基本 URL
    null
  5. document 为给定 "html"、"text/html" 和 navigationParams创建和初始化 Document 对象 的结果。

  6. 或者将 document 与自定义渲染相关联(该渲染不使用正常的 Document 渲染规则进行渲染),或者修改 document 直到它表示用户代理想要渲染的内容。

  7. 返回document

因为我们确保生成的 Document来源不透明,并且生成的 Document 无法运行具有访问 DOM 权限的脚本,因此此 Document 的存在和属性对 Web 开发人员代码不可见。这意味着上面大多数值(例如,text/html 类型)并不重要。类似地,navigationParams 中的大多数项目都没有任何可观察到的影响,除了防止 Document 创建算法 出现混乱,因此设置为默认值。

页面设置完成后,用户代理必须假装它已 停止解析

7.5.8 完成加载过程

一个 Document 有一个 完全加载时间(一个时间或 null),最初为 null。

如果 Document完全加载时间 不为 null,则认为该 Document 已完全加载

完全完成加载 Document document

  1. 断言document浏览上下文 不为 null。

  2. document完全加载时间 设置为当前时间。

  3. containerdocument节点可导航容器

    document框架iframe 中的 初始 about:blank Document 的情况下,这将为 null,因为在调用此算法的 浏览上下文创建 时,容器关系尚未建立。(这发生在 创建新的子可导航 的后续步骤中。)

    这样做的结果是以下步骤什么也不做,即我们不会在这些情况下为容器元素触发异步 load 事件。相反,在 处理 iframe 属性 的特殊初始插入情况下,会触发同步 load 事件。

  4. 如果 containeriframe 元素,则 在给定 container 的 DOM 操作任务源上排队一个元素任务 以运行给定 containeriframe 加载事件步骤

  5. 否则,如果 container 不为 null,则 在给定 container 的 DOM 操作任务源上排队一个元素任务container 上触发名为 load 的事件。

7.5.9 卸载文档

一个 Document 有一个 可挽救的 状态,最初必须为 true,还有一个 页面显示 标志,最初必须为 false。页面显示 标志用于确保脚本以一致的方式接收 pageshowpagehide 事件(例如,它们永远不会在没有中间 pageshow 的情况下连续接收两个 pagehide 事件,反之亦然)。

一个 Document 有一个 DOMHighResTimeStamp 挂起时间,最初为 0。

一个 Document 有一个 列表挂起的计时器句柄,最初为空。

事件循环 有一个 终止嵌套级别 计数器,最初必须为 0。

Document 对象有一个 卸载计数器,用于在以下算法运行时忽略某些操作。最初,计数器必须设置为零。

卸载 Document oldDocument,给定一个可选的 Document newDocument

  1. 断言:这是在 oldDocument相关代理事件循环 上排队的 任务 的一部分运行。

  2. unloadTimingInfo 为一个新的 文档卸载时间信息

  3. 如果未给出 newDocument,则将 unloadTimingInfo 设置为 null。

    在这种情况下,没有需要知道 oldDocument 卸载需要多长时间的新文档。

  4. 否则,如果 newDocument事件循环 不是 oldDocument事件循环,则用户代理可能正在 并行 卸载 oldDocument。在这种情况下,用户代理应该将 unloadTimingInfo 设置为 null。

    在这种情况下,newDocument 的加载不受卸载 oldDocument 需要多长时间的影响,因此传达该时间信息毫无意义。

  5. 如果用户代理打算在 会话历史条目 中保持 oldDocument 存活,以便以后可以 用于历史遍历,则令 intendToKeepInBfcache 为 true。

    如果<var>oldDocument</var>不可<i id="unloading-documents:concept-document-salvageable">恢复</i>,或者<var>oldDocument</var>的任何后代用户代理不打算以相同的方式保持存活(包括由于它们缺乏<i id="unloading-documents:concept-document-salvageable-2">恢复能力</i>),则此值必须为假。

  6. 令<var>eventLoop</var>为<var>oldDocument</var>的相关代理事件循环

  7. 将<var>eventLoop</var>的终止嵌套级别增加1。

  8. 将<var>oldDocument</var>的卸载计数器增加1。

  9. 如果<var>intendToKeepInBfcache</var>为假,则将<var>oldDocument</var>的<i id="unloading-documents:concept-document-salvageable-3">可恢复</i>状态设置为假。

  10. 如果<var>oldDocument</var>的页面显示为真

    1. 将<var>oldDocument</var>的页面显示设置为假。

    2. 在<var>oldDocument</var>的相关全局对象上,使用<var>oldDocument</var>的<i id="unloading-documents:concept-document-salvageable-4">可恢复</i>状态触发一个名为<code id="unloading-documents:event-pagehide-3">pagehide</code>的页面转换事件。

    3. 将<var>oldDocument</var>的可见性状态更新为“<code>hidden</code>”。

  11. 如果<var>unloadTimingInfo</var>不为null,则将<var>unloadTimingInfo</var>的卸载事件开始时间设置为给定<var>newDocument</var>的相关全局对象当前高分辨率时间,并根据<var>oldDocument</var>的相关设置对象跨源隔离功能粗化

  12. 如果<var>oldDocument</var>的<i id="unloading-documents:concept-document-salvageable-5">可恢复</i>状态为假,则在<var>oldDocument</var>的相关全局对象触发一个名为<code id="unloading-documents:event-unload">unload</code>的事件,并设置<var>legacy target override flag</var>。

  13. 如果<var>unloadTimingInfo</var>不为null,则将<var>unloadTimingInfo</var>的卸载事件结束时间设置为给定<var>newDocument</var>的相关全局对象当前高分辨率时间,并根据<var>oldDocument</var>的相关设置对象跨源隔离功能粗化

  14. 将<var>eventLoop</var>的终止嵌套级别减少1。

  15. 将<var>oldDocument</var>的挂起时间设置为给定<var>document</var>的相关全局对象当前高分辨率时间

  16. 将<var>oldDocument</var>的挂起的定时器句柄设置为获取活动定时器映射的键的结果。

  17. 将<var>oldDocument</var>的用户是否滚动过设置为假。

  18. 运行本规范和其他适用规范中为<var>oldDocument</var>定义的任何卸载文档清理步骤

  19. 如果<var>oldDocument</var>的节点可导航顶级可遍历,则为顶级可遍历及其后代构建未恢复的原因,给定<var>oldDocument</var>的节点可导航

  20. 如果<var>oldDocument</var>的<i id="unloading-documents:concept-document-salvageable-6">可恢复</i>状态为假,则销毁<var>oldDocument</var>。

  21. 将<var>oldDocument</var>的卸载计数器减少1。

  22. 如果给定<var>newDocument</var>,<var>newDocument</var>的是通过跨源重定向创建的为假,并且<var>newDocument</var>的来源与<var>oldDocument</var>的来源相同,则将<var>newDocument</var>的先前文档卸载时间设置为<var>unloadTimingInfo</var>。

卸载文档及其后代,给定一个<code id="unloading-documents:document-7">Document</code> <var>document</var>,一个可选的<code id="unloading-documents:document-8">Document</code>-或-null <var>newDocument</var>(默认为null),一组可选的步骤<var>afterAllUnloads</var>,以及一组可选的步骤<var>firePageSwapSteps</var>

  1. 断言:这在<var>document</var>的节点可导航可遍历导航会话历史遍历队列中运行。

  2. 令<var>childNavigables</var>为<var>document</var>的子导航

  3. 令<var>numberUnloaded</var>为0。

  4. 对于<var>childNavigable</var>的每个<span class="XXX">以什么顺序?</span>,在给定<var>childNavigable</var>的活动窗口导航和遍历任务源排队一个全局任务,以执行以下步骤

    1. 令<var>incrementUnloaded</var>为一个增加<var>numberUnloaded</var>值的算法步骤。

    2. 给定<var>childNavigable</var>的活动文档、null和<var>incrementUnloaded</var>,卸载文档及其后代

  5. 等待直到<var>numberUnloaded</var>等于<var>childNavigable</var>的大小

  6. 在给定<var>document</var>的相关全局对象导航和遍历任务源排队一个全局任务,以执行以下步骤

    1. 如果给定<var>firePageSwapSteps</var>,则运行<var>firePageSwapSteps</var>。

    2. 如果<var>newDocument</var>不为null,则卸载<var>document</var>,并传递<var>newDocument</var>。

    3. 如果给定<var>afterAllUnloads</var>,则运行它。

本规范定义了以下卸载文档清理步骤。其他规范可以定义更多。给定一个<code id="unloading-documents:document-9">Document</code> <var>document</var>

  1. 令<var>window</var>为<var>document</var>的相关全局对象

  2. 对于每个其相关全局对象为<var>window</var>的<code id="unloading-documents:websocket-2">WebSocket</code>对象<var>webSocket</var>,使<var>webSocket</var>消失

    如果这影响了任何<code id="unloading-documents:websocket-2-2">WebSocket</code>对象,则给定<var>document</var>和“<code id="unloading-documents:blocking-websocket">websocket</code>”,使文档不可恢复

  3. 对于每个其相关全局对象为<var>window</var>的<code id="unloading-documents:webtransport">WebTransport</code>对象<var>transport</var>,运行给定<var>transport</var>的上下文清理步骤

  4. 如果<var>document</var>的<i id="unloading-documents:concept-document-salvageable-7">可恢复</i>状态为假,则

    1. 对于每个其相关全局对象等于<var>window</var>的<code id="unloading-documents:eventsource">EventSource</code>对象<var>eventSource</var>,强制关闭<var>eventSource</var>。

    2. 清空<var>window</var>的活动定时器映射

如果规范作者直接发送拉取请求,从这里添加调用到他们的规范中,而不是使用卸载文档清理步骤钩子,则会更好,以确保跨规范调用的顺序明确定义。截至撰写本文时,以下规范已知具有卸载文档清理步骤,这些步骤将以未指定的顺序运行:<cite>全屏 API</cite>、<cite>Web NFC</cite>、<cite>WebDriver BiDi</cite>、<cite>计算压力</cite>、<cite>文件 API</cite>、<cite>媒体捕获和流</cite>、<cite>画中画</cite>、<cite>屏幕方向</cite>、<cite>服务工作者</cite>、<cite>WebLocks API</cite>、<cite>WebAudio API</cite>、<cite>WebRTC</cite>。 [FULLSCREEN] [WEBNFC] [WEBDRIVERBIDI] [COMPUTEPRESSURE] [FILEAPI] [MEDIASTREAM] [PICTUREINPICTURE] [SCREENORIENTATION] [SW] [WEBLOCKS] [WEBAUDIO] [WEBRTC]

问题 #8906跟踪使这些步骤的顺序明确的工作。

7.5.10 销毁文档

销毁一个Document document

  1. 断言:这是在document相关代理事件循环上排队的任务的一部分执行的。

  2. 中止 document

  3. document可恢复状态设置为false。

  4. portsMessagePort列表,其相关全局对象关联的Documentdocument

  5. 对于ports中的每个port分离 port

  6. 运行document的任何由本规范和其他适用规范定义的卸载文档清理步骤

  7. 从任何任务队列中移除其文档document的任何任务(不运行这些任务)。

  8. document浏览上下文设置为null。

  9. document节点可导航活动会话历史条目文档状态文档设置为null。

  10. 移除每个其集合包含 documentWorkerGlobalScope对象的所有者集合中的document

  11. 对于documentworklet全局作用域中的每个workletGlobalScope终止 workletGlobalScope

即使在销毁之后,Document对象本身可能仍然可以通过脚本访问,在我们要销毁子可导航的情况下。

销毁文档及其后代,给定一个Document document和一个可选的步骤集afterAllDestruction,执行以下步骤并行

  1. 如果document不是完全活动的,则

    1. 使文档不可恢复,给定document和"屏蔽"。

    2. 如果document节点可导航顶级可遍历,则为顶级可遍历及其后代构建未恢复的原因,给定document节点可导航

  2. childNavigablesdocument子可导航

  3. numberDestroyed为0。

  4. 对于childNavigables的每个childNavigable按什么顺序?),在导航和遍历任务源排队一个全局任务,给定childNavigable活动窗口,以执行以下步骤

    1. incrementDestroyed为一个增加numberDestroyed值的算法步骤。

    2. 销毁文档及其后代,给定childNavigable活动文档incrementDestroyed

  5. 等待直到numberDestroyed等于childNavigable大小

  6. 排队一个全局任务,在导航和遍历任务源上,给定document相关全局对象,以执行以下步骤

    1. 销毁 document

    2. 如果提供了afterAllDestruction,则运行它。

7.5.11 中止文档加载

中止一个Document document

  1. 断言:这是在document相关代理事件循环上排队的任务的一部分执行的。

  2. 取消document上下文中获取算法的任何实例,丢弃为它们排队的任何任务,并丢弃从网络为它们接收的任何进一步数据。如果这导致获取算法的任何实例被取消或任何排队任务或任何网络数据被丢弃,则使文档不可恢复,给定document和"获取"。

  3. 如果document用于WebDriver BiDi的加载期间导航ID不为null,则

    1. 使用document浏览上下文和一个新的WebDriver BiDi导航状态调用WebDriver BiDi导航中止,该状态的iddocument用于WebDriver BiDi的加载期间导航IDstatus为"已取消",urldocumentURL

    2. document用于WebDriver BiDi的加载期间导航ID设置为null。

  4. 如果document活动解析器,则

    1. document活动解析器已中止设置为true。

    2. 中止该解析器.

    3. document可恢复设置为false。

    4. 使文档不可恢复,给定document和"解析器中止"。

中止文档及其后代,给定一个Document document

  1. 断言:这是在document相关代理事件循环上排队的任务的一部分执行的。

  2. descendantNavigablesdocument后代可导航

  3. 对于descendantNavigables的每个descendantNavigable按什么顺序?),在导航和遍历任务源排队一个全局任务,给定descendantNavigable活动窗口,以执行以下步骤

    1. 中止descendantNavigable活动文档

    2. 如果descendantNavigable活动文档可恢复为false,则将document可恢复设置为false。

  4. 中止 document

停止加载一个可导航 navigable

  1. documentnavigable活动文档

  2. 如果document卸载计数器为0,并且navigable正在进行的导航导航ID,则navigable设置正在进行的导航为null。

    这将导致任何正在进行的 navigable 导航中止,因为在导航过程中的某些点,对正在进行的导航 的更改会导致进一步的工作被放弃。

  3. 给定 document中止一个文档及其后代

通过其用户界面,用户代理还允许停止遍历,即正在进行的导航 为 "traversal" 的情况。上述算法没有考虑这种情况。(另一方面,用户代理不允许window.stop() 停止遍历,因此上述算法对于该调用者是正确的。)参见issue #6905

7.6 `X-Frame-Options` 头部

Headers/X-Frame-Options

所有当前引擎都支持。

Firefox4+Safari4+Chrome4+
Opera10.5+Edge79+
Edge (Legacy)12+Internet Explorer8+
Firefox AndroidSafari iOSChrome AndroidWebView Android?Samsung Internet?Opera Android?

HTTP 响应头部 `X-Frame-Options` 是一种控制 Document 是否以及如何加载到子导航 中的传统方法。它被 frame-ancestors CSP 指令取代,该指令对相同情况提供了更细粒度的控制。它最初在 HTTP Header Field X-Frame-Options 中定义,但此处的定义和处理模型取代了该文档。 [CSP] [RFC7034]

特别是,HTTP Header Field X-Frame-Options 指定了该头的 `ALLOW-FROM` 变体,但不应实现。

根据以下处理模型,如果在同一个响应 中同时使用了 CSP frame-ancestors 指令和 `X-Frame-Options` 头部,则忽略 `X-Frame-Options`。

对于 Web 开发人员和一致性检查器,其值ABNF

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

检查导航响应对 `X-Frame-Options` 的遵守情况,给定一个响应 response、一个导航 navigable、一个CSP 列表 cspList 和一个来源 destinationOrigin

  1. 如果 navigable 不是子导航,则返回 true。

  2. 对于 cspList 的每个 policy

    1. 如果 policy处置 不是 "enforce",则继续

    2. 如果 policy指令集包含 frame-ancestors 指令,则返回 true。

  3. rawXFrameOptions获取、解码和拆分 response头部列表 中的 `X-Frame-Options` 的结果。

  4. xFrameOptions 为一个新的集合

  5. 对于 rawXFrameOptions 的每个 value追加 value转换为 ASCII 小写)到 xFrameOptions

  6. 如果 xFrameOptions大小 大于 1,并且 xFrameOptions包含 "deny"、"allowall" 或 "sameorigin" 中的任何一个,则返回 false。

    这里的目的是阻止任何试图应用 `X-Frame-Options` 的尝试,这些尝试试图做一些有效的事情,但看起来很混乱。

    这是传统 `ALLOWALL` 值对处理模型的唯一影响。

  7. 如果 xFrameOptions大小 大于 1,则返回 true。

    这意味着它包含多个无效值,我们将其视为与完全省略头部相同。

  8. 如果 xFrameOptions[0] 为 "deny",则返回 false。

  9. 如果 xFrameOptions[0] 为 "sameorigin",则

    1. containerDocumentnavigable容器文档

    2. containerDocument 不为 null 时

      1. 如果 containerDocument来源destinationOrigin 不同源,则返回 false。

      2. containerDocument 设置为 containerDocument容器文档

  10. 返回 true。

    如果我们到达了这一点,那么我们有一个孤立的无效值(它可能是一个传统的 `ALLOWALL` 或 `ALLOW-FROM` 形式)。这些被视为头部完全省略。


下表说明了对该头的各种值的处理,包括不符合规范的值

`X-Frame-Options`有效结果
`DENY`禁止嵌入
`SAMEORIGIN`允许同源嵌入
`INVALID`允许嵌入
`ALLOWALL`允许嵌入
`ALLOW-FROM=https://example.com/`允许嵌入(来自任何地方)

下表说明了如何处理涉及多个值的各种不符合规范的情况

`X-Frame-Options`结果
`SAMEORIGIN, SAMEORIGIN`允许同源嵌入
`SAMEORIGIN, DENY`禁止嵌入
`SAMEORIGIN,`禁止嵌入
`SAMEORIGIN, ALLOWALL`禁止嵌入
`SAMEORIGIN, INVALID`禁止嵌入
`ALLOWALL, INVALID`禁止嵌入
`ALLOWALL,`禁止嵌入
`INVALID, INVALID`允许嵌入

无论值是通过一个以逗号分隔的值的头部传递,还是通过多个头部传递,都会获得相同的结果。

7.7 `Refresh` 头部

HTTP 响应头部 `Refresh` 等效于具有 http-equiv 属性的 meta 元素(处于刷新状态)。它采用相同的值,并且工作方式基本相同。其处理模型在创建和初始化 Document 对象 中详细说明。

浏览器用户代理应提供 导航重新加载停止加载顶级可遍历集 中的任何顶级可遍历 的能力。

例如,通过地址栏和重新加载/停止按钮 UI。

浏览器用户代理应提供通过增量遍历顶级可遍历集 中的任何顶级可遍历 的能力。

例如,通过后退和前进按钮,可能包括长按功能以更改增量。

建议此类用户代理允许通过大于 1 的增量进行遍历,以避免页面通过填充会话历史记录中的虚假条目来“困住”用户。(例如,通过重复调用history.pushState()片段导航。)

一些用户代理具有将单个“后退”或“前进”按钮按下转换为更大增量的启发式方法,特别是为了克服此类滥用。我们正在考虑在issue #7832 中指定这些启发式方法。

浏览器用户代理应为用户提供创建新的顶级可遍历的能力,给定用户提供的或用户代理确定的初始URL

例如,通过“新标签页”或“新窗口”按钮。

浏览器用户代理应为用户提供任意关闭顶级可遍历集 中的任何顶级可遍历 的能力。

例如,通过单击“关闭标签页”按钮。


浏览器用户代理可以提供方法,让用户显式地使任何导航(不仅仅是顶级可遍历导航重新加载停止加载

例如,通过上下文菜单。

浏览器用户代理可以提供让用户销毁顶级可遍历 的能力。

例如,通过强制关闭包含一个或多个此类顶级可遍历 的窗口。


当用户请求重新加载一个重新加载活动会话历史条目文档状态资源POST 资源可导航对象时,用户代理应首先提示用户确认操作,否则可能会重复事务(例如,购买或数据库修改)。

当用户请求重新加载一个可导航对象时,用户代理可以提供一种在重新加载时忽略任何缓存的机制。


由上述机制发起的对navigate的所有调用都必须将userInvolvement参数设置为"浏览器 UI"。

由上述机制发起的对reload的所有调用都必须将userInvolvement参数设置为"浏览器 UI"。

由上述机制发起的对通过增量遍历历史记录的所有调用都不得为sourceDocument参数传递值。


以上建议以及本规范中的数据结构并非旨在限制用户代理如何向用户呈现会话历史记录。

例如,尽管顶级可遍历对象会话历史条目被存储和维护为列表,并且建议用户代理提供一个用于通过增量遍历该列表的接口,但新颖的用户代理可以替代或另外提供一个树状视图,其中每个页面都有多个用户可以选择的前进页面。

同样,尽管所有子可导航对象的会话历史记录都存储在其可遍历可导航对象中,但用户代理可以向用户提供更细致的每个可导航对象的会话历史记录视图。


浏览器用户代理可以使用顶级浏览上下文is popup布尔值用于以下目的

在这两种情况下,用户代理还可以合并用户偏好,或提供是否采用弹出窗口路线的选择。

提供此类弹出窗口的最小用户界面的用户代理建议不要隐藏浏览器的地址栏。