Fetch

现行标准 — 最后更新

参与:
GitHub whatwg/fetch (新问题, 开放问题)
在 Matrix 上聊天
提交记录:
GitHub whatwg/fetch/commits
此提交时的快照
@fetchstandard
测试:
web-platform-tests fetch/ (进行中的工作)
翻译 (非规范性):
日本語
简体中文

摘要

Fetch 标准定义了请求、响应及其关联过程:获取。

目标

目标是统一整个网络平台上的获取操作,并提供一致的处理方式,包括以下内容:

为此,它还取代了最初定义于The Web Origin Concept中的 HTTP `Origin` 标头语义。 [ORIGIN]

1. 前言

在高层次上,获取资源是一个相当简单的操作。请求进入,响应出来。然而,这一操作的细节相当复杂,过去往往没有被仔细记录下来,且在不同的 API 中存在差异。

众多 API 提供了获取资源的能力,例如 HTML 的 imgscript 元素,CSS 的 cursorlist-style-image, 以及 navigator.sendBeacon()self.importScripts() JavaScript API。Fetch 标准为这些功能提供了统一的架构,使它们在处理重定向和 CORS 协议等各种获取方面保持一致。

Fetch 标准还定义了 fetch() JavaScript API,它以相对较低的抽象层次暴露了大部分网络功能。

2. 基础设施

本规范依赖于 Infra 标准。[INFRA]

本规范使用了以下标准中的术语:ABNFEncodingHTMLHTTPMIME SniffingStreamsURLWeb IDL、 和 WebSockets[ABNF] [ENCODING] [HTML] [HTTP] [MIMESNIFF] [STREAMS] [URL] [WEBIDL] [WEBSOCKETS]

指由 HTTP 增强的 ABNF(特别是添加了 #)以及 RFC 7405。[RFC7405]


包括 HTTP cookies、TLS 客户端证书,以及 认证条目(用于 HTTP 认证)。[COOKIES] [TLS] [HTTP]


结构体,用于 Fetch 算法中的簿记细节。它包含以下

一个 请求
(默认值为 null)
(默认值为 null)
(默认值为 null)
(默认值为 null)
(默认值为 null)
(默认值为 null)
null 或算法。
(默认值为 null)
null、全局对象,或 并行队列
(默认值为 false)
一个布尔值。
(默认值为一个新的 Fetch 控制器
一个 Fetch 控制器
一个 Fetch 时序信息
(默认值为 null)
null、"pending",或 响应

是一个 结构体,用于让 Fetch 的调用者在开始后对其执行某些操作。它包含以下

(默认值为 "ongoing")
"ongoing"、"terminated" 或 "aborted"。
(默认值为 null)
null 或 Fetch 时序信息
(默认值为 null)
null 或接受一个 全局对象 的算法。
(默认值为 null)
null 或 记录结构化序列化 的结果)。
(默认值为 null)
null 或不接受任何参数的算法。

要为一个 Fetch 控制器 controller 执行 ,给定一个 全局对象 global

  1. 断言controller报告时序步骤 不为 null。

  2. 调用 controller报告时序步骤 并传入 global

要为一个 Fetch 控制器 controller 执行

  1. 断言controller下一个手动重定向步骤 不为 null。

  2. 调用 controller下一个手动重定向步骤

要提取 Fetch 控制器 controller

  1. 断言controller完整时序信息 不为 null。

  2. 返回 controller完整时序信息

一个fetch 控制器 controller,可选error

  1. controller状态 设置为 "aborted"。

  2. fallbackError 设置为 "AbortError" DOMException

  3. 如果未给定 error,则将其设置为 fallbackError

  4. serializedError 设置为 结构化序列化(error)。 如果抛出异常,则捕获并将 serializedError 设置为 结构化序列化(fallbackError)。

  5. controller序列化的中止原因 设置为 serializedError

,给定 null 或 记录 abortReasonrealm realm

  1. fallbackError 设置为 "AbortError" DOMException

  2. deserializedError 设置为 fallbackError

  3. 如果 abortReason 不为 null,则将 deserializedError 设置为 结构化反序列化(abortReason, realm)。如果抛出异常或返回 undefined,则将 deserializedError 设置为 fallbackError

  4. 返回 deserializedError

一个fetch 控制器 controller,将controller状态设置为 "terminated"。

一个 Fetch 参数 fetchParams 如果其 控制器状态 是 "aborted",则为

一个 Fetch 参数 fetchParams 如果其 控制器状态 是 "aborted" 或 "terminated",则为

是一个 结构体,用于维护 资源 时序导航时序 所需的时序信息。它包含以下 [RESOURCE-TIMING] [NAVIGATION-TIMING]

(默认值为 0)
(默认值为 0)
(默认值为 0)
(默认值为 0)
(默认值为 0)
(默认值为 0)
(默认值为 0)
(默认值为 0)
(默认值为 0)
一个 DOMHighResTimeStamp
(默认值为 null)
null 或 连接时序信息
(默认值为 « »)
一个字符串 列表
(默认值为 false)
一个布尔值。

是一个 结构体,用于维护 资源时序导航时序 所需的信息。它包含以下 [RESOURCE-TIMING] [NAVIGATION-TIMING]

(默认值为 0)
(默认值为 0)
一个数字。
(默认值为空字符串)
一个 ASCII 字符串

,给定一个 Fetch 时序信息 timingInfo,返回一个新的 Fetch 时序信息,其 开始时间重定向后开始时间timingInfo开始时间 相同。

,给定一个算法 algorithm全局对象并行队列 taskDestination,执行以下步骤:

  1. 如果 taskDestination并行队列,则将 algorithm 排入 taskDestination

  2. 否则,在 网络任务源 上为 taskDestinationalgorithm 排队一个全局任务


,将其表示为最短的小数字符串。

这将被 Infra 中更详细的算法替代。参见 infra/201

2.1. URL

是 "about"、"blob" 或 "data"。

如果 URLschemelocal scheme,则该 URL

此定义还被 Referrer Policy 使用。[REFERRER]

是 "http" 或 "https"。

是 "about"、"blob"、 "data"、"file" 或 HTTP(S) scheme

HTTP(S) schemefetch scheme 也被 HTML 使用。[HTML]

2.2. HTTP

虽然 fetch 不仅仅涵盖 HTTP,但它从 HTTP 中借用了许多概念,并将这些概念应用于通过其他方式获取的资源(例如 data URL)。

是 U+0009 制表符或 U+0020 空格。

是 U+000A 换行符、U+000D 回车符,或 HTTP 制表符或空格

HTTP 空白字符 仅适用于在 HTTP 标头上下文之外重用的特定构造(例如 MIME 类型)。对于 HTTP 标头值,优先使用 HTTP 制表符或空格,而在该上下文之外则优先使用 ASCII 空白字符。与 ASCII 空白字符 不同的是,这里不包括 U+000C 换页符。

是 0x0A (LF) 或 0x0D (CR)。

是 0x09 (HT) 或 0x20 (SP)。

HTTP 换行字节HTTP 制表符或空格字节

,从 字符串 input 中,给定一个 位置变量 position 及一个可选的布尔值 extract-value(默认为 false):

  1. positionStart 设为 position

  2. value 设为空字符串。

  3. 断言:inputposition 处的 码点 是 U+0022 (")。

  4. position 前移 1。

  5. 执行如下操作,直到结束:

    1. 将从 inputposition 处的 收集到的序列码点,若不为 U+0022 (") 或 U+005C (\) 则附加到 value

    2. 如果 position 超过 input 末尾,则 终止

    3. quoteOrBackslash 设为 inputposition 处的 码点

    4. position 前移 1。

    5. 如果 quoteOrBackslash 是 U+005C (\),则执行以下操作:

      1. 如果 position 超过 input 末尾,则将 U+005C (\) 附加到 value终止

      2. positioninput 中的 码点 附加到 value

      3. position 前移 1。

    6. 否则:

      1. 断言:quoteOrBackslash 是 U+0022 (")。

      2. 终止

  6. 如果 extract-value 为 true,则返回 value

  7. 返回 input 中从 positionStartposition码点,包括在内。

输入 输出 extract-value 设为 true 的输出 最终 位置变量
""\" ""\" "\" 2
""Hello" World" ""Hello"" "Hello" 7
""Hello \\ World\""" ""Hello \\ World\""" "Hello \ World"" 18

在这些示例中,位置变量 总是从 0 开始。

2.2.1. 方法

是符合 字节序列方法 标记产生式。

是 `GET`、 `HEAD` 或 `POST` 的 方法

是 `CONNECT`、`TRACE` 或 `TRACK` 的 方法,与 字节不区分大小写 相匹配。[HTTPVERBSEC1][HTTPVERBSEC2][HTTPVERBSEC3]

要对 进行 规范化,如果它是 `DELETE`、`GET`、 `HEAD`、`OPTIONS`、`POST` 或 `PUT` 的 字节不区分大小写 匹配项,则将其 字节大写化

规范化 是为了向后兼容和跨 API 一致性进行的,因为 方法 实际上是 “区分大小写” 的。

使用 `patch` 很可能会导致 `405 Method Not Allowed`。而 `PATCH` 更有可能成功。

方法 没有任何限制。 `CHICKEN` 是完全可以接受的(而不是 `CHECKIN` 的拼写错误)。除了那些 规范化 的方法外,对大小写也没有限制。 `Egg` 或 `eGg` 也是可以的,尽管为了统一建议使用大写。

2.2.2.

HTTP通常将头部称为“字段”或“头字段”。Web平台使用更口语化的术语“头”。[HTTP]

是零个或多个列表中的。它最初为« »。

头列表本质上是一个专门的多映射:一个有序的键值对列表,可能有重复的键。由于除了`Set-Cookie`之外的头在暴露给客户端JavaScript时总是被合并,实施可以选择更高效的表示,只要它们也支持与`Set-Cookie`头相关的数据结构即可。

,给定头名name和字符串type,从头列表list中,执行以下步骤。它们返回null或结构化字段值

  1. 断言:type是"dictionary"、"list"或"item"之一。

  2. value成为listname获得的结果。

  3. 如果value为null,则返回null。

  4. result成为解析结构化字段的结果,input_string设置为valueheader_type设置为type

  5. 如果解析失败,则返回null。

  6. 返回result

获取结构化字段值有意不区分是否存在,以及其是否解析为结构化字段值失败。这确保了Web平台的一致处理。

,给定一个元组(头名name结构化字段值structuredValue),在头列表list中:

  1. serializedValue成为执行序列化结构化字段算法得到的structuredValue的结果。

  2. 设置nameserializedValue)在list中。

结构化字段值定义为HTTP最终可以以有趣和有效的方式序列化的对象。目前,Fetch仅支持作为头值字节序列,这意味着这些对象只能通过序列化设置在头列表中,且只能通过解析从头列表中获得。在未来,它们作为对象的事实可能会被端到端地保留。[RFC8941]


一个头列表list一个头名name,如果list包含一个,其名字是与name字节不区分大小写匹配的。

一个头名name头列表list中,运行这些步骤。它们返回null或头值

  1. 如果list不包含name,则返回null。

  2. 返回list中所有,其名字是与name字节不区分大小写匹配的,彼此之间用0x2C 0x20分隔,按顺序排列。

一个头名name头列表list中,运行这些步骤。它们返回null或字符串列表。

  1. value成为获取namelist的结果。

  2. 如果value为null,则返回null。

  3. 返回获取、解码和拆分value的结果。

这是获取、解码和拆分的实际工作方式,name参数为`A`:

头(如在网络上) 输出
A: nosniff,
« "nosniff", "" »
A: nosniff
B: sniff
A:
A:
B: sniff
« "" »
B: sniff
null
A: text/html;", x/x
« "text/html;", x/x" »
A: text/html;"
A: x/x
A: x/x;test="hi",y/y
« "x/x;test="hi"", "y/y" »
A: x/x;test="hi"
C: **bingo**
A: y/y
A: x / x,,,1
« "x / x", "", "", "1" »
A: x / x
A: ,
A: 1
A: "1,2", 3
« ""1,2"", "3" »
A: "1,2"
D: 4
A: 3

一个头值value,运行这些步骤。它们返回字符串列表。

  1. input成为等同解码value的结果。

  2. position成为input位置变量,初始指向input的开头。

  3. values成为一个字符串列表,初始为« »。

  4. temporaryValue为空字符串。

  5. 当为真时:

    1. 将结果收集的代码点序列(不是U+0022(")或U+002C(,))从input中,给定position,添加到temporaryValue

      结果可能是空字符串。

    2. 如果 position 没有超出 input 的末尾,且 inputposition 位置的 代码点 是 U+0022 ("):

      1. 将从 input 中,基于 position收集到的 HTTP 引号字符串 结果追加到 temporaryValue

      2. 如果 position 没有超出 input 的末尾,则 继续
    3. 移除 temporaryValue 开头和结尾的所有HTTP 制表符或空格

    4. temporaryValue 追加到 values

    5. temporaryValue 设为空字符串。

    6. 如果 position 超出 input 的末尾,则返回 values

    7. 断言inputposition 位置的 代码点 是 U+002C (,)。

    8. position 前进 1。

除了特别指定的调用点,以上算法不得直接调用。应使用 获取、解码并拆分 代替。

一个namevalue)到一个头列表list中:

  1. 如果list包含name,则将name设置为第一个匹配的名字

    这重用了list中已存在的名字的大小写。如果有多个匹配的,它们的名字都将相同。

  2. 追加namevalue)到list

一个头名name从一个头列表list中,移除所有,其名字name字节不区分大小写匹配,从list中。

一个namevalue)在头列表list中:

  1. 如果list包含name,则将第一个匹配的的值设置为value并移除其他的。

  2. 否则,追加namevalue)到list

一个namevalue)在头列表list中:

  1. 如果list包含name,则将第一个匹配的头值设置为value,并在其后追加0x2C 0x20,再追加value

  2. 否则,追加namevalue)到list

合并XMLHttpRequestWebSocket协议握手使用。

,给定名称列表headerNames,执行这些步骤。它们返回一个有序集合头名

  1. headerNamesSet成为一个新的有序集合

  2. 对于每一个headerNamesname追加结果字节小写nameheaderNamesSet

  3. 返回结果排序headerNamesSet按升序排序,并使用字节小于

一个头列表list,执行这些步骤。它们返回一个头列表

  1. headers成为一个头列表

  2. names成为结果将头名称转换为排序的小写集合与所有的名字list中。

  3. 对于每一个namesname

    1. 如果name是`set-cookie`,则:

      1. values成为一个列表,包含所有list中,其名字是与name字节不区分大小写匹配的,按顺序排列。

      2. 对于每一个valuesvalue

        1. 追加namevalue)到headers

    2. 否则:

      1. value成为结果获取namelist中。

      2. 断言:value非null。

      3. 追加namevalue)到headers

  4. 返回headers


一个是一个元组,由一个(一个头名)和(一个头值)组成。

一个是一个字节序列,匹配字段名标记生成。

一个是一个字节序列,匹配以下条件:

头值的定义并不基于字段值标记生成,因为它与已部署的内容不兼容

一个字节序列potentialValue,移除任何前导和尾随HTTP空白字节potentialValue


要确定是否一个namevalue)是一个,运行这些步骤:

  1. 如果value长度大于128,则返回false。

  2. 字节小写name并根据结果切换:

    `accept`

    如果value包含一个CORS不安全的请求头字节,则返回false。

    `accept-language`
    `content-language`

    如果value包含一个不在范围0x30(0)到0x39(9)之间的字节,不在范围0x41(A)到0x5A(Z)之间的字节,不在范围0x61(a)到0x7A(z)之间的字节,并且不是0x20(SP),0x2A(*),0x2C(,),0x2D(-),0x2E(.),0x3B(;),或0x3D(=)的字节,则返回false。

    `content-type`
    1. 如果value包含一个CORS不安全的请求头字节,则返回false。

    2. mimeType成为结果解析 的结果,解析value的结果。

    3. 如果mimeType解析失败,则返回false。

    4. 如果mimeType本质不是"application/x-www-form-urlencoded","multipart/form-data",或"text/plain",则返回false。

    这故意不使用提取MIME类型,因为该算法相对宽容,而服务器并不期望实现它。

    如果使用了提取MIME类型,以下请求将不会导致CORS预检,服务器上的简单解析器可能会将请求体视为JSON:

    fetch("https://victim.example/naïve-endpoint", {
    method: "POST",
    headers: [
          ["Content-Type", "application/json"],
          ["Content-Type", "text/plain"]
    ], 
    credentials: "include",
    body: JSON.stringify(exerciseForTheReader) 
    }); 
    
    `range`
    1. rangeValue成为结果解析单个范围头值给定value和false。

    2. 如果rangeValue解析失败,则返回false。

    3. 如果rangeValue[0]为null,则返回false。

      由于网络浏览器历史上没有发出类似`bytes=-500`的范围,本算法不将它们列入白名单。

    其他情况

    返回false。

  3. 返回true。

对于`Content-Type`头的安全列表,有有限的例外,如在CORS协议例外中记录的那样。

一个是一个字节byte,满足以下任一条件:

,给定头列表headers,确定如下:

  1. unsafeNames成为一个新的列表

  2. potentiallyUnsafeNames成为一个新的列表

  3. safelistValueSize为0。

  4. 对于每一个headersheader

    1. 如果header不是CORS安全列出的请求头,则追加header名字unsafeNames

    2. 否则,追加header名字potentiallyUnsafeNames,并增加safelistValueSizeheader长度

  5. 如果safelistValueSize大于1024,则对于每一个potentiallyUnsafeNamesname追加nameunsafeNames

  6. 返回使用unsafeNames进行的将头名称转换为排序的小写集的结果。

是一个头名,是与`Authorization`字节不区分大小写匹配的。

是一个头名,是与以下之一字节不区分大小写匹配的

这些是可以由特权API设置的头,如果它们的关联请求对象被复制,则会被保留,但如果请求被非特权API修改,则会被移除。

`Range`头常用于下载媒体获取

提供了一个帮助程序来将范围头添加到特定请求。

,给定列表头名list,是一个头名,与以下之一字节不区分大小写匹配的:

是一个头名,是与以下之一字节不区分大小写匹配的:

要确定是否一个namevalue)是一个,运行这些步骤:

  1. 如果name不是一个no-CORS安全列出的请求头名,则返回false。

  2. 返回是否(namevalue)是一个CORS安全列出的请求头

一个namevalue)是,如果这些步骤返回true:

  1. 如果name是一个字节不区分大小写匹配的:

    则返回true。

  2. 如果name字节小写化`proxy-`或`sec-`开头,则返回true。

  3. 如果name是一个字节不区分大小写匹配的:

    • `X-HTTP-Method`
    • `X-HTTP-Method-Override`
    • `X-Method-Override`

    则:

    1. parsedValues成为结果获取,解码和拆分value

    2. 对于每一个parsedValuesmethod:如果method同构编码是一个禁止的方法,则返回true。

  4. 返回false。

这些被禁止是为了让用户代理对它们保持完全控制。

头名以`Sec-`开头是为了允许铸造新的,它们可以从API中使用,如允许开发者控制fetch,如XMLHttpRequest[XHR]

`Set-Cookie`头在语义上是一个响应头,所以在请求上没有用处。因为`Set-Cookie`头不能组合,它们需要在Headers对象中进行更复杂的处理。这里禁止它是为了避免将这种复杂性泄露到请求中。

是一个头名,是与以下之一字节不区分大小写匹配的:

是一个头名,是与以下之一字节不区分大小写匹配的:


,给定header,运行这些步骤:

  1. 如果解析header,根据headerABNFheader名字失败,则返回失败。

  2. 返回一个或多个,结果来自解析header,根据headerABNFheader名字

,给定头名name头列表list,运行这些步骤:

  1. 如果list不包含name,则返回null。

  2. 如果name允许单个,并且list包含多于一个,则返回失败。

    如果需要不同的错误处理,请先提取所需的

  3. values成为一个空的列表

  4. 对于每一个headerlist包含namename

    1. extract成为结果提取头值header

    2. 如果extract失败,则返回失败。

    3. 依次将extract中的每个追加到values中。

  5. 返回values

,给定一个整数rangeStart,一个整数rangeEnd,和一个整数fullLength,运行这些步骤:

  1. contentRange成为`bytes `。

  2. 追加rangeStart序列化并且同构编码,到contentRange

  3. 追加0x2D(-)到contentRange

  4. 追加rangeEnd序列化并且同构编码contentRange

  5. 追加0x2F(/)到contentRange

  6. 追加fullLength序列化并且同构编码contentRange

  7. 返回contentRange

字节序列value和一个布尔值allowWhitespace,运行这些步骤:

  1. data成为同构解码value

  2. 如果data"bytes"开头,则返回失败。

  3. position成为位置变量data,初始指向data的第5个代码点

  4. 如果allowWhitespace为true,收集一个代码点序列,这些是HTTP制表符或空格,来自data给定position

  5. 如果positiondata代码点不是U+003D(=),则返回失败。

  6. position前进1。

  7. 如果allowWhitespace为true,收集一个代码点序列,这些是HTTP制表符或空格,来自data给定position

  8. rangeStart成为结果收集一个代码点序列,这些是ASCII数字,来自data给定position

  9. rangeStartValue成为rangeStart,解释为十进制数,如果rangeStart不是空字符串;否则为null。

  10. 如果allowWhitespace为true,收集一个代码点序列,这些是HTTP制表符或空格,来自data给定position

  11. 如果positiondata代码点不是U+002D(-),则返回失败。

  12. position前进1。

  13. 如果allowWhitespace为true,收集一个代码点序列,这些是HTTP制表符或空格,来自data给定position

  14. rangeEnd成为结果收集一个代码点序列,这些是ASCII数字,来自data给定position

  15. rangeEndValue成为rangeEnd,解释为十进制数,如果rangeEnd不是空字符串;否则为null。

  16. 如果position不是data的末尾,则返回失败。

  17. 如果rangeEndValuerangeStartValue是null,则返回失败。

  18. 如果rangeStartValuerangeEndValue是数字,并且rangeStartValue大于rangeEndValue,则返回失败。

  19. 返回(rangeStartValuerangeEndValue)。

    范围结束或起始可以省略,例如`bytes=0-`或`bytes=-500`是有效的范围。

解析单个范围头值对于允许的范围头值子集是成功的,但它是用户代理在请求媒体或恢复下载时使用的最常见形式。这种格式的范围头值可以使用添加范围头设置。


是一个实现定义的头值为`User-Agent`

是`text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8`。

2.2.3. 状态码

是一个在0到999范围内的整数。

将HTTP/1的status-code映射到这个概念中的各种边缘情况正在问题 #1156中处理。

是一个状态码,其值为101、103、204、205或304。

是一个在200到299范围内的状态码

是一个状态码,其值为301、302、303、307或308。

2.2.4. 主体

包括以下内容:

一个主体body,请执行以下步骤:

  1. 让« out1out2 »成为双路分流body的结果。

  2. body设置为out1

  3. 返回一个主体,其out2,其他成员从body复制。

要获取一个字节序列bytes,请返回主体,其结果为安全提取bytes的结果。


一个主体body,给定一个算法processBodyChunk、一个算法processEndOfBody、一个算法processBodyError,以及一个可选的null、并行队列全局对象taskDestination(默认为null),请执行以下步骤。processBodyChunk必须是接受字节序列的算法。processEndOfBody必须是接受无参数的算法。processBodyError必须是接受异常的算法。

  1. 如果taskDestination为null,则将taskDestination设置为启动新并行队列的结果。

  2. reader成为获取一个读取器的结果,针对body

    此操作不会抛出异常。

  3. 执行逐步读取循环,给定readertaskDestinationprocessBodyChunkprocessEndOfBodyprocessBodyError

要执行,给定一个ReadableStreamDefaultReader对象reader并行队列全局对象taskDestination、算法processBodyChunk、算法processEndOfBody和算法processBodyError

  1. readRequest成为以下读取请求

    块步骤,给定chunk
    1. continueAlgorithm设为null。

    2. 如果chunk不是Uint8Array对象,则将continueAlgorithm设置为以下步骤:给定TypeError,运行processBodyError

    3. 否则:

      1. bytes成为chunk副本

        强烈建议实现尽可能采用避免此副本的策略。

      2. continueAlgorithm设置为以下步骤:

        1. 给定bytes,运行processBodyChunk

        2. 给定readertaskDestinationprocessBodyChunkprocessEndOfBodyprocessBodyError,执行逐步读取循环

    4. 给定continueAlgorithmtaskDestination将获取任务排队

    关闭步骤
    1. 给定processEndOfBodytaskDestination将获取任务排队

    错误步骤,给定e
    1. 给定processBodyErrortaskDestination将获取任务排队,运行processBodyError并给定e

  2. reader读取一个块,给定readRequest

一个主体body,给定一个算法processBody、一个算法processBodyError,以及一个可选的null、并行队列全局对象taskDestination(默认为null),请执行以下步骤。processBody必须是接受字节序列的算法。processBodyError必须是一个可选的接受异常的算法。

  1. 如果taskDestination为null,则将taskDestination设置为启动新并行队列的结果。

  2. 给定一个字节序列bytes,让successSteps成为bytes将获取任务排队,运行processBody并给定bytes,并使用taskDestination

  3. 给定一个可选的异常exception,让errorSteps成为exception将获取任务排队,运行processBodyError并给定exception,并使用taskDestination

  4. reader成为获取一个读取器的结果,针对body。如果抛出异常,则使用该异常运行errorSteps并返回。

  5. 给定successStepserrorSteps,从reader读取所有字节


是一个元组,包括一个(一个主体)和一个(一个头部值或null)。


,给定codingsbytes,请执行以下步骤:

  1. 如果codings不受支持,则返回bytes

  2. 返回使用codings解码bytes的结果,如HTTP中所述,如果解码未导致错误,则返回结果,否则失败。[HTTP]

2.2.5. 请求

本节详细记录了请求的工作原理。要开始,请参阅 设置请求

输入到fetch的是一个

一个请求有一个相关联的(一个方法)。除非另有说明,否则它是`GET`。

在重定向过程中,可以将其更新为`GET`,如HTTP 获取中所述。

一个请求有一个相关联的(一个URL)。

建议实现将其设为指向URL列表中第一个URL的指针。它仅作为其他标准集成Fetch的便利字段提供。

一个请求有一个相关联的。除非另有说明,否则该标志未设置。

一个请求有一个相关联的(一个头列表)。除非另有说明,否则它为« »。

一个请求有一个相关联的。除非另有说明,否则该标志未设置。

通过APIs如fetch()XMLHttpRequest,设置不安全请求标志,以确保根据所提供的方法头列表执行CORS预检Fetch。这并不意味着API可以使用禁止的方法禁止的请求头

一个请求有一个相关联的(null,一个字节序列,或一个主体)。除非另有说明,否则它为null。

将会安全地提取到一个主体中,并且在HTTP 获取过程中,可能会因为某些重定向而将此字段设置为null。


一个请求有一个相关联的(null或一个环境设置对象)。

一个请求有一个相关联的(null,一个环境,或一个环境设置对象)。除非另有说明,否则它为null。

这仅用于导航请求和worker请求,但不包括服务worker请求。它引用了一个环境用于导航请求和一个环境设置对象用于worker请求。

一个请求有一个相关联的(一个字符串)。除非另有说明,否则它是空字符串。

这仅用于导航请求。它是目标浏览上下文的id活动文档环境设置对象的ID。

一个请求有一个相关联的("no-window","client"或一个环境设置对象,其全局对象是一个Window对象)。除非另有说明,否则它是"client"。

"client"的值在fetching过程中会被更改为"no-window"或请求的客户端。它为标准提供了一种方便的方式,不必显式设置请求的window

一个请求有一个相关联的布尔值。除非另有说明,否则它为false。

这可以用于允许请求超出环境设置对象的生命周期,例如,navigator.sendBeacon()和HTML img元素会使用此功能。设置为true的请求需要额外的处理要求。

一个请求有一个相关联的,可以是null,"audio", "beacon", "body", "css", "early-hints", "embed", "fetch", "font", "frame", "iframe", "image", "img", "input", "link", "object", "ping", "script", "track", "video", "xmlhttprequest",或"other"。除非另有说明,否则它为null。[RESOURCE-TIMING]

一个请求有一个相关联的,它可以是"all"或"none"。除非另有说明,否则它为"all"。

这决定了哪些service workers会接收到这个fetch的fetch事件。

"all"
相关的service workers会为这个fetch接收到fetch事件。
"none"
没有service workers会为这个fetch接收到事件。

一个请求有一个相关联的,可以是空字符串,"download","imageset","manifest","prefetch","prerender",或"xslt"。除非另有说明,否则它为空字符串。

目前,请求发起者的粒度不是特别细,因为其他规范不需要它如此。它主要是一个规范工具,用于辅助定义CSP和混合内容。它不会暴露给JavaScript。[CSP] [MIX]

一个请求有一个相关联的,可以是空字符串,"audio", "audioworklet", "document", "embed", "font", "frame", "iframe", "image", "json", "manifest", "object", "paintworklet", "report", "script", "serviceworker", "sharedworker", "style", "track", "video", "webidentity", "worker", 或"xslt"。除非另有说明,否则它为空字符串。

这些在RequestDestination中反映出来,除了"serviceworker"和"webidentity",因为具有这些目的地的fetch会跳过service workers。

一个请求目的地,如果它是"audioworklet","paintworklet","script","serviceworker","sharedworker",或"worker"。

使用类似脚本的算法还应该考虑"xslt",因为它也可以导致脚本执行。它未包含在列表中,因为它并不总是相关,并且可能需要不同的行为。

下表说明了请求发起者目的地、CSP指令和功能之间的关系。对于功能而言,它并不详尽。功能需要在各自的标准中定义相关的值。

发起者 目的地 CSP 指令 功能
"" "report" CSP,NEL报告。
"document" HTML的导航算法(仅限顶级)。
"frame" child-src HTML的<frame>
"iframe" child-src HTML的<iframe>
"" connect-src navigator.sendBeacon()EventSource,HTML的<a ping=""><area ping="">fetch()XMLHttpRequestWebSocket,缓存 API
"object" object-src HTML的<object>
"embed" object-src HTML的<embed>
"audio" media-src HTML的<audio>
"font" font-src CSS的@font-face
"image" img-src HTML的<img src>/favicon.ico资源,SVG的<image>,CSS的background-image,CSS的cursor,CSS的list-style-image,…
"audioworklet" script-src audioWorklet.addModule()
"paintworklet" script-src CSS.paintWorklet.addModule()
"script" script-src HTML的<script>importScripts()
"serviceworker" child-srcscript-srcworker-src navigator.serviceWorker.register()
"sharedworker" child-srcscript-srcworker-src SharedWorker
"webidentity" connect-src Federated Credential Management请求
"worker" child-srcscript-srcworker-src Worker
"json" connect-src import "..." with { type: "json" }
"style" style-src HTML的<link rel=stylesheet>,CSS的@importimport "..." with { type: "css" }
"track" media-src HTML的<track>
"video" media-src HTML的<video>元素
"download" "" HTML的download="",“另存为...” UI
"imageset" "image" img-src HTML的<img srcset><picture>
"manifest" "manifest" manifest-src HTML的<link rel=manifest>
"prefetch" "" default-src(无特定指令) HTML的<link rel=prefetch>
"prerender" HTML的<link rel=prerender>
"xslt" "xslt" script-src <?xml-stylesheet>

CSP的form-action需要直接在HTML的导航或表单提交算法中挂钩。

CSP还需要检查请求客户端全局对象关联的Document祖先导航以适用于各种CSP指令。


一个请求有一个相关联的,可以是"high"、"low"或 "auto"。除非另有说明,否则它是"auto"。

一个请求有一个相关联的(null 或一个实现定义的对象)。除非另有说明,否则它是null。

一个请求有一个相关联的,可以是 "client"或一个。除非另有说明,否则它是 "client"。

"client"在获取过程中发生改变时提供了 方便的方式,避免标准需要设置请求

一个请求有一个相关联的,可以是 "client"或一个策略容器。除非另有说明,否则它是 "client"。

"client"在策略容器获取过程中发生改变时提供了 方便的方式,避免标准需要设置请求策略容器

一个请求有一个相关联的,可以是 "no-referrer"、"client"或一个URL。除非另有说明, 它是"client"。

"client" 在获取过程中会更改为 "no-referrer" 或URL。它为标准提供了一种方便的方式,不必设置请求引用

一个请求有一个相关联的,它是一个引用者策略。除非另有说明,否则它是空字符串。[REFERRER]

这可以用于覆盖此请求的引用者策略。

一个请求有一个相关联的,可以是 "same-origin"、"cors"、"no-cors"、 "navigate"或"websocket"。除非另有说明,否则它是 "no-cors"。

"same-origin"
用于确保请求发往同源URL。如果请求未发往同源URL,Fetch将返回 一个网络错误
"cors"
对于那些响应污染设置为"cors"的请求, 将请求变为CORS请求——在这种情况下,如果请求的资源不理解CORS协议,或如果请求的资源是故意不参与CORS协议的,fetch将返回一个网络错误
"no-cors"
限制请求使用CORS安全方法CORS安全请求头。成功后,fetch将返回一个不透明过滤响应
"navigate"
这是一个仅在在文档间导航时使用的特殊模式。
"websocket"
这是一个仅在建立WebSocket连接时使用的特殊模式。

尽管默认的请求模式是 "no-cors",但强烈建议标准不要在新功能中使用它。它是相当不安全的。

一个请求有一个相关联的。除非另有说明,否则它是未设置的。

设置use-CORS-preflight 标志是导致CORS 预检请求的几个条件之一。如果在XMLHttpRequestUpload 对象上注册了一个或多个事件监听器,或在请求中使用了ReadableStream 对象,则会设置use-CORS-preflight 标志

一个请求有一个相关联的, 可以是"omit"、"same-origin"或 "include"。除非另有说明,否则它是"same-origin"。

"omit"
从此请求中排除凭证,并使响应中返回的任何凭证被忽略。
"same-origin"
包括向同源URL发出的请求中的凭证,并使用从同源URL返回的任何凭证。
"include"
总是包括此请求的凭证,并总是使用响应中返回的任何凭证。

请求凭证模式控制着在获取期间凭证的流动。当请求模式是 "navigate"时,它的凭证模式 被认为是"include",并且fetch目前不 考虑其他值。如果HTML在此处进行更改,此标准将需要相应的更改。

一个请求有一个相关联的。 除非另有说明,否则它是未设置的。

当此标志设置时,当一个请求URL具有一个用户名密码,并且存在一个认证条目用于该请求,则该URL的凭证优先于认证条目的凭证。现代规范避免设置此标志,因为在URL中放置凭证是不被鼓励的,但一些旧的功能为兼容性原因而设置此标志。

一个请求有一个相关联的,可以是 "default"、"no-store"、"reload"、 "no-cache"、"force-cache"或 "only-if-cached"。除非另有说明,否则它是"default"。

"default"
Fetch将在访问网络的途中检查HTTP缓存。如果HTTP缓存中包含匹配的新鲜响应,它将被返回。如果HTTP缓存中包含匹配的stale-while-revalidate响应,它将被返回,并将进行一个条件网络获取以更新HTTP缓存中的条目。如果HTTP缓存中包含匹配的过期响应,将返回一个条件网络获取以更新HTTP缓存中的条目。否则,将返回一个非条件网络获取以更新HTTP缓存中的条目。[HTTP][HTTP-CACHING][STALE-WHILE-REVALIDATE]
"no-store"
Fetch的行为就好像根本没有HTTP缓存一样。
"reload"
Fetch的行为就像在访问网络的途中没有HTTP缓存。因此,它会创建一个正常请求,并用响应更新HTTP缓存。
"no-cache"
如果HTTP缓存中有响应,Fetch将创建一个条件请求,否则创建一个正常请求。然后它用响应更新HTTP缓存。
"force-cache"
Fetch使用HTTP缓存中与请求匹配的任何响应,而不关注陈旧性。如果没有响应,它会创建一个正常请求,并用响应更新HTTP缓存。
"only-if-cached"
Fetch使用HTTP缓存中与请求匹配的任何响应,而不关注陈旧性。如果没有响应,它会返回一个网络错误。(只能在请求模式为"same-origin"时使用。任何缓存的重定向都将被遵循,前提是请求重定向模式为"follow",并且重定向不会违反请求模式。)

如果头列表包含`If-Modified-Since`、`If-None-Match`、`If-Unmodified-Since`、`If-Match`或`If-Range`,fetch将在其缓存模式为"default"时,将其设置为"no-store"。

一个请求有一个相关联的,可以是 "follow"、"error"或"manual"。 除非另有说明,否则它是"follow"。

"follow"
在获取资源时遵循所有重定向。
"error"
当请求遇到重定向时,返回一个网络错误
"manual"
在请求遇到重定向时,获取一个不透明重定向过滤响应,以允许服务工作者离线重播重定向。响应在其他方面与网络错误无法区分,以不违反原子HTTP重定向处理

一个请求有一个相关联的(一个字符串)。除非另有说明,否则它是空字符串。

一个请求有一个相关联的(一个字符串)。除非另有说明,否则它是空字符串。

一个请求有一个相关联的,可以是空字符串、 "parser-inserted"或 "not-parser-inserted"。除非另有说明,否则它是空字符串。

一个请求加密随机数元数据解析器元数据通常从HTML元素的属性和标志中填充,这些元素负责创建一个请求。它们用于内容安全策略中的各种算法,以确定在给定上下文中是否应阻止请求或响应。

一个请求有一个相关联的。 除非另有说明,否则它未设置。

此标志仅供HTML的导航算法专用。[HTML]

一个请求有一个相关联的。 除非另有说明,否则它未设置。

此标志仅供HTML的导航算法专用。[HTML]

一个请求有一个相关联的布尔值。 除非另有说明,否则它为false。

这是HTML的导航算法专用的。[HTML]

一个请求有一个相关联的布尔值。 除非另有说明,否则它为false。

此标志仅供HTML的渲染阻塞机制专用。[HTML]


一个请求有一个相关联的(一个或多个列表)。 除非另有说明,否则它是包含请求URL的副本的列表。

一个请求有一个相关联的。 它是指向最后一个URL的指针,在请求URL列表中。

一个请求有一个相关联的。 除非另有说明,否则它为零。

一个请求有一个相关联的, 它可以是"basic"、"cors"或"opaque"。 除非另有说明,否则它是"basic"。

一个请求有一个相关联的。 除非另有说明,否则它未设置。

一个请求有一个相关联的。 除非另有说明,否则它未设置。

一个请求有一个相关联的。除非另有说明,否则它未设置。

一个请求URL列表当前URL重定向计数响应污染完成标志时间允许失败标志Fetch算法用作簿记详情。


是一个请求,其目标是"audio"、 "audioworklet"、 "font"、"image"、"json"、"manifest"、 "paintworklet"、"script"、"style"、"track"、 "video"、"xslt"或空字符串。

是一个请求,其目标是"document"、"embed"、 "frame"、"iframe"、"object"、 "report"、 "serviceworker"、"sharedworker"或"worker"。

是一个请求,其目标是 "document"、"embed"、"frame"、"iframe"或"object"。

有关这些术语的用法,请参见处理Fetch[SW]


一个请求 请求如果满足以下步骤返回true,则具有一个

  1. lastURL为null。

  2. 请求URL列表中的每个url

    1. 如果lastURL是null,则将lastURL设置为url继续

    2. 如果url来源lastURL来源同源,并且请求来源lastURL来源同源,则返回true。

    3. 设置lastURLurl
  3. 返回false。

,给定一个请求 请求,运行以下步骤:

  1. 如果请求重定向污染来源,则返回"null"。

  2. 返回请求来源序列化

,给定一个请求 请求, 运行以下步骤来返回序列化请求来源的结果,同构编码


为了一个请求 请求,运行以下步骤:

  1. newRequest请求的副本,但不包括它的正文

  2. 如果请求正文非空,将newRequest正文设置为克隆请求正文的结果。

  3. 返回newRequest


为了到一个请求 请求,并带有一个整数first和一个可选的整数last,运行以下步骤:

  1. 断言:未提供last,或first小于或等于last

  2. rangeValue为`bytes=`。

  3. 序列化同构编码first,并将结果附加到rangeValue

  4. 将0x2D (-)附加到rangeValue

  5. 如果提供了last,则序列化同构编码它,并将结果附加到rangeValue

  6. 附加(`Range`,rangeValue)到请求标头列表

范围标头表示一个包含的字节范围。这里一个范围标头first是0而last是500,表示一个501字节的范围。

将多个响应组合成一个逻辑资源的功能历来是安全漏洞的来源。请为涉及部分响应的功能寻求安全审查。


为了,给定一个响应 响应,运行以下步骤:

  1. 断言:响应URL列表非空

  2. url响应URL列表[0]的副本。

    这不是响应URL,以避免泄露关于重定向目标的信息(请参见CSP报告中的类似考虑)。[CSP]

  3. 设置用户名给定url和空字符串。

  4. 设置密码给定url和空字符串。

  5. 返回url序列化,并设置排除片段为true。

为了检查,给定一个请求请求,运行以下步骤:

  1. 如果请求模式不是"no-cors",则返回true。

  2. 如果请求客户端是null,则返回true。

  3. 如果请求客户端策略容器嵌入策略不是"credentialless",则返回true。

  4. 如果请求来源请求当前URL来源同源,并且请求没有重定向污染来源,则返回true。

  5. 返回false。

2.2.6. 响应

Fetch的结果是一个。一个响应会随着时间的推移而演变。也就是说,并不是所有的字段都能立即获得。

一个响应有一个相关联的,它可以是 "basic", "cors", "default", "error", "opaque",或 "opaqueredirect"。 除非另有说明,否则它是"default"。

一个响应可以有一个相关联的,该标志最初未设置。

这表明请求被开发人员或终端用户故意中止。

一个响应有一个相关联的。它是指向URL的指针,位于响应URL 列表的最后,如果响应URL 列表为空,则为null。

一个响应有一个相关联的(一个列表,包含零个或多个URL)。除非另有说明,否则它是« »。

除去第一个和最后一个URL(如果有的话),响应URL 列表不会直接暴露给脚本,因为那样会违反原子 HTTP 重定向处理

一个响应有一个相关联的,它是一个状态。 除非另有说明,否则它是200。

一个响应有一个相关联的。除非另有说明,否则它是空字节序列。

通过 HTTP/2 连接的响应始终将状态消息设为空字节序列,因为 HTTP/2 不支持它们。

一个响应有一个相关联的(一个标头列表)。除非另有说明,否则它是« »。

一个响应有一个相关联的(为null或正文)。除非另有说明,否则它是null。

网络响应正文的来源和长度概念始终为null。

一个响应有一个相关联的(空字符串, "local",或"validated")。除非另有说明,否则它是空字符串。

这是为了供Service WorkersResource Timing使用。[SW] [RESOURCE-TIMING]

一个响应有一个相关联的(零个或多个标头名称的列表)。除非另有说明,否则列表为空。

一个响应通常会通过从`Access-Control-Expose-Headers`标头中提取标头值来设置其CORS暴露的标头名称列表。此列表用于CORS 过滤响应以确定要暴露哪些标头。

一个响应有一个相关联的,最初未设置。

这是用来防止将早期范围请求的部分响应提供给没有发出范围请求的API。有关攻击的详细描述,请参见标志的使用情况。

一个响应有一个相关联的(布尔值),最初为true。

一个响应有一个相关联的,最初未设置。

这是为了使Fetch的调用方可以通过查看返回响应的标志来确定是否允许对提取的资源使用敏感的时间数据。因为在重定向链中的前一个响应已设置标志时,重定向响应的标志也必须设置,这也通过请求的时间允许失败标志进行内部跟踪。

一个响应有一个相关联的(一个响应正文信息)。除非另有说明,否则它是新的响应正文信息

一个响应有一个相关联的(为null或服务工作者计时信息),最初为null。

一个响应有一个相关联的(布尔值),最初为false。


一个是一个响应,其类型为"error",状态 为0,状态消息为空字节序列,标头列表为« »,正文为 null,且正文信息为新的响应正文信息

一个是一个网络 错误,其中止标志已设置。

要根据fetch 参数 fetchParams创建合适的网络错误

  1. 断言:fetchParams取消

  2. 如果fetchParams中止,则返回一个中止的网络错误;否则,返回一个网络错误


一个是一个响应,它对相关联的响应提供有限的视图。此相关联的响应可以通过访问(一个既不是网络错误也不是过滤响应的响应)。

除非另有说明,过滤响应的相关概念(如其正文)指的是其内部响应的相关概念。(对这些的例外情况列在定义过滤响应的具体类型时。)

Fetch算法通过processResponse和等效参数来暴露过滤响应,以确保它们不会意外泄露信息。如果出于遗留原因需要揭示信息,例如向解码器提供图像数据,规范算法可以使用相关联的内部响应

新规范不应在不透明过滤响应不透明重定向过滤响应上进一步构建。它们是遗留构造,并且在当代计算机架构下无法始终得到充分保护。

一个是一个过滤响应,其类型为"basic",且标头列表排除内部响应标头列表中名称为禁止的响应标头名称的任何标头

一个是一个过滤响应,其类型为"cors",且标头列表排除内部响应标头列表中名称CORS-安全列入的响应标头名称标头

一个是一个过滤响应,其类型为"opaque",URL 列表为« »,状态为0,状态消息为空字节序列,标头列表为« »,正文为null,且正文信息为新的响应正文信息

一个是一个过滤响应,其类型为"opaqueredirect",状态为0,状态消息为空字节序列,标头列表为« »,正文为null,且正文信息为新的响应正文信息

暴露不透明重定向过滤响应URL 列表是无害的,因为未执行任何重定向。

换句话说,一个不透明过滤响应和一个不透明重定向过滤响应网络错误几乎无法区分。在引入新的 API 时,请不要在规范算法中使用内部响应,因为那样会泄露信息。

这也意味着 JavaScript API,例如response.ok,将返回相当无用的结果。

通过typegetter将响应的类型暴露给脚本:

console.log(new Response().type); // "default"

console.log((await fetch("/")).type); // "basic"

console.log((await fetch("https://api.example/status")).type); // "cors"

console.log((await fetch("https://crossorigin.example/image", { mode: "no-cors" })).type); // "opaque"

console.log((await fetch("/surprise-me", { redirect: "manual" })).type); // "opaqueredirect"

(这假设存在各种资源,https://api.example/status具有适当的 CORS 标头,并且/surprise-me使用重定向状态。)


一个响应 response,运行以下步骤:

  1. 如果response是一个过滤响应,则返回一个新的相同的过滤响应,其内部响应克隆response内部响应

  2. newResponse成为response的一个副本,除去其正文

  3. 如果response正文不为null,则将newResponse正文设置为克隆 response正文的结果。

  4. 返回newResponse


一个是一个响应,其当前年龄在其新鲜度寿命内。

一个是一个响应,它不是一个新鲜响应,其当前年龄陈旧但重新验证寿命内。[HTTP-CACHING] [STALE-WHILE-REVALIDATE]

一个是一个响应,它不是一个新鲜响应或一个陈旧但重新验证响应


给定null或一个ASCII 字符串 requestFragment,一个响应 response是以下步骤返回的值。它们返回null、失败或一个URL

  1. 如果response状态不是重定向状态,则返回null。

  2. location设置为给定`Location`和response标头列表提取标头列表值的结果。

  3. 如果location是一个标头值,则将location设置为使用responseURL解析location的结果。

    如果response是通过Response构造函数构造的,则responseURL将为null,这意味着只有它是一个带片段的绝对 URL 字符串时,location才会成功解析。

  4. 如果location是一个URL,其片段为null,则将location片段设置为requestFragment

    这确保了合成响应(实际上是所有响应)遵循 HTTP 定义的重定向处理模型。[HTTP]

  5. 返回location

位置 URL算法仅用于该标准中的重定向处理以及手动处理重定向的HTML导航算法。[HTML]

2.2.7. 杂项

是 “fetch”或目的地,且不是空字符串。

potentialDestination潜在目的地,运行以下步骤:

  1. 如果potentialDestination为“fetch”,则返回空字符串。

  2. 断言:potentialDestination目的地

  3. 返回potentialDestination

2.3. 认证条目

是用户名、密码和领域的元组,用于HTTP认证和HTTP代理认证,并与一个或多个请求关联。

用户代理应允许这些条目与HTTP cookie和类似的跟踪功能一起清除。

更多详细信息由HTTP定义。[HTTP] [HTTP-CACHING]

2.4. Fetch 组

每个环境设置对象都有一个关联的

一个Fetch 组包含一个有序的列表。

一个Fetch 记录有一个关联的(一个请求)。

一个Fetch 记录有一个关联的(一个Fetch 控制器或null)。


当一个Fetch 组时,对于每个关联的Fetch 记录,如果其Fetch 记录控制器非null,且其请求完成标志未设置或keepalive为false,则终止Fetch 记录控制器

2.5. 解析域名

(这是一个跟踪向量。),给定一个网络分区密钥key和一个来源origin

  1. 如果originhost是一个IP地址,则返回« originhost »。

  2. 如果originhost公共后缀是"localhost"或"localhost.",则返回« ::1127.0.0.1 »。

  3. 执行一个实现定义的操作,将origin转换为一个或多个IP地址集合

    还可以实现定义的其他操作,以获取连接信息,而不仅仅是IP地址。例如,如果originscheme是一个HTTP(S) scheme,实现可能会执行DNS查询以获取HTTPS RRs。[SVCB]

    如果此操作成功,则返回集合,其中包括IP地址和任何额外的实现定义的信息。

  4. 返回失败。

解析来源的结果可以被缓存。如果它们被缓存,则应使用key作为缓存密钥的一部分。

通常此操作会涉及DNS,因此缓存可能发生在DNS服务器上而不考虑key。根据实现的不同,可能也无法在本地考虑key[RFC1035]

解析来源算法返回的IP地址的顺序可能在不同调用之间有所不同。

细节(除了缓存密钥外)没有被严格规定,因为它们与Fetch标准建立的系统无关。其他文档不应该在没有与Fetch标准社区进行充分讨论的情况下,基于此原语进行构建。

2.6. 连接

用户代理有一个关联的。一个连接池是一个有序集合,包含零个或多个。每个连接通过一个关联的(一个网络分区密钥)、(一个来源)、以及(一个布尔值)来标识。

每个连接都有一个关联的(一个连接时间信息)。

是一个用于维护获取连接过程中的时间信息的结构体。它包含以下项目

(默认为0)
(默认为0)
(默认为0)
(默认为0)
(默认为0)
一个DOMHighResTimeStamp
(默认为空的字节序列
一个字节序列

,给定一个连接时间信息timingInfo、一个DOMHighResTimeStampdefaultStartTime和一个布尔值crossOriginIsolatedCapability,运行以下步骤:

  1. 如果timingInfo连接开始时间小于defaultStartTime,则返回一个新的连接时间信息,其中域名查找开始时间defaultStartTime域名查找结束时间defaultStartTime连接开始时间defaultStartTime连接结束时间defaultStartTime安全连接开始时间defaultStartTime,以及ALPN 协商协议timingInfoALPN 协商协议

  2. 返回一个新的连接时序信息,其中域名查询开始时间是给定timingInfo域名查询开始时间crossOriginIsolatedCapability粗化时间的结果,域名查询结束时间是给定timingInfo域名查询结束时间crossOriginIsolatedCapability粗化时间的结果,连接开始时间是给定timingInfo连接开始时间crossOriginIsolatedCapability粗化时间的结果,连接结束时间是给定timingInfo连接结束时间crossOriginIsolatedCapability粗化时间的结果,安全连接开始时间 是给定timingInfo连接结束时间crossOriginIsolatedCapability粗化时间的结果,ALPN 协议协商timingInfoALPN 协议协商


为"no"、"yes"或"yes-and-dedicated"。

,给定一个网络分区密钥keyURLurl、布尔值credentials、一个可选的新连接设置new(默认值为"no"),以及一个可选的布尔值(默认值为false),运行以下步骤:

  1. 如果new为"no",则:

    1. connections为用户代理的连接池连接的集合,其中key密钥originurl来源凭据credentials

    2. 如果connections不为空且requireUnreliable为false,则返回connections中的一个。

    3. 如果在connections中有支持不可靠传输的连接,例如HTTP/3,则返回该连接

  2. proxies为以实现定义的方式找到的用于url的代理的结果。如果没有代理,则令proxies为«"DIRECT"»。

    这是非标准技术(如Web Proxy Auto-Discovery Protocol (WPAD)proxy auto-config (PAC))发挥作用的地方。"DIRECT"值意味着对于这个特定的url不使用代理。

  3. timingInfo为新的连接时间信息

  4. 对于每个proxies中的proxy

    1. timingInfo域名查找开始时间设置为不安全共享当前时间

    2. hosts为«url来源host»。

    3. 如果proxy为"DIRECT",则将hosts设置为运行解析一个origin给定keyurl来源的结果。

    4. 如果hosts为失败,则继续

    5. timingInfo域名查找结束时间设置为不安全共享当前时间

    6. connection为运行以下步骤的结果:运行创建一个连接给定keyurl来源credentialsproxy、从hosts中以实现定义的方式获取的hosttimingInfo、和requireUnreliable,以实现定义的次数彼此并行运行,并等待至少1个返回一个值。在实现定义的方式中,从返回的值中选择一个值并返回它。任何其他返回的为连接的值可能会被关闭。

      本质上,这允许实现从解析一个origin的返回值中选择一个或多个IP地址(假设proxy为"DIRECT")并让它们彼此竞争,优先选择IPv6地址,在超时的情况下重试等。

    7. 如果connection失败,则继续

    8. 如果new不是"yes-and-dedicated",则追加connection到用户代理的连接池

    9. 返回connection

  5. 返回失败。

这故意有点模糊,因为连接管理有很多细微差别,最好由实现者自行决定。描述这一点有助于解释<link rel=preconnect>功能,并明确规定连接凭证为关键。这后一部分澄清了,例如,TLS会话标识符不会在凭证为假的连接与凭证为真的连接之间复用。


,给定一个网络分区密钥key来源origin、布尔值credentials、字符串proxyhosthost连接时间信息timingInfo和布尔值requireUnreliable,运行以下步骤:

  1. timingInfo连接开始时间设置为不安全共享当前时间

  2. connection为新的连接,其中key密钥originorigincredentials凭据timingInfo时间信息记录连接时间信息,给定connection,并使用connection建立一个到host的HTTP连接,考虑proxyorigin,具有以下警告:[HTTP][HTTP1][TLS]

    • 如果requireUnreliable为true,则建立一个支持不可靠传输的连接,例如一个HTTP/3连接。[HTTP3]

    • 在建立一个支持不可靠传输的连接时,启用WebTransport所需的选项。对于HTTP/3,这意味着在初始SETTINGS帧中包括SETTINGS_ENABLE_WEBTRANSPORT,值为1,以及H3_DATAGRAM,值为1[WEBTRANSPORT-HTTP3][HTTP3-DATAGRAM]

    • 如果credentials为false,则不要发送TLS客户端证书。

    • 如果建立连接不成功(例如,UDP、TCP或TLS错误),则返回失败。

  3. timingInfoALPN 协商协议设置为connection的ALPN协议ID,具有以下警告:[RFC7301]

    • 当配置了代理时,如果建立了隧道连接,则这必须是隧道协议的ALPN协议ID,否则必须是到代理的第一跳的ALPN协议ID。

    • 如果用户代理使用了实验性、未注册的协议,则用户代理必须使用使用的ALPN协议ID(如果有)。如果没有使用ALPN进行协议协商,则用户代理可以使用另一个描述性字符串。

      timingInfoALPN 协商协议旨在标识使用的网络协议,无论它实际上是如何协商的;即使ALPN未用于协商网络协议,这也是表示使用的协议的ALPN协议ID。

    IANA维护ALPN协议ID列表

  4. 返回connection


,给定一个连接connection,令timingInfoconnection时间信息,并遵守以下要求:

限制和粗化连接时间信息算法确保了重用连接的细节不会暴露,并且时间值被粗化。

2.7. 网络分区密钥

是由站点和null或实现定义的值组成的元组。

,给定一个环境environment:

  1. topLevelOriginenvironment顶级来源

  2. 如果topLevelOrigin为null,则将topLevelOrigin设置为environment顶级创建URL来源

  3. 断言:topLevelOrigin是一个来源

  4. topLevelSite为给定topLevelOrigin 获取站点的结果。

  5. secondKey为null或实现定义的值。

    第二个密钥故意有些模糊,因为细节仍在发展中。请参见问题#1035

  6. 返回(topLevelSite, secondKey)。

,给定一个请求request:

  1. 如果request保留客户端非null,则返回给定request确定网络分区密钥的结果。

  2. 如果request客户端非null,则返回给定request确定网络分区密钥的结果。

  3. 返回null。

2.8. HTTP缓存分区

,给定一个请求 request:

  1. key为给定request确定网络分区密钥的结果。

  2. 如果key为null,则返回null。

  3. 返回与key关联的唯一HTTP缓存。[HTTP-CACHING]

2.9. 端口封锁

新协议可以通过使用ALPN在TLS中协商协议,避免封锁端口的需求。在这种情况下,该协议无法通过HTTP请求被伪造。[RFC7301]

要确定是否由于使用了而阻止获取一个请求request:

  1. urlrequest当前URL

  2. 如果urlschemeHTTP(S) scheme,并且url端口不良端口,则返回阻止

  3. 返回允许

端口,如果它在以下表格的第一列中列出。

端口 典型服务
1 tcpmux
7 echo
9 discard
11 systat
13 daytime
15 netstat
17 qotd
19 chargen
20 ftp-data
21 ftp
22 ssh
23 telnet
25 smtp
37 time
42 name
43 nicname
53 domain
69 tftp
77 —​
79 finger
87 —​
95 supdup
101 hostname
102 iso-tsap
103 gppitnp
104 acr-nema
109 pop2
110 pop3
111 sunrpc
113 auth
115 sftp
117 uucp-path
119 nntp
123 ntp
135 epmap
137 netbios-ns
139 netbios-ssn
143 imap
161 snmp
179 bgp
389 ldap
427 svrloc
465 submissions
512 exec
513 login
514 shell
515 printer
526 tempo
530 courier
531 chat
532 netnews
540 uucp
548 afp
554 rtsp
556 remotefs
563 nntps
587 submission
601 syslog-conn
636 ldaps
989 ftps-data
990 ftps
993 imaps
995 pop3s
1719 h323gatestat
1720 h323hostcall
1723 pptp
2049 nfs
3659 apple-sasl
4045 npp
4190 sieve
5060 sip
5061 sips
6000 x11
6566 sane-port
6665 ircu
6666 ircu
6667 ircu
6668 ircu
6669 ircu
6679 osaut
6697 ircs-u
10080 amanda

运行以下步骤:

  1. mimeType设为从response标头列表提取的MIME类型的结果。

  2. 如果mimeType为失败,则返回允许

  3. destination设为request目的地

  4. 如果destinationscript-like,并且以下任意一项为真,则返回阻止

    • mimeType本质 "audio/"、"image/" 或 "video/" 开头。
    • mimeType本质是 "text/csv"。
  5. 返回允许

3. HTTP扩展

3.1. `Origin` 标头

请求的`` 标头指示fetch的来源。

`Origin` 标头是一个不显示路径的 `Referer` [sic] 标头版本。它用于所有HTTP fetches,其中requestresponse tainting为`cors`,以及 requestmethod既不是 `GET`也不是`HEAD`。由于兼容性约束,它不包含在所有fetches`中。

其可能的是给定request字节序列化请求来源的所有返回值。

这取代了Web Origin 概念中的定义。[ORIGIN]


为了, 给定requestrequest,请运行以下步骤:

  1. serializedOrigin设为使用request 字节序列化请求来源的结果。

  2. 如果requestresponse tainting为`cors`或 request模式为`websocket`,则将(``Origin``, serializedOrigin)附加到request标头列表中。

  3. 否则,如果requestmethod既不是`GET`也不是`HEAD`,则:

    1. 如果request模式不是`cors`, 则根据request引用者策略进行切换:

      "no-referrer"

      serializedOrigin设置为`null`。

      "no-referrer-when-downgrade"
      "strict-origin"
      "strict-origin-when-cross-origin"

      如果request来源元组来源,其scheme为 `"https"`,且request当前URLscheme不是 `"https"`,则将serializedOrigin设置为`null`。

      "same-origin"

      如果request来源request当前URL来源不同源,则将serializedOrigin设置为 `"null"`。

      否则
      什么也不做。
    2. (`Origin`, serializedOrigin) 附加到request标头列表中。

所有fetches中,request引用者策略都会被考虑在内,而fetcher没有明确选择与服务器共享其来源, 例如通过使用CORS协议

3.2. CORS协议

为了允许跨来源共享响应,并允许比HTML的form 元素可能实现的更灵活的fetches应运而生。它 构建于HTTP之上,并允许响应声明它们可以与其他来源共享。

这需要是一种选择加入的机制,以防止泄露防火墙后(内网)的响应数据。此外,对于包含凭据请求, 也需要选择加入,以防止泄露潜在敏感数据。

本节解释了与服务器开发者相关的CORS协议。用户代理的要求是fetch算法的一部分, 除了新的HTTP标头语法

3.2.1. 概述

CORS协议由一组标头组成, 这些标头指示响应是否可以跨来源共享。

对于比HTML的form 元素更复杂的请求, 会执行CORS预检请求, 以确保request当前URL支持CORS协议

3.2.2. HTTP 请求

是包含 `Origin` 头的HTTP请求。它不能被可靠地识别为参与 CORS协议,因为 `Origin` 头也会包含在 所有请求中,这些请求的方法 既不是 `GET` 也不是 `HEAD`。

是一种 CORS 请求, 用于检查是否理解CORS协议。它使用 `OPTIONS` 作为 方法,并包含以下

``

指示将来对同一资源的CORS 请求可能使用的 方法

CORS预检请求 还可以包含以下

``

指示将来对同一资源的CORS 请求可能使用的

3.2.3. HTTP 响应

CORS 请求的HTTP响应可以包含以下

``

指示响应是否可以共享,通过在响应中返回请求 `Origin` 的字面 (可以是 `null`)或 `*`。

``

指示当请求的请求凭据模式为 "include" 时,响应是否可以共享。

对于 CORS 预检请求,请求的 请求凭据模式总是 "same-origin",即排除凭据,但对于任何后续的 CORS 请求, 它可能不是。因此,也需要在对CORS预检请求的HTTP响应中指明支持。

CORS 预检请求的HTTP响应可以包含以下

``

指示响应的响应URLCORS 协议 支持哪些方法

`Allow` 与CORS协议无关。

``

指示响应的响应URLCORS 协议 支持哪些

``

指示由 `Access-Control-Allow-Methods` 和 `Access-Control-Allow-Headers` 头提供的信息 可以缓存的秒数(默认5秒)。

CORS 请求但不是 CORS 预检请求的HTTP响应还可以包含以下

``

指示可以作为响应的一部分公开的头,通过列出它们的名称


CORS 请求的成功HTTP响应, 即服务器开发者打算共享的响应,可以使用任何 状态, 只要它包含上述头,且头的 与请求匹配。

CORS 预检请求的成功HTTP响应类似,除非它限制为 ok 状态,例如200或204。

任何其他类型的HTTP响应都不是成功的,最终将无法共享或失败 CORS 预检请求。请注意,服务器执行的任何工作仍可能通过侧信道泄露, 例如时间。如果服务器开发者希望明确表示这一点,可以使用403 状态, 并省略相关头。

如果需要,也可以共享“失败”,但这将使其成为成功的HTTP响应。 这就是为什么对于不是 CORS 预检请求的CORS请求的成功HTTP响应, 状态可以是任何值,包括403。

最终,服务器开发者在如何处理HTTP响应方面有很大的自由,这些策略可以在对 CORS 预检请求和随后对 CORS 请求的响应之间有所不同:

3.2.4. HTTP 新头语法

ABNF用于 CORS 协议 所用的

Access-Control-Request-Method    = method
Access-Control-Request-Headers   = 1#field-name

wildcard                         = "*"
Access-Control-Allow-Origin      = origin-or-null / wildcard
Access-Control-Allow-Credentials = %s"true" ; case-sensitive
Access-Control-Expose-Headers    = #field-name
Access-Control-Max-Age           = delta-seconds
Access-Control-Allow-Methods     = #method
Access-Control-Allow-Headers     = #field-name

对于 `Access-Control-Expose-Headers`, `Access-Control-Allow-Methods`,和 `Access-Control-Allow-Headers` 响应,对于不包含 凭据请求,`*`作为值 算作通配符。对于这样的请求, 没有办法单独匹配一个头名称 或 `*` 的方法

3.2.5. CORS 协议与凭据

请求凭据模式为 "include" 时, 它对CORS 协议 的影响不仅限于在fetch中包含 凭据

在过去,XMLHttpRequest 可以用于将请求凭据模式设置为 "include":

var client = new XMLHttpRequest()
client.open("GET", "./")
client.withCredentials = true
/* … */

如今,fetch("./", { credentials:"include" }).then(/* … */) 就足够了。

请求的请求凭据模式不一定在服务器上可观察到; 只有当请求存在凭据时, 才能通过包含凭据来观察到。请注意,即使如此, CORS 预检请求 从不包含凭据。

因此,服务器开发者需要决定是否可以共享带有凭据"污染"的响应。还需要决定是否允许需要 CORS 预检请求 的请求包含凭据。 一般来说,共享带有凭据的响应和允许带有凭据的请求是相当不安全的,必须极其小心地避免困惑的代理问题

要共享带有凭据的响应,Access-Control-Allow-OriginAccess-Control-Allow-Credentials头是重要的。 以下表格旨在说明对于请求 https://rabbit.invalid/ 的各种合法和非法组合:

请求的凭据模式 Access-Control-Allow-Origin Access-Control-Allow-Credentials 共享? 备注
"omit" * 省略
"omit" * true 如果凭据模式不是 "include",则 Access-Control-Allow-Credentials 被忽略。
"omit" https://rabbit.invalid/ 省略 序列化来源没有尾随斜杠。
"omit" https://rabbit.invalid 省略
"include" * true 如果凭据模式是 "include", Access-Control-Allow-Origin 不能是 *
"include" https://rabbit.invalid true
"include" https://rabbit.invalid True true 是字节大小写敏感的。

类似地,Access-Control-Expose-HeadersAccess-Control-Allow-Methods,和 Access-Control-Allow-Headers响应头只有在请求的 凭据模式不是 "include" 时才能使用 `*` 作为值。

3.2.6. 示例

一个位于https://foo.invalid/的脚本想要从https://bar.invalid/获取一些数据。(凭据或响应头访问并不重要。)

var url = "https://bar.invalid/api?key=730d67a37d7f3d802e96396d00280768773813fbe726d116944d814422fc1a45&data=about:unicorn";
fetch(url).then(success, failure)

这将使用CORS 协议,尽管这对来自foo.invalid的开发者来说是完全透明的。作为CORS 协议的一部分, 用户代理将在请求中包含 `Origin` 头:

Origin: https://foo.invalid

在从bar.invalid接收到响应后,用户代理将验证 `Access-Control-Allow-Origin`响应头。 如果它的值是 `https://foo.invalid` 或 `*`,用户代理将调用success回调。 如果它有任何其他值,或者缺失,用户代理将调用failure回调。

foo.invalid的开发者回来了,现在希望在从bar.invalid获取一些数据的同时访问响应头。

fetch(url).then(response => {
  var hsts = response.headers.get("strict-transport-security"),
      csp = response.headers.get("content-security-policy")
  log(hsts, csp)
})

bar.invalid提供了一个正确的 `Access-Control-Allow-Origin`响应头, 如前面的示例所示。hstscsp的值将取决于 `Access-Control-Expose-Headers`响应头。 例如,如果响应包括以下头:

Content-Security-Policy: default-src 'self'
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
Access-Control-Expose-Headers: Content-Security-Policy

那么hsts将为 null,csp将为"default-src 'self'",即使响应中确实包含了两个头。 这是因为bar.invalid需要通过在 `Access-Control-Expose-Headers`响应头中列出它们的名称来明确共享每个头。

或者,如果bar.invalid想要共享所有响应头,对于不包含凭据的请求,可以使用 `*` 作为 `Access-Control-Expose-Headers`响应头的值。 如果请求包含凭据,则响应头名称必须明确列出,且不能使用 `*`。

foo.invalid的开发者再次回来了,这次是在包含凭据的情况下从bar.invalid获取一些数据。 这次CORS 协议对开发者不再透明, 因为凭据需要显式选择加入:

fetch(url, { credentials:"include" }).then(success, failure)

这也使得bar.invalid中包含的任何 `Set-Cookie`响应头完全有效(否则将被忽略)。

用户代理将确保在请求中包含任何相关的凭据。它还将对响应施加更严格的要求。bar.invalid不仅需要在 `Access-Control-Allow-Origin`头中列出 `https://foo.invalid` 作为值(当涉及到凭据时,不允许使用 `*`),还必须包含 `Access-Control-Allow-Credentials`头:

Access-Control-Allow-Origin: https://foo.invalid
Access-Control-Allow-Credentials: true

如果响应未包含这两个头,或它们的值不正确,将调用failure回调。然而,任何`Set-Cookie`响应头仍将被尊重。

3.2.7. CORS 协议例外情况

规范允许针对非安全列表的 `Content-Type` 头值的 CORS 安全列表进行有限的例外。这些例外适用于可以由 Web 内容触发但其头和主体只能由 Web 内容进行最小控制的请求。因此,服务器应预期跨域 Web 内容被允许触发具有以下非安全列表 `Content-Type` 头值的非预检请求:

规范应避免引入新的例外,且应仅在充分考虑安全后果的情况下才这样做。可以通过提交问题来提出新的例外。

3.3. `Content-Length` 头

`Content-Length` 头主要在 HTTP 中定义。由于 HTTP 中定义的处理模型与 Web 内容不兼容,其处理模型在此定义。[HTTP]

要从 头列表 headers,请按以下步骤操作:

  1. values获取、解码并分割headers 的 `Content-Length` 的结果。

  2. 如果 values 为 null,则返回 null。

  3. candidateValue 为 null。

  4. 对于每个 values 中的 value

    1. 如果 candidateValue 为 null,则将 candidateValue 设置为 value

    2. 否则,如果 value 不是 candidateValue,则返回失败。

  5. 如果 candidateValue 是空字符串或具有非 ASCII 数字码点,则返回 null。

  6. 返回解释为十进制数字的 candidateValue

3.4. `Content-Type` 头

`Content-Type` 头主要在 HTTP 中定义。由于 HTTP 中定义的处理模型与 Web 内容不兼容,其处理模型在此定义。[HTTP]

要从 头列表 headers,请运行以下步骤。它们将返回失败或MIME 类型

  1. charset 为 null。

  2. essence 为 null。

  3. mimeType 为 null。

  4. values获取、解码并分割headers 的 `Content-Type` 的结果。

  5. 如果 values 为 null,则返回失败。

  6. 对于每个 values 中的 value

    1. temporaryMimeType解析 value 的结果。

    2. 如果 temporaryMimeType 是失败或其本质为"*/*",则继续

    3. mimeType 设置为 temporaryMimeType

    4. 如果 mimeType本质不为 essence,则:

      1. charset 设置为 null。

      2. 如果 mimeType参数["charset"] 存在,则将 charset 设置为 mimeType参数["charset"]。

      3. essence 设置为 mimeType本质

    5. 否则,如果 mimeType参数["charset"]不存在,且 charset 非 null,则将 mimeType参数["charset"]设置为 charset

  7. 如果 mimeType 为 null,则返回失败。

  8. 返回 mimeType

提取 MIME 类型返回失败或MIME 类型本质对于给定格式不正确时,将其视为致命错误。现有的 Web 平台功能并未始终遵循这一模式,这多年来已成为这些功能中安全漏洞的主要来源。相比之下,MIME 类型参数通常可以安全忽略。

这是 提取 MIME 类型 的实际运作方式:

头(如网络上) 输出(序列化
Content-Type: text/plain;charset=gbk, text/html
text/html
Content-Type: text/html;charset=gbk;a=b, text/html;x=y
text/html;x=y;charset=gbk
Content-Type: text/html;charset=gbk;a=b
Content-Type: text/html;x=y
Content-Type: text/html;charset=gbk
Content-Type: x/x
Content-Type: text/html;x=y
text/html;x=y
Content-Type: text/html
Content-Type: cannot-parse
text/html
Content-Type: text/html
Content-Type: */*
Content-Type: text/html
Content-Type:

在失败或给定MIME 类型 mimeType编码 fallbackEncoding 时,,请运行以下步骤:

  1. 如果 mimeType 为失败,则返回 fallbackEncoding

  2. 如果 mimeType["charset"]不存在,则返回 fallbackEncoding

  3. tentativeEncoding获取编码mimeType["charset"] 的结果。

  4. 如果 tentativeEncoding 为失败,则返回 fallbackEncoding

  5. 返回 tentativeEncoding

此算法允许 mimeType 失败,因此它可以更容易地与提取 MIME 类型结合使用。

它被标记为传统,因为现代格式将专门使用UTF-8

3.5. `X-Content-Type-Options` 标头

可以使用 `` 响应标头,以要求检查响应的 `Content-Type` 标头是否与 请求目标一致。

为了,给定一个标头列表list,请执行以下步骤:

  1. values获取、解码和分割`X-Content-Type-Options` 自 list的结果。

  2. 如果 values 为 null,则返回 false。

  3. 如果 values[0] 是 ASCII 不区分大小写的匹配 "nosniff",则返回 true。

  4. 返回 false。

Web 开发者和一致性检查者必须使用以下 ABNF用于 `X-Content-Type-Options`:

X-Content-Type-Options           = "nosniff" ; case-insensitive

执行以下步骤:

  1. 如果确定 nosniff并且response标头列表为 false,则返回allowed

  2. mimeType设置为从response提取 MIME 类型的结果。

  3. destination设置为request目标

  4. 如果destination类似脚本,并且mimeType为失败或不是JavaScript MIME 类型,则返回blocked

  5. 如果destination是"style"并且mimeType失败或其本质不是"text/css",则返回blocked

  6. 返回allowed

只有请求目标类似脚本或"style"的才被考虑,因为任何漏洞都与它们有关。此外,考虑到"image"与已部署的内容不兼容。

3.6. `Cross-Origin-Resource-Policy` 标头

可以使用 `` 响应标头,以要求检查请求当前 URL是否与 请求匹配 当请求模式为 "no-cors"。

ABNF

Cross-Origin-Resource-Policy     = %s"same-origin" / %s"same-site" / %s"cross-origin" ; case-sensitive

要执行,给定 origin,一个环境设置对象settingsObject,一个字符串destination,一个响应 response,以及一个可选的布尔值forNavigation,请执行以下步骤:

  1. 如果未给定forNavigation,将其设置为 false。

  2. embedderPolicy设置为settingsObject策略容器嵌入者策略

  3. 如果origin,"unsafe-none",responseforNavigation一起执行跨源资源策略内部检查返回blocked,则返回blocked

    此步骤是必要的,因为我们不希望报告与下面的 Cross-Origin Embedder Policy 无关的违规行为。

  4. 如果originembedderPolicy仅报告值responseforNavigation一起执行的跨源资源策略内部检查返回blocked,则排队一个跨源嵌入者策略 CORP 违规报告responsesettingsObjectdestination和 true 一起执行。

  5. 如果originembedderPolicyresponseforNavigation一起执行的跨源资源策略内部检查返回allowed,则返回allowed

  6. 排队一个跨源嵌入者策略 CORP 违规报告responsesettingsObjectdestination和 false 一起执行。

  7. 返回blocked

只有 HTML 的导航算法在forNavigation设置为 true 时才会使用此检查,并且总是用于嵌套导航。否则,response要么是内部响应不透明过滤响应响应,将成为内部响应的不透明过滤响应。[HTML]

要执行,给定 origin,一个嵌入者策略值embedderPolicyValue,一个响应response,以及一个布尔值forNavigation,请执行以下步骤:

  1. 如果forNavigation为 true,并且embedderPolicyValue为"unsafe-none",则返回allowed

  2. policy设置为从response获取`Cross-Origin-Resource-Policy`。

    这意味着`Cross-Origin-Resource-Policy: same-site, same-origin`在下方作为allowed出现,因为只要embedderPolicyValue是"unsafe-none",它将永远不会匹配任何内容。两个或多个`Cross-Origin-Resource-Policy`标头将具有相同效果。

  3. 如果policy既不是`same-origin`,`same-site`,也不是`cross-origin`,则将policy设置为 null。

  4. 如果policy为 null,则根据embedderPolicyValue切换:

    "unsafe-none"

    什么都不做。

    "credentialless"

    在以下情况下,将policy设置为`same-origin`:

    "require-corp"

    policy设置为`same-origin`。

  5. 根据policy切换:

    null
    `cross-origin`

    返回allowed

    `same-origin`

    如果originresponseURL为同源,则返回allowed

    否则,返回blocked

    `same-site`

    如果以下所有条件都为真:

    则返回allowed

    否则,返回blocked

    `Cross-Origin-Resource-Policy: same-site` 不会考虑通过安全传输传递的响应与非安全请求源匹配,即使它们的 hosts 是相同站点。安全传输的响应只会匹配安全传输的发起者。

,给定一个响应response,一个环境设置对象settingsObject,一个字符串destination,以及一个布尔值reportOnly,请执行以下步骤:

  1. endpoint设置为settingsObject策略容器嵌入者策略仅报告的报告终端,如果reportOnly为 true,并且settingsObject策略容器嵌入者策略报告终端

  2. serializedURL设置为通过序列化响应 URL 以进行报告response执行的结果。

  3. disposition设置为"reporting",如果reportOnly为 true;否则为"enforce"。

  4. body设置为一个包含以下属性的新对象:

    "type" "corp"
    "blockedURL" serializedURL
    "destination" destination
    "disposition" disposition
  5. settingsObject全局对象生成并排队一个报告,给定"coep" 报告类型endpointbody[REPORTING]

3.7. `Sec-Purpose` 标头

`` HTTP 请求标头指定该请求除了为用户立即使用资源之外,还具有一个或多个其他目的。

`Sec-Purpose` 标头字段是一个结构化标头,其值必须是一个token

唯一定义的tokenprefetch。它表明请求的目的是获取预期不久将需要的资源。

服务器可以使用此标头调整预取的缓存到期时间,禁止预取,或在统计页面访问量时区别对待。

4. 获取

下面的算法定义了获取。大致上,它接受一个请求和一个或多个在操作期间不同时间点运行的算法。下面列出的最后两个算法会将响应传递给它们。前两个算法可用于捕获上传。

为了,给定一个请求 request,一个可选的算法,一个 可选的算法, 一个可选的算法,一个可选的 算法, 一个可选的算法,一个可选的算法, 和一个可选的布尔值(默认false),运行 以下步骤。如果给定,processRequestBodyChunkLength必须是一个接受表示传输字节数的整数的算法。如果给定,processRequestEndOfBody必须 是一个不接受参数的算法。如果给定,processEarlyHintsResponse必须是一个接受响应的算法。 如果给定,processResponse必须是一个接受响应的算法。如果 给定,processResponseEndOfBody必须是一个接受响应的算法。如果 给定,processResponseConsumeBody必须是一个接受响应和 null、失败或字节序列的算法。

用户代理可能会被要求正在进行的获取。 用户代理可以接受或忽略挂起请求。挂起的获取可以。如果正在进行的获取正在更新 请求的HTTP缓存中的响应,用户代理应 忽略挂起请求。

如果请求的缓存模式为“no-store”或响应中出现`Cache-Control: no-store`标头, 用户代理不会更新HTTP缓存中的条目。[HTTP-CACHING]

  1. 断言request模式是“navigate”或 processEarlyHintsResponse为null。

    仅对导航验证早期提示(响应状态为103的响应)。

  2. taskDestination为null。

  3. crossOriginIsolatedCapability为false。

  4. 如果request客户端非null,则:

    1. taskDestination设置为request客户端全局对象

    2. crossOriginIsolatedCapability设置为request客户端跨源隔离能力

  5. 如果useParallelQueue为true,则将taskDestination设置为启动新并行队列的结果。

  6. timingInfo为新的获取时序信息,其开始时间重定向后开始时间是给定 crossOriginIsolatedCapability粗化共享当前时间渲染阻塞设置为request渲染阻塞

  7. fetchParams为新的获取参数,其请求request时序信息timingInfo处理请求体块长度processRequestBodyChunkLength处理请求体结束processRequestEndOfBody处理早期提示响应processEarlyHintsResponse处理响应processResponse处理响应体消耗processResponseConsumeBody处理响应体结束processResponseEndOfBody任务目标taskDestination跨源隔离能力crossOriginIsolatedCapability

  8. 如果request主体字节序列,则将request主体设置为request主体作为主体

  9. 如果request窗口为“client”,则将 request窗口设置为request客户端, 如果request客户端全局对象Window对象; 否则为“no-window”。

  10. 如果request来源为“client”,则将 request来源设置为request客户端来源

  11. 如果以下所有条件为真:

    则:

    1. 断言request来源request客户端同源

    2. onPreloadedResponseAvailable为一个给定响应response时运行以下步骤的算法:将fetchParams预加载响应候选设置为 response

    3. foundPreloadedResource为调用消耗预加载资源的结果,给定request窗口requestURLrequest目标request模式request凭证模式request完整性元数据, 和onPreloadedResponseAvailable

    4. 如果foundPreloadedResource为true并且fetchParams预加载响应候选为null,则将fetchParams预加载响应候选设置为"pending"。

  12. 如果request策略容器为“client”,则:

    1. 如果request客户端非null,则将request策略容器设置为request客户端策略容器克隆[HTML]

    2. 否则,将request策略容器设置为新的策略容器

  13. 如果request头列表不包含Accept”,则:

    1. value为“*/*”。

    2. 如果request启动器为“prefetch”,则将value设置为文档“Accept”头的值

    3. 否则,用户代理应将value设置为第一个匹配的语句(如果有),根据request目标

      document
      frame
      iframe
      文档“Accept”头的值
      image
      image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5
      json
      application/json,*/*;q=0.5
      style
      text/css,*/*;q=0.1
    4. 附加(“Accept”,value) 到request头列表

  14. 如果request头列表不包含Accept-Language”,则用户代理应附加(“Accept-Language”,适当的头值)到request头列表

  15. 如果request内部优先级为null,则使用request优先级启动器目标渲染阻塞实现定义的方式将request内部优先级设置为实现定义的对象。

    实现定义的对象可以包含HTTP/2的流权重和 依赖性,在适用的传输层(包括HTTP/3)中用于优先级的HTTP的可扩展优先级方案中的优先级,以及用于优先级调度和处理HTTP/1获取的等效信息。[RFC9218]

  16. 如果request子资源请求,则:

    1. record为新的获取记录,其请求request控制器fetchParams控制器

    2. record附加到request客户端获取组获取记录列表中。

  17. 给定fetchParams,运行主获取

  18. 返回fetchParams控制器

4.1. 主获取

要执行,给定获取参数fetchParams和一个可选的布尔值recursive(默认为false),执行以下步骤:

  1. requestfetchParams请求

  2. response为null。

  3. 如果request仅本地URL标志已设置且request当前URL不是本地,则将response设置为网络错误

  4. 运行报告请求的内容安全策略违规

  5. 如果适用,将request升级为可能可信的URL

  6. 如果适用,将混合内容的request升级为可能可信的URL

  7. 如果应该由于不良端口阻止request应该将request阻止为混合内容,或应该被内容安全策略阻止的request返回已阻止,则将response设置为网络错误

  8. 如果request引用策略为空字符串,则将request引用策略设置为request策略容器引用策略

  9. 如果request引用不是“no-referrer”,则将request引用设置为调用确定request的引用的结果。[REFERRER]

    如在引用策略中所述,用户代理可以为最终用户提供覆盖request引用为“no-referrer”或暴露较少敏感信息的选项。

  10. 如果所有以下条件为真,则将request当前URL方案设置为“https”:

    由于所有DNS操作通常都是实现定义的,如何确定DNS解析是否包含HTTPS RR也是实现定义的。由于传统上DNS操作不会在尝试获取连接之前执行,用户代理可能需要提前执行DNS操作,查询本地DNS缓存,或在获取算法的后期等待并可能在发现需要更改request当前URL方案时撤销逻辑。

  11. 如果recursive为false,则request的以下步骤并行执行

  12. 如果response为null,则将response设置为运行以下第一个匹配语句对应步骤的结果:

    fetchParams预加载响应候选项不为null
    1. 等待fetchParams预加载响应候选项不为“pending”。

    2. 断言fetchParams预加载响应候选项响应

    3. 返回fetchParams预加载响应候选项

    request当前URL来源request同源,且request响应污染为“basic
    request当前URL方案为“data
    request模式为“navigate”或“websocket
    1. request响应污染设置为“basic”。

    2. 返回运行方案获取给定fetchParams的结果。

    HTML分配从URL创建的任何文档和工作者,其方案为“data”一个唯一的不透明来源。仅可以从URL创建服务工作者,其方案HTTP(S)方案

    request模式为“same-origin

    返回网络错误

    request模式为“no-cors
    1. 如果request重定向模式不为“follow”,则返回网络错误

    2. request响应污染设置为“opaque”。

    3. 返回运行方案获取给定fetchParams的结果。

    request当前URL方案不是HTTP(S)方案

    返回网络错误

    requestuse-CORS-preflight标志已设置
    requestunsafe-request标志已设置,且request方法不是CORS-safelisted方法CORS-unsafe请求标头名称request标头列表不为空
    1. request响应污染设置为“cors”。

    2. corsWithPreflightResponse设置为运行HTTP获取给定fetchParams和true的结果。

    3. 如果corsWithPreflightResponse网络错误,则使用request运行清除缓存条目

    4. 返回corsWithPreflightResponse

    否则
    1. request响应污染设置为“cors”。

    2. 返回运行HTTP获取给定fetchParams的结果。

  13. 如果recursive为true,则返回response

  14. 如果response不是网络错误response不是过滤响应,则:

    1. 如果request响应污染为“cors”,则:

      1. headerNames设置为从提取的结果标头列表值给定 `Access-Control-Expose-Headers`和response标头列表

      2. 如果request凭据模式不是“include”且headerNames包含`*`,则将responseCORS公开标头名称列表设置为response标头名称中所有唯一的值response标头列表

      3. 否则,如果headerNames不为null或失败,则将responseCORS公开标头名称列表设置为headerNames

        此时headerNames中的一个仍可以为`*`,但只会匹配一个标头,其名称为`*`。

    2. 根据request响应污染设置response为以下过滤响应,将response作为其内部响应

      basic
      基本过滤响应
      cors
      CORS过滤响应
      opaque
      不透明过滤响应
  15. internalResponseresponse,如果response网络错误;否则response内部响应

  16. 如果internalResponseURL列表为空,则将其设置为requestURL列表克隆

    例如,响应URL列表可以为空,例如当获取“about:”URL时。

  17. 如果request重定向污染的来源,则将internalResponse跨来源重定向标志设置为true。

  18. 如果request计时允许失败标志未设置,则将internalResponse计时允许通过标志设置。

  19. 如果response不是网络错误,且以下任何返回已阻止

    则将responseinternalResponse设置为网络错误

  20. 如果response类型为“opaque”,internalResponse状态为206,internalResponserange-requested标志已设置,且request标头列表不包含`Range`,则将responseinternalResponse设置为网络错误

    传统上,即使未请求范围,API也接受范围响应。这可以防止先前范围请求的部分响应被提供给未发出范围请求的API。

    进一步详情

    上述步骤防止以下攻击:

    使用媒体元素请求跨源HTML资源的范围。虽然这是无效媒体,但可以在服务工作者中保留响应的克隆。这可以稍后用作脚本元素获取的响应。如果部分响应是有效的JavaScript(即使整个资源不是),执行它将泄露私人数据。

  21. 如果response不是网络错误,且request方法为`HEAD`或`CONNECT`,或internalResponse状态空体状态,则将internalResponse主体设置为null并忽略向其进行的任何入队(如果有)。

    这标准化了对违反HTTP的服务器的错误处理。

  22. 如果request完整性元数据不为空字符串,则:

    1. processBodyError为此步骤:运行获取响应交接给定fetchParams网络错误

    2. 如果response主体为null,则运行processBodyError并中止这些步骤。

    3. processBody给定bytes为这些步骤:

      1. 如果bytes匹配request完整性元数据,则运行processBodyError并中止这些步骤。[SRI]

      2. response主体设置为bytes作为主体

      3. 运行获取响应交接给定fetchParamsresponse

    4. 完全读取response主体给定processBodyprocessBodyError

  23. 否则,运行获取响应交接给定fetchParamsresponse


给定,给定获取参数fetchParams响应response,执行以下步骤:

  1. timingInfofetchParams计时信息

  2. 如果response不是网络错误,且fetchParams请求客户端是一个安全上下文,则将timingInfo服务器计时标头设置为获取、解码和拆分`Server-Timing`的结果 来自response内部响应标头列表

    使用_response_的内部响应是安全的,因为通过`Timing-Allow-Origin`标头保护暴露`Server-Timing`标头数据。

    用户代理也可以决定将`Server-Timing`标头暴露给非安全上下文的请求。

  3. processResponseEndOfBody为以下步骤:

    1. unsafeEndTime不安全共享当前时间

    2. 如果fetchParams请求目的地为“document”,则将fetchParams控制器完整计时信息设置为fetchParams计时信息

    3. fetchParams控制器报告计时步骤设置为以下步骤,给定全局对象global

      1. 如果fetchParams请求URL方案不是HTTP(S)方案,则返回。

      2. timingInfo结束时间设置为相对高分辨率时间,给定unsafeEndTimeglobal

      3. cacheStateresponse缓存状态

      4. bodyInforesponse主体信息

      5. 如果response计时允许通过标志未设置,则将timingInfo设置为创建一个不透明计时信息的结果,并将cacheState设置为空字符串。

        这包括response网络错误的情况。

      6. responseStatus设置为0。

      7. 如果fetchParams请求模式不是“navigate”或response跨来源重定向标志为false:

        1. responseStatus设置为response状态

        2. mimeTyperesponse的标头列表中提取的MIME类型的结果。

        3. 如果mimeType不是失败,则将bodyInfo内容类型设置为最小化的受支持MIME类型的结果,给定mimeType

      8. 如果fetchParams请求启动者类型不为null,则标记资源计时给定timingInfofetchParams请求URLfetchParams请求启动者类型globalcacheStatebodyInforesponseStatus

    4. processResponseEndOfBodyTask为以下步骤:

      1. fetchParams请求已完成标志设置为已完成。

      2. 如果fetchParams处理响应结束不为null,则给定response运行fetchParams处理响应结束

      3. 如果fetchParams请求启动者类型不为null且fetchParams请求客户端全局对象fetchParams任务目标,则给定fetchParams控制器报告计时步骤,运行fetchParams请求客户端全局对象

    5. 排队一个获取任务以运行processResponseEndOfBodyTask,以fetchParams任务目标

  4. 如果fetchParams处理响应不为null,则排队一个获取任务以运行fetchParams处理响应给定response,以fetchParams任务目标

  5. internalResponseresponse,如果response网络错误;否则response内部响应

  6. 如果internalResponse主体为null,则运行processResponseEndOfBody

  7. 否则:

    1. transformStream为一个新的TransformStream

    2. identityTransformAlgorithm为一个算法,该算法给定chunk入队chunktransformStream

    3. 设置transformStream,将transformAlgorithm设置为identityTransformAlgorithm,并将flushAlgorithm设置为processResponseEndOfBody

    4. internalResponse主体设置为internalResponse主体管道传输transformStream的结果。

    TransformStream是为了在流到达终点时接收通知的目的,并且是一个身份转换流

  8. 如果fetchParams处理响应消耗主体不为null,则:

    1. processBody给定nullOrBytes为此步骤:运行fetchParams处理响应消耗主体给定responsenullOrBytes

    2. processBodyError为此步骤:运行fetchParams处理响应消耗主体给定response和失败。

    3. 如果internalResponse主体为null,则排队一个获取任务以运行processBody给定null,以fetchParams任务目标

    4. 否则,完全读取internalResponse主体给定processBodyprocessBodyErrorfetchParams任务目标

4.2. scheme fetch

要执行,给定fetch 参数 fetchParams

  1. 如果fetchParams取消,则为fetchParams返回适当的网络错误

  2. request成为fetchParams请求

  3. 根据request当前URLscheme切换并运行相关步骤:

    "about"

    如果request当前URL路径 是字符串 "blank",则返回一个新的响应,其状态消息为`OK`,头列表为« (`Content-Type`, `text/html;charset=utf-8`) »,并且body是空字节序列作为body

    类似 "about:config" 的URL导航过程中处理,并在fetch的上下文中导致网络错误

    "blob"
    1. blobURLEntry成为request当前URLblob URL条目

    2. 如果request方法不是`GET`, blobURLEntry为null,或者blobURLEntry对象不是一个Blob对象,则返回一个网络错误[FILEAPI]

      `GET` 方法限制除了具有互操作性外没有其他有用的目的。

    3. blob成为blobURLEntry对象

    4. response成为一个新的响应

    5. fullLength成为blob大小

    6. serializedFullLength成为fullLength序列化同构编码

    7. type成为blob类型

    8. 如果request头列表包含 `Range`:

      1. bodyWithType成为安全提取blob的结果。

      2. response状态消息设置为`OK`。

      3. responsebody设置为bodyWithTypebody

      4. response头列表设置为« (`Content-Length`, serializedFullLength), (`Content-Type`, type) »。

    9. 否则:

      1. 设置responserange-requested 标志

      2. rangeHeader成为从request头列表获取`Range`的结果。

      3. rangeValue成为解析单个范围头值时给定rangeHeader和true的结果。

      4. 如果rangeValue失败,则返回一个网络错误

      5. 让(rangeStart, rangeEnd)为rangeValue

      6. 如果rangeStart为null:

        1. rangeStart设置为fullLengthrangeEnd

        2. rangeEnd设置为rangeStart + rangeEnd − 1。

      7. 否则:

        1. 如果rangeStart大于或等于fullLength,则返回一个网络错误

        2. 如果rangeEnd为null或rangeEnd大于或等于fullLength,则将rangeEnd设置为fullLength − 1。

      8. slicedBlob成为调用切片blob并给定blobrangeStartrangeEnd + 1和type的结果。

        一个范围头表示一个包含的字节范围,而切片blob算法输入范围则不然。要使用切片blob算法,我们必须增加rangeEnd

      9. slicedBodyWithType成为安全提取slicedBlob的结果。

      10. responsebody设置为slicedBodyWithTypebody

      11. serializedSlicedLength成为slicedBlob大小序列化同构编码

      12. contentRange成为调用构建内容范围并给定rangeStartrangeEndfullLength的结果。

      13. response状态设置为206。

      14. response状态消息设置为`Partial Content`。

      15. response头列表设置为« (`Content-Length`, serializedSlicedLength), (`Content-Type`, type),(`Content-Range`, contentRange) »。

    10. 返回response

    "data"
    1. dataURLStruct成为在request当前URL上运行data:URL处理器的结果。

    2. 如果dataURLStruct失败,则返回一个网络错误

    3. mimeType成为dataURLStructMIME类型序列化

    4. 返回一个新的响应,其状态消息为 `OK`,头列表为« (`Content-Type`, mimeType) »,并且bodydataURLStructbody 作为body

    "file"

    目前,虽然不幸的是,file: URL被留作读者的练习。

    如果有疑问,返回一个网络错误

    HTTP(S) scheme

    返回运行HTTP fetch并给定fetchParams的结果。

  4. 返回一个网络错误

4.3. HTTP fetch

要执行,给定fetch 参数 fetchParams和一个可选的布尔值makeCORSPreflight(默认值为false),执行以下步骤:

  1. request成为fetchParamsrequest

  2. responseinternalResponse为null。

  3. 如果requestservice-workers 模式为"all",那么:

    1. requestForServiceWorker成为request克隆

    2. 如果requestForServiceWorkerbody为非空, 那么:

      1. transformStream成为一个新的TransformStream

      2. transformAlgorithm给定chunk时,执行以下步骤:

        1. 如果fetchParams取消,则中止这些步骤。

        2. 如果chunk不是一个Uint8Array对象,则终止fetchParamscontroller

        3. 否则,在transformStream入队chunk。用户代理可以将chunk分割成实现定义的实用大小,并且入队它们。用户代理也可以将chunk合并为一个实现定义的实用大小,并且入队它。

      3. 设置transformStream,其中transformAlgorithm设置为transformAlgorithm

      4. requestForServiceWorkerbodystream设置为requestForServiceWorkerbodystream 通过transformStream传递的结果。

    3. serviceWorkerStartTime成为给定fetchParams粗化的共享当前时间

    4. response设置为调用handle fetch并给定requestForServiceWorkerfetchParamscontrollerfetchParams跨源隔离能力的结果。[HTML] [SW]

    5. 如果response非空,那么:

      1. fetchParams时间信息最终的service worker开始时间设置为serviceWorkerStartTime

      2. 如果requestbody为非空,则取消requestbody,原因未定义。
      3. 如果response不是过滤后的响应,则将internalResponse设置为response;否则将internalResponse设置为response内部响应

      4. 如果以下条件之一为真:

        则返回一个网络错误

  4. 如果response为null,那么:

    1. 如果makeCORSPreflight为true并且以下条件之一为真:

      那么:

      1. preflightResponse成为运行CORS-preflight fetch并给定request的结果。

      2. 如果preflightResponse是一个网络错误,则返回preflightResponse

      此步骤检查CORS-preflight缓存,如果没有合适的条目,它会执行一个CORS-preflight fetch,如果成功,它将填充缓存。执行CORS-preflight fetch的目的是确保获取的资源熟悉CORS协议。缓存的目的是减少CORS-preflight fetch的数量。

    2. 如果request重定向模式为"follow",则将requestservice-workers 模式设置为"none"。

      来自网络的重定向(与来自服务工作者的不同)不应暴露给服务工作者。

    3. responseinternalResponse设置为运行HTTP-network-or-cache fetch并给定fetchParams的结果。

    4. 如果request响应污染为"cors",并且CORS检查对于requestresponse返回失败,那么返回一个网络错误

      由于CORS检查不适用于其状态为304或407的响应,也不适用于来自服务工作者的响应,因此在此应用。

    5. 如果TAO检查对于requestresponse返回失败,那么设置request时间允许失败标志

  5. 如果request响应污染response类型为"opaque",并且对于requestrequest客户端request目的地internalResponse跨源资源策略检查返回阻止,那么返回一个网络错误

    跨源资源策略检查适用于来自网络和服务工作者的响应。这与CORS检查不同,因为request客户端和服务工作者可能有不同的嵌入者策略。

  6. 如果internalResponse状态重定向状态

    1. 如果internalResponse状态不是303,requestbody为非空,并且连接使用的是HTTP/2,则鼓励用户代理传输RST_STREAM帧。

      303被排除在外,因为某些社区赋予其特殊地位。

    2. 切换request重定向模式

      "error"
      1. response设置为一个网络错误

      "manual"
      1. 如果request模式为"navigate",则将fetchParamscontroller下一步手动重定向步骤设置为运行HTTP-redirect fetch并给定fetchParamsresponse

      2. 否则,将response设置为一个opaque-redirect过滤后的响应,其内部响应internalResponse

      "follow"
      1. response设置为运行HTTP-redirect fetch并给定fetchParamsresponse的结果。

  7. 返回response通常,internalResponsebodystream在返回后仍在入队。

4.4. HTTP-redirect fetch

要执行,给定fetch 参数 fetchParams响应 response,请运行以下步骤:

  1. request设为fetchParams请求

  2. 如果response不是过滤的响应,则将internalResponse设为response;否则设为response内部响应

  3. locationURL设为给定request当前 URL片段internalResponse位置 URL

  4. 如果locationURL为 null,则返回response

  5. 如果locationURL为失败,则返回一个网络错误

  6. 如果locationURLscheme不是HTTP(S) scheme,则返回一个网络错误

  7. 如果request重定向计数为20,则返回一个网络错误

  8. request重定向计数增加1。

  9. 如果request模式为"cors",locationURL 包含凭证,且requestlocationURL不同源,则返回一个网络错误

  10. 如果request响应污染为"cors"且locationURL 包含凭证,则返回一个网络错误

    此步骤捕捉跨源资源重定向到同源URL的情况。

  11. 如果internalResponse状态不是303,requestbody为非空,且requestbodysource为 null,则返回一个网络错误

  12. 如果以下任一条件为真:

    • internalResponse状态为301或302,且request方法为`POST`

    • internalResponse状态为303,且request方法不是`GET`或`HEAD`

    则:

    1. request方法设为`GET`,并将requestbody设为 null。

    2. 对于headerName,即属于request-body-header 名称的每个值,删除headerNamerequestheader 列表

  13. 如果request当前 URLlocationURL不同源,则对于属于CORS 非通配符请求头名称的每个headerName删除requestheader 列表

    即,当初始请求之后遇到不同的源时,`Authorization` 头会被删除。

  14. 如果requestbody为非空,则将requestbody设为运行安全提取requestbodysourcebody的结果。

    requestbodysource是否为 null 已经检查过。

  15. timingInfo设为fetchParamstiming 信息

  16. timingInfo重定向结束时间重定向后开始时间设为给定fetchParams粗化共享当前时间

  17. 如果timingInfo重定向开始时间为0,则将timingInfo重定向开始时间设为timingInfo开始时间

  18. 追加locationURLrequestURL 列表

  19. 调用在重定向时设置request的referrer策略requestinternalResponse[REFERRER]

  20. recursive设为true。

  21. 如果request重定向模式为"manual",则:

    1. 断言:request模式为"navigate"。

    2. recursive设为false。

  22. 返回运行main fetch给定fetchParamsrecursive的结果。

    这必须调用main fetch以正确设置request响应污染

4.5. HTTP-网络或缓存获取

要执行,给定fetch 参数 fetchParams,一个可选的布尔值isAuthenticationFetch(默认为 false),以及一个可选的布尔值isNewConnectionFetch(默认为 false),执行以下步骤:

某些实现可能支持部分内容的缓存,如 HTTP 缓存 中所述。然而,这在浏览器缓存中并不广泛支持。[HTTP-CACHING]

  1. request设为fetchParams请求

  2. httpFetchParams设为 null。

  3. httpRequest设为 null。

  4. response设为 null。

  5. storedResponse设为 null。

  6. httpCache设为 null。

  7. 取消设置revalidatingFlag

  8. 运行以下步骤,但在中止时如果fetchParams已取消

    1. 如果requestwindow为"no-window"且request重定向模式为"error",则将httpFetchParams设为fetchParams,并将httpRequest设为request

    2. 否则:

      1. httpRequest设为request克隆

        建议实现避免在requestbody为 null 时对其进行分流,因为在这种情况下只需要一个 body。例如,当requestbody为 null 时,重定向和身份验证将导致获取失败。

      2. httpFetchParams设为fetchParams的副本。

      3. httpFetchParams请求设为httpRequest

    3. includeCredentials设为 true,如果以下任一条件为 true:

      否则为 false。

    4. 如果Cross-Origin-Embedder-Policy 允许凭证返回 false,则将includeCredentials设为 false。

    5. contentLength设为httpRequestbody长度,如果httpRequestbody非空;否则设为 null。

    6. contentLengthHeaderValue设为 null。

    7. 如果httpRequestbody为 null,且httpRequest方法是`POST`或`PUT`,则将contentLengthHeaderValue设为`0`。

    8. 如果contentLength非空,则将contentLengthHeaderValue设为contentLength序列化等形编码

    9. 如果contentLengthHeaderValue非空,则附加(`Content-Length`,contentLengthHeaderValue)到httpRequestheader 列表

    10. 如果contentLength非空,且httpRequestkeepalive为 true,则:

      1. inflightKeepaliveBytes设为 0。

      2. group设为httpRequestclientfetch 组

      3. inflightRecords设为groupfetch 记录的集合,这些记录的请求keepalive为 true,且done 标志未设置。

      4. 遍历inflightRecords中的每个fetchRecord

        1. inflightRequest设为fetchRecord请求

        2. inflightKeepaliveBytes增加inflightRequestbody长度

      5. 如果contentLengthinflightKeepaliveBytes的总和超过 64 KiB,则返回网络错误

      上述限制确保了允许在httpRequest包含 body 的情况下,request 的大小是有界的,不允许无限期保持活动。

    11. 如果httpRequestreferrer是一个URL,则:

      1. referrerValue设为httpRequestreferrer序列化等形编码

      2. 附加(`Referer`,referrerValue)到httpRequestheader 列表

    12. 附加一个请求`Origin`headerhttpRequest

    13. 附加 Fetch metadata headershttpRequest[FETCH-METADATA]

    14. 如果httpRequestinitiator为"prefetch",则设置结构化字段值,给定(`Sec-Purpose`,tokenprefetch`)到httpRequestheader 列表

    15. 如果httpRequestheader 列表不包含`User-Agent`,则用户代理应附加(`User-Agent`,默认`User-Agent`值)到httpRequestheader 列表

    16. 如果httpRequest缓存模式为"default"且httpRequestheader 列表包含`If-Modified-Since`, `If-None-Match`, `If-Unmodified-Since`, `If-Match`,或 `If-Range`,则将httpRequest缓存模式设为"no-store"。

    17. 如果httpRequest缓存模式为"no-cache",httpRequest防止 no-cache cache-control header 修改标志未设置,且httpRequestheader 列表不包含`Cache-Control`,则附加(`Cache-Control`,`max-age=0`)到httpRequestheader 列表

    18. 如果httpRequest缓存模式为"no-store"或"reload",则:

      1. 如果httpRequestheader 列表不包含`Pragma`,则附加(`Pragma`,`no-cache`)到httpRequestheader 列表

      2. 如果httpRequestheader 列表不包含`Cache-Control`,则附加(`Cache-Control`,`no-cache`)到httpRequestheader 列表

    19. 如果httpRequestheader 列表包含`Range`,则附加(`Accept-Encoding`,`identity`)到httpRequestheader 列表

      这可以避免在使用部分编码的处理内容编码时发生故障。

      此外,许多服务器错误地忽略了`Range`header,如果接受非身份编码。

    20. 根据 HTTP 修改httpRequestheader 列表。如果httpRequestheader 列表包含header名称,则不要附加

      最好能让这一点更具规范性。在这个阶段,headers如 `Accept-Encoding`, `Connection`, `DNT`,和 `Host`, 应该在必要时附加

      `Accept`, `Accept-Charset`,和 `Accept-Language`不应在此时包含。

      `Accept`和`Accept-Language`已经包含 (除非使用fetch(),默认情况下不包含后者),`Accept-Charset`则是浪费字节。详见HTTP header 层次划分的更多细节。

    21. 如果includeCredentials为 true,则:

      1. 如果用户代理未配置为阻止httpRequest的 cookies(参见第7节[COOKIES]),则:

        1. cookies设为使用用户代理的 cookie 存储和httpRequest当前 URL运行"cookie-string"算法的结果(参见第5.4节[COOKIES])。

        2. 如果cookies不为空字符串,则附加(`Cookie`,cookies)到httpRequestheader 列表
      2. 如果httpRequestheader 列表不包含`Authorization`,则:

        1. authorizationValue设为 null。

        2. 如果存在httpRequest身份验证条目,并且httpRequestuse-URL-credentials 标志未设置或httpRequest当前 URL包含凭证,则将authorizationValue设为身份验证条目

        3. 否则,如果httpRequest当前 URL确实包含凭证isAuthenticationFetch为 true,则将authorizationValue设为httpRequest当前 URL转换为`Authorization`值

        4. 如果authorizationValue非空,则附加(`Authorization`,authorizationValue)到httpRequestheader 列表

    22. 如果存在代理身份验证条目,则根据需要使用它。

      这故意不依赖于httpRequest凭证模式

    23. httpCache设为确定 HTTP 缓存分区的结果,给定httpRequest

    24. 如果httpCache为 null,则将httpRequest缓存模式设为"no-store"。

    25. 如果httpRequest缓存模式既不是"no-store"也不是"reload",则:

      1. storedResponse设为从httpCache中选择响应的结果,可能需要验证,如HTTP 缓存的"从缓存构建响应"一章中所述,如果有的话。[HTTP-CACHING]

        根据 HTTP 的要求,这仍然会考虑`Vary`header

      2. 如果storedResponse非空,则:

        1. 如果缓存模式为"default",storedResponsestale-while-revalidate 响应,且httpRequestclient非空,则:

          1. response设为storedResponse

          2. response缓存状态设为"local"。

          3. revalidateRequest设为request克隆

          4. revalidateRequest缓存模式设为"no-cache"。

          5. 设置revalidateRequest防止 no-cache cache-control header 修改标志

          6. revalidateRequestservice-workers 模式设为"none"。

          7. 并行运行,给定新的fetch 参数,其中revalidateRequestrequest

            此获取仅用于更新httpCache的状态,响应将在下一次缓存访问前未使用。陈旧的响应将用作当前请求的响应。此获取是在 client 的上下文中发出的,因此如果它消失,请求将被终止。

        2. 否则:

          1. 如果storedResponse陈旧响应,则设置revalidatingFlag

          2. 如果revalidatingFlag已设置,且httpRequest缓存模式既不是"force-cache"也不是"only-if-cached",则:

            1. 如果storedResponseheader 列表包含`ETag`,则附加(`If-None-Match`,`ETag`的)到httpRequestheader 列表

            2. 如果storedResponseheader 列表包含`Last-Modified`,则附加(`If-Modified-Since`,`Last-Modified`的)到httpRequestheader 列表

            另见HTTP 缓存的"发送验证请求"一章。[HTTP-CACHING]

          3. 否则,将response设为storedResponse,并将response缓存状态设为"local"。

  9. 如果中止,则返回fetchParams适当网络错误

  10. 如果response为 null,则:

    1. 如果httpRequest缓存模式为"only-if-cached",则返回网络错误

    2. forwardResponse设为运行HTTP-网络获取的结果,给定httpFetchParamsincludeCredentials,以及isNewConnectionFetch

    3. 如果httpRequest方法不安全的forwardResponse状态在 200 到 399 范围内,则使httpCache中的适当存储的响应失效,如HTTP 缓存的"使存储的响应失效"一章中所述,并将storedResponse设为 null。[HTTP-CACHING]

    4. 如果revalidatingFlag已设置,且forwardResponse状态为 304,则:

      1. 使用forwardResponseheader 列表更新storedResponseheader 列表,如HTTP 缓存的"验证时刷新存储的响应"一章中所述。[HTTP-CACHING]

        这还会更新缓存中的存储响应。

      2. response设为storedResponse

      3. response缓存状态设为"validated"。

    5. 如果response为 null,则:

      1. response设为forwardResponse

      2. httpRequestforwardResponse存储在httpCache中,如HTTP 缓存的"存储响应到缓存"一章中所述。[HTTP-CACHING]

        如果forwardResponse网络错误,这实际上缓存了网络错误,有时称为"负缓存"。

        相关的body 信息与响应一起存储在缓存中。

  11. responseURL 列表设为httpRequestURL 列表克隆

  12. 如果httpRequestheader 列表包含`Range`,则设置responserange-requested 标志

  13. response请求包含凭证设为includeCredentials

  14. 如果response状态为 401,httpRequest响应污染不为"cors",includeCredentials为 true,且requestwindow环境设置对象,则:

    1. 需要测试:多个`WWW-Authenticate` headers,缺失,解析问题。

    2. 如果requestbody非空,则:

      1. 如果requestbody为空,则返回网络错误

      2. requestbody设为body的结果,来自安全提取requestbody

    3. 如果requestuse-URL-credentials 标志未设置或isAuthenticationFetch为 true,则:

      1. 如果fetchParams已取消,则返回fetchParams适当网络错误

      2. usernamepassword设为在requestwindow中提示最终用户输入的用户名和密码,分别。

      3. 设置用户名,给定request当前 URLusername

      4. 设置密码,给定request当前 URLpassword

    4. response设为运行HTTP-网络或缓存获取的结果,给定fetchParams并为 true。

  15. 如果response状态为 407,则:

    1. 如果requestwindow为"no-window",则返回网络错误

    2. 需要测试:多个`Proxy-Authenticate` headers,缺失,解析问题。

    3. 如果fetchParams已取消,则返回fetchParams适当网络错误

    4. requestwindow中适当提示最终用户,并将结果存储为代理身份验证条目[HTTP]

      代理身份验证的剩余细节由 HTTP 定义。

    5. response设为运行HTTP-网络或缓存获取的结果,给定fetchParams

  16. 如果所有以下条件为 true:

    • response状态为 421

    • isNewConnectionFetch为 false

    • requestbody为空,或requestbody非空且requestbody非空

    则:

    1. 如果fetchParams已取消,则返回fetchParams适当网络错误

    2. response设为运行HTTP-网络或缓存获取的结果,给定fetchParamsisAuthenticationFetch,并为 true。

  17. 如果isAuthenticationFetch为 true,则为request创建一个身份验证条目和给定的域。

  18. 返回response通常,在返回后,responsebodystream仍在排队中。

4.6. HTTP-网络获取

要执行,给定fetchParams,一个可选的布尔值includeCredentials(默认为 false),以及一个可选的布尔值forceNewConnection(默认为 false),按以下步骤进行:

  1. request设为fetchParams请求

  2. response设为 null。

  3. timingInfo设为fetchParams时序信息

  4. networkPartitionKey设为给定request确定网络分区键的结果。

  5. newConnection设为"yes",如果forceNewConnection为 true;否则为"no"。

  6. 根据request模式进行切换:

    "websocket"

    connection设为获取 WebSocket 连接的结果,给定request当前 URL

    否则

    connection设为获取连接的结果,给定networkPartitionKeyrequest当前 URLincludeCredentialsnewConnection

  7. 运行以下步骤,但在fetchParams中止时中止,fetchParams取消

    1. 如果connection失败,则返回网络错误

    2. timingInfo最终连接时序信息设为钳制并粗化连接时序信息的结果,给定connection时序信息timingInfo重定向后启动时间fetchParams跨域隔离能力

    3. 如果connection是 HTTP/1.x 连接,request主体不为 null,且request主体为 null,则返回网络错误

    4. timingInfo最终网络请求启动时间设为给定fetchParams粗化的共享当前时间
    5. response设为通过connection使用request进行 HTTP 请求的结果,并注意以下事项:

      Fetch 和 HTTP 之间的确切分层仍需理清,因此response在这里既代表响应,又代表一个 HTTP 响应。

      如果 HTTP 请求导致 TLS 客户端证书对话框,则:

      1. 如果request窗口是一个环境设置对象,则在request窗口中显示该对话框。

      2. 否则,返回网络错误

      要传输request主体body,执行以下步骤:

      1. 如果body为 null 且fetchParams处理请求主体结束不为 null,则排队一个 fetch 任务,给定fetchParams处理请求主体结束fetchParams任务目标

      2. 否则,如果body为非空:

        1. 给定bytes,将processBodyChunk设为以下步骤:

          1. 如果fetchParams取消,则中止这些步骤。

          2. 并行中运行此步骤:传输bytes

          3. 如果fetchParams处理请求主体块长度不为 null,则运行fetchParams处理请求主体块长度,给定bytes长度

        2. processEndOfBody设为以下步骤:

          1. 如果fetchParams取消,则中止这些步骤。

          2. 如果fetchParams处理请求主体结束不为 null,则运行fetchParams处理请求主体结束

        3. 给定e,将processBodyError设为以下步骤:

          1. 如果fetchParams取消,则中止这些步骤。

          2. 如果e是"AbortError"DOMException,则中止fetchParams控制器

          3. 否则,终止fetchParams控制器

        4. 增量读取request主体,给定processBodyChunkprocessEndOfBodyprocessBodyErrorfetchParams任务目标

  8. 如果中止,则:

    1. 如果connection使用 HTTP/2,则发送RST_STREAM帧。

    2. 返回fetchParams适当的网络错误

  9. buffer设为空的字节序列

    这表示用户代理内部网络层的缓冲区。

  10. pullAlgorithm设为以下步骤:

    1. promise设为一个新的 promise

    2. 并行中运行以下步骤:

      1. 如果buffer的大小小于用户代理选择的下限且正在进行的获取操作被暂停,则恢复获取操作。

      2. 等待直到buffer不为空。

      3. 排队一个 fetch 任务,在fetchParams任务目标上运行以下步骤。

        1. 从字节中提取bufferstream中。

        2. 如果stream处于错误状态,则终止fetchParams控制器

        3. 解决promise,返回 undefined。

    3. 返回promise

  11. cancelAlgorithm设为一个算法,该算法中止fetchParams控制器,给定reason

  12. stream设为一个新的ReadableStream

  13. 设置stream的字节读取支持,pullAlgorithm设为pullAlgorithmcancelAlgorithm设为cancelAlgorithm

  14. response主体设为一个新的主体,其stream

  15. (这是一个跟踪向量)如果includeCredentials为 true,且用户代理未配置为阻止request的 cookie(见[COOKIES]第 7 节),则在每个header名称与 `Set-Cookie` 匹配时,使用"set-cookie-string" 解析算法(见[COOKIES]第 5.2 节)解析responseheader 列表中的值(如果有的话),并将其应用于request当前 URL

  16. 并行中运行以下步骤:

    1. 运行以下步骤,但在fetchParams中止时中止,fetchParams取消

      1. 在以下情况下:

        1. 如果已经从response的消息主体中传输了一个或多个字节,则:

          1. bytes设为已传输的字节。

          2. codings设为提取 header 列表值的结果,给定 `Content-Encoding` 和responseheader 列表

          3. 增加response主体信息编码大小,增加的大小为bytes长度

          4. bytes设为处理内容编码的结果,给定codingsbytes

            这使得 `Content-Length`header不再可靠。

          5. 增加response主体信息解码大小,增加的大小为bytes长度

          6. 如果bytes失败,则终止fetchParams控制器

          7. bytes附加到buffer中。

          8. 如果buffer的大小超过用户代理选择的上限,则要求用户代理暂停正在进行的获取操作。

        2. 否则,如果response的消息主体的字节传输已正常完成且stream处于可读状态,则关闭stream,并中止这些并行步骤。

    2. 如果中止,则:

      1. 如果fetchParams中止,则:

        1. 设置response中止标志

        2. 如果stream处于可读状态,则使用反序列化的中止原因使stream出现错误,给定fetchParams控制器序列化中止原因和一个实现定义的realm

      2. 否则,如果stream处于可读状态,则使用TypeError使stream出现错误。

      3. 如果connection使用 HTTP/2,则发送RST_STREAM帧。

      4. 否则,用户代理应关闭connection,除非这样做对性能有害。

        例如,如果用户代理知道在可重用连接上仅剩余少量字节的传输,则关闭连接并在下一次获取操作中重新进行握手可能会更糟。

    这些步骤在并行中运行,因为此时尚不清楚response主体是否相关(response可能是重定向)。

  17. 返回response通常,response主体在返回后仍在排队。

4.7. CORS 预检获取

这实际上是用户代理实现的检查,以查看是否理解CORS 协议。所谓的CORS 预检请求。如果成功,它将填充CORS 预检缓存,以尽量减少这些获取的次数。

要执行,给定请求 request,请执行以下步骤:

  1. preflight为一个新的请求, 其方法为`OPTIONS`,URL 列表requestURL 列表克隆发起者request发起者目标request目标request引用request引用引用策略request引用策略模式为`cors`,并且响应污染为`cors`。

    preflightservice-workers 模式无关紧要, 因为此算法使用HTTP 网络或缓存获取而非HTTP 获取

  2. 附加 (`Accept`, `*/*`) 到 preflight头列表

  3. 附加 (`Access-Control-Request-Method`, request方法) 到preflight头列表

  4. headers为带有request头列表CORS 非安全请求头名称

  5. 如果headers不为空,则:

    1. valueheaders中各项之间用`,`分隔的值。

    2. 附加 (`Access-Control-Request-Headers`, value) 到preflight头列表

    这故意不使用合并,因为0x2C后的0x20并不是这样实现的,不管是好是坏。

  6. response为运行HTTP 网络或缓存获取的结果,给定新的获取参数,其请求preflight

  7. 如果针对requestresponseCORS 检查返回成功,且response状态OK 状态,则:

    CORS 检查是在request而非preflight上进行的,以确保使用正确的凭证模式

    1. methods提取头列表值的结果,给定 `Access-Control-Allow-Methods` 和response头列表

    2. headerNames提取头列表值的结果,给定 `Access-Control-Allow-Headers` 和response头列表

    3. 如果methodsheaderNames为失败,返回网络错误

    4. 如果methods为null且request使用 CORS 预检标志被设置,则将 methods设置为包含request方法的新列表。

      这确保了由于设置了request使用 CORS 预检标志而发生的CORS 预检获取缓存

    5. 如果request方法不在methods中, request方法不是CORS 安全列表方法,并且request凭证模式为 `include`或methods不包含`*`,则返回网络错误

    6. 如果request头列表中的一个名称CORS 非通配符请求头名称 并且与headerNames中的没有字节不区分大小写的匹配,则 返回网络错误

    7. 对于request头列表中的CORS 非安全请求头名称的每个unsafeName,如果unsafeNameheaderNames中的没有字节不区分大小写的匹配,并且request凭证模式为`include`或headerNames不包含`*`,则返回网络错误

    8. max-age提取头列表值的结果,给定 `Access-Control-Max-Age`和 response头列表

    9. 如果max-age为失败或null,则将max-age设置为5。

    10. 如果max-age大于对max-age施加的限制,则将max-age设置为施加的限制。

    11. 如果用户代理不提供缓存, 则返回response

    12. 对于每个使用requestmethods中的方法缓存条目匹配,将匹配条目的max-age设置为max-age

    13. 对于没有使用requestmethods中的方法缓存条目匹配,使用requestmax-agemethod和null创建新的缓存条目

    14. 对于每个使用requestheaderNames中的头名称缓存条目匹配,将匹配条目的max-age设置为max-age

    15. 对于没有使用requestheaderNames中的头名称缓存条目匹配,使用requestmax-age、null 和headerName创建新的缓存条目

    16. 返回response

  8. 否则,返回网络错误

4.8. CORS 预检缓存

用户代理有一个关联的CORS 预检缓存是一个列表,其中包含缓存条目

包括:

缓存条目必须在其最大存活时间字段中指定的秒数过去后从存储条目中删除。缓存条目可能会在此时刻到达之前被删除。

,给定requestmax-agemethodheaderName,运行以下步骤:

  1. entry为一个缓存条目,初始化如下:

    给定request确定网络分区键的结果

    字节序列化的来源

    给定request字节序列化请求来源的结果

    URL

    request当前 URL

    最大存活时间

    max-age

    凭证

    如果request凭证模式是`include`,则为 true,否则为 false

    方法

    method

    头名称

    headerName

  2. entry附加到用户代理的CORS 预检缓存中。

,给定request移除用户代理的CORS 预检缓存中的任何缓存条目,其是给定request确定的网络分区键的结果,字节序列化的来源是给定request字节序列化请求来源的结果,URLrequest当前 URL

存在一个,用于缓存条目 entry,如果entry是给定request确定网络分区键的结果,entry字节序列化来源是使用request字节序列化请求来源的结果,entryURLrequest当前URL,并且其中一个

为真。

当用户代理的CORS-preflight 缓存中存在一个缓存条目,且该条目与request存在缓存条目匹配,并且其方法method或`*`时,则methodrequest存在

当用户代理的CORS 预检缓存中存在一个缓存条目,并且其缓存条目匹配使用request时,存在,且满足以下条件之一:

为真。

4.9. CORS 检查

要对requestresponse执行,请执行以下步骤:

  1. origin为从response头列表获取`Access-Control-Allow-Origin`的结果。

  2. 如果origin为 null,则返回失败。

    Null 不是`null`。

  3. 如果request凭证模式不是`include`,且origin为`*`,则返回成功。

  4. 如果使用request字节序列化请求来源的结果不为origin,则返回失败。

  5. 如果request凭证模式不是`include`,则返回成功。

  6. credentials为从response头列表获取`Access-Control-Allow-Credentials`的结果。

  7. 如果credentials为`true`,则返回成功。

  8. 返回失败。

4.10. TAO 检查

要对requestresponse执行,请执行以下步骤:

  1. 如果request时间允许失败标志已设置,则返回失败。

  2. values为从response头列表获取、解码并拆分`Timing-Allow-Origin`的结果。

  3. 如果values包含`*`,则返回成功。

  4. 如果values包含使用request序列化请求来源的结果,则返回成功。

  5. 如果request模式为`navigate`,且request当前 URL来源request来源不同源,则返回失败。

    对于嵌套可导航项的导航,这是必要的。在这种情况下,request来源将是容器文档的来源,而TAO 检查将返回失败。由于导航计时从不验证TAO 检查的结果,嵌套文档仍然可以访问完整的计时信息,但容器文档无法访问。

  6. 如果request响应污染为`basic`,则返回成功。

  7. 返回失败。

5. Fetch API

这个fetch() 方法是用于fetching资源的相对底层的API。它涵盖的范围比XMLHttpRequest略广,但在请求进展方面(非响应进展)目前有所欠缺。

fetch()方法使得fetch资源并将其内容提取为Blob相当简单:

fetch("/music/pk/altes-kamuffel.flac")
  .then(res => res.blob()).then(playBlob)

如果你只关心记录一个特定的响应头:

fetch("/", {method:"HEAD"})
  .then(res => log(res.headers.get("strict-transport-security")))

如果你想检查一个特定的响应头,然后处理跨域资源的响应:

fetch("https://pk.example/berlin-calling.json", {mode:"cors"})
  .then(res => {
    if(res.headers.get("content-type") &&
       res.headers.get("content-type").toLowerCase().indexOf("application/json") >= 0) {
      return res.json()
    } else {
      throw new TypeError()
    }
  }).then(processJSON)

如果你想处理URL查询参数:

var url = new URL("https://geo.example.org/api"),
    params = {lat:35.696233, long:139.570431}
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]))
fetch(url).then(/* … */)

如果你想逐步接收主体数据:

function consume(reader) {
  var total = 0
  return pump()
  function pump() {
    return reader.read().then(({done, value}) => {
      if (done) {
        return
      }
      total += value.byteLength
      log(`received ${value.byteLength} bytes (${total} bytes in total)`)
      return pump()
    })
  }
}

fetch("/music/pk/altes-kamuffel.flac")
  .then(res => consume(res.body.getReader()))
  .then(() => log("consumed the entire body without keeping the whole thing in memory!"))
  .catch(e => log("something went wrong: " + e))

5.1. Headers 类

typedef (sequence<sequence<ByteString>> or record<ByteString, ByteString>) ;

[Exposed=(Window,Worker)]
interface  {
  constructor(optional HeadersInit );

  undefined append(ByteString , ByteString );
  undefined delete(ByteString );
  ByteString? get(ByteString );
  sequence<ByteString> getSetCookie();
  boolean has(ByteString );
  undefined set(ByteString , ByteString );
  iterable<ByteString, ByteString>;
};

一个Headers 对象有一个关联的(一个头列表),它最初是空的。这可以是指向其他东西的头列表的指针,例如,像Request 对象展示的那样,指向一个请求的头列表。

一个Headers 对象也有一个关联的,它是一个。一个头保护是“immutable”、“request”、“request-no-cors”、“response”或“none”。


headers = new Headers([init])

创建一个新的Headers 对象。init可以用来填充它的内部头列表,如下面的示例所示。

const meta = { "Content-Type": "text/xml", "Breaking-Bad": "<3" };
new Headers(meta);

// The above is equivalent to
const meta2 = [
  [ "Content-Type", "text/xml" ],
  [ "Breaking-Bad", "<3" ]
];
new Headers(meta2);
headers . append(name, value)

将一个头添加到headers中。

headers . delete(name)

headers中删除一个头。

headers . get(name)

以字符串形式返回所有名称为name的头的值,用逗号和空格分隔。

headers . getSetCookie()

返回所有名称为`Set-Cookie`的头的值的列表。

headers . has(name)

返回是否存在名称为name的头。

headers . set(name, value)

value替换第一个名称为name的头的值,并删除任何剩余的名称为name的头。

for(const [name, value] of headers)

headers可以被迭代。


一个 name, value)对于一个 Headers 对象headers

  1. 如果name不是一个头名称value不是一个头值,那么抛出一个TypeError异常。

  2. 如果headers保护是“immutable”,那么抛出一个TypeError异常。

  3. 如果headers保护是“request”,并且(name, value)是一个禁止的请求头,那么返回false。

  4. 如果headers保护是“response”,并且name是一个禁止的响应头名称,那么返回false。

  5. 返回true。

未共享“request-no-cors”的步骤,因为在CORS-安全列出的请求头中,无法获得始终成功的虚假值(对于delete())。

一个name, value)到一个Headers对象headers,请执行以下步骤:

  1. 规范化 value

  2. 如果为headers验证name, value)返回false,则返回。

  3. 如果headers保护是“request-no-cors”:

    1. temporaryValue成为从headers头列表获取name的结果。

    2. 如果temporaryValue为null,则将temporaryValue设置为value

    3. 否则,将temporaryValue设置为temporaryValue,后跟0x2C 0x20,再后跟value

    4. 如果(name, temporaryValue)不是一个no-CORS安全列出的请求头,则返回。

  4. 将(name, value追加headers头列表中。

  5. 如果headers保护是“request-no-cors”,则从headers移除受保护的no-CORS请求头

一个Headers对象headers,使用给定对象object,请执行以下步骤:

  1. 如果object是一个序列,那么对于object中的每个header

    1. 如果header大小不为2,则抛出一个TypeError异常。

    2. 将(header[0], header[1])追加headers中。

  2. 否则,object是一个记录,那么对于object中的每个keyvalue,将(key, value追加headers中。

从一个Headers对象headers,请执行以下步骤:

  1. 对于受保护的no-CORS请求头名称中的每个headerName

    1. headers头列表删除headerName

当头被非特权代码修改时,将调用此方法。

以下是构造函数的步骤:

  1. this保护设置为“none”。

  2. 如果init已给定,则使用init 填充this

方法的步骤是将(name, value追加this

方法的步骤是:

  1. 如果为this 验证name, ``)返回false,则返回。

    传递一个虚拟的头值不应产生任何负面影响。

  2. 如果this保护是“request-no-cors”,name不是一个no-CORS安全列出的请求头名称,并且name不是一个受保护的no-CORS请求头名称,则返回。

  3. 如果this头列表不包含name,则返回。

  4. this头列表删除name

  5. 如果this保护是“request-no-cors”,则从this移除受保护的no-CORS请求头

方法的步骤是:

  1. 如果name不是一个头名称,则抛出一个TypeError异常。

  2. 返回从this头列表获取name的结果。

方法的步骤是:

  1. 如果this头列表不包含`Set-Cookie`,则返回« »。

  2. 按顺序返回this头列表中所有与`Set-Cookie`字节大小写不敏感匹配的

方法的步骤是:

  1. 如果name不是一个头名称,则抛出一个TypeError异常。

  2. 如果this头列表包含name,则返回true;否则返回false。

方法的步骤是:

  1. 规范化value

  2. 如果为this验证name, value)返回false,则返回。

  3. 如果this保护是“request-no-cors”,并且(name, value)不是一个no-CORS安全列出的请求头,则返回。

  4. 将(name, value设置this头列表中。

  5. 如果this保护是“request-no-cors”,则从this移除受保护的no-CORS请求头

要迭代的值对是通过对排序和组合this头列表运行来返回的值。

5.2. BodyInit 联合类型

typedef (Blob  BufferSource  FormData  URLSearchParams  USVString) ;

typedef (ReadableStream  XMLHttpRequestBodyInit) ;

为了从一个带类型的body,从一个字节序列BodyInit对象object中,执行以下步骤:

  1. 如果object是一个ReadableStream对象,则:

    1. 断言:object既不是被打扰,也不是锁定的

  2. 返回提取object的结果。

安全提取操作是提取操作的一个子集,保证不会抛出异常。

为了从一个带类型的body,从一个字节序列BodyInit对象object中,使用一个可选的布尔值(默认值为false),执行以下步骤:

  1. stream为null。

  2. 如果object是一个ReadableStream对象,则将stream设置为object

  3. 否则,如果object是一个Blob对象,将stream设置为执行object获取流的结果。

  4. 否则,将stream设置为新的ReadableStream对象,并设置stream为字节读取支持。

  5. 断言stream是一个ReadableStream对象。

  6. action为null。

  7. source为null。

  8. length为null。

  9. type为null。

  10. 根据object进行切换:

    Blob

    source设置为object

    length设置为objectsize

    如果objecttype属性不是空字节序列,则将type设置为它的值。

    字节序列

    source设置为object

    BufferSource

    source设置为对象持有字节的副本

    FormData

    action设置为此步骤:运行multipart/form-data编码算法,使用object条目列表UTF-8

    source设置为object

    length设置为不明确,请参见html/6424以改进此内容

    type设置为`multipart/form-data; boundary=`,后跟multipart/form-data边界字符串,由multipart/form-data编码算法生成。

    URLSearchParams

    source设置为运行application/x-www-form-urlencoded序列化器的结果,与object列表

    type设置为`application/x-www-form-urlencoded;charset=UTF-8`。

    标量值字符串

    source设置为objectUTF-8编码

    type设置为`text/plain;charset=UTF-8`。

    ReadableStream

    如果keepalive为true,则抛出一个TypeError

    如果object被打扰的或锁定的,则抛出一个TypeError

  11. 如果source字节序列,则将action设置为返回sourcesource长度的步骤。

  12. 如果action不为null,则并行执行以下步骤:

    1. 运行action

      只要有一个或多个字节可用且stream没有错误,就将从可用字节创建的结果作为Uint8Array入队到stream中。

      当运行action完成时,关闭stream

  13. body设为一个body,其streamstreamsourcesourcelengthlength

  14. 返回(body, type)。

5.3. Body 混入

interface mixin  {
  readonly attribute ReadableStream? body;
  readonly attribute boolean bodyUsed;
  [NewObject] Promise<ArrayBuffer> arrayBuffer();
  [NewObject] Promise<Blob> blob();
  [NewObject] Promise<Uint8Array> bytes();
  [NewObject] Promise<FormData> formData();
  [NewObject] Promise<any> json();
  [NewObject] Promise<USVString> text();
};

像HTML这样不希望网络层依赖的格式可能不会在此公开。相反,HTML解析器API可能会在适当的时候接受一个流。

包括Body 接口混入的对象有一个关联的(null或body)。

包括Body 接口混入的对象在其body为非null且其bodystreamdisturbedlocked时,称为


requestOrResponse . body

ReadableStream形式返回requestOrResponse的body。

requestOrResponse . bodyUsed

返回requestOrResponse的body是否已被读取。

requestOrResponse . arrayBuffer()

返回一个promise,该promise在requestOrResponse的body作为ArrayBuffer时被实现。

requestOrResponse . blob()

返回一个promise,该promise在requestOrResponse的body作为Blob时被实现。

requestOrResponse . bytes()

返回一个promise,该promise在requestOrResponse的body作为Uint8Array时被实现。

requestOrResponse . formData()

返回一个promise,该promise在requestOrResponse的body作为FormData时被实现。

requestOrResponse . json()

返回一个promise,该promise在requestOrResponse的body被解析为JSON时被实现。

requestOrResponse . text()

返回一个promise,该promise在requestOrResponse的body作为字符串时被实现。


,给定一个RequestResponse 对象requestOrResponse

  1. headers设为null。

  2. 如果requestOrResponse是一个Request 对象,则将headers设为requestOrResponserequestheader list

  3. 否则,将headers设为requestOrResponseresponseheader list

  4. mimeType设为headers中提取MIME类型的结果。

  5. 如果mimeType失败,则返回null。

  6. 返回mimeType

获取器的步骤是:如果thisbody为null,则返回null;否则,返回thisbodystream

获取器的步骤是:如果thisbody为非null且thisbodystreamdisturbed,则返回true;否则返回false。

算法,在给定一个包括Bodyobject和一个接受字节序列并返回一个JavaScript值或抛出异常的算法convertBytesToJSValue时,执行以下步骤:

  1. 如果objectunusable,则返回一个以TypeError为拒绝理由的promise。

  2. promise成为一个新的promise

  3. errorSteps接受errorerror拒绝promise
  4. successSteps接受一个字节序列data,以data为参数运行convertBytesToJSValue,并以其结果解决promise。如果此过程抛出异常,则以该异常运行errorSteps
  5. 如果objectbody为null,则以一个空的字节序列运行successSteps

  6. 否则,完全读取objectbody,给定successStepserrorSteps,和object相关全局对象

  7. 返回promise

方法的步骤是:将this与以下步骤一起运行consume body,给定一个字节序列bytes,返回从bytes创建的ArrayBufferthis相关领域中。

上面的方法可能会以RangeError作为拒绝。

方法的步骤是:将this与以下步骤一起运行consume body,给定一个字节序列bytes,返回一个bytes作为内容的Blob,其type属性是使用this获取MIME类型的结果。

方法的步骤是返回运行consume body的结果,使用this并在给定字节序列bytes的情况下:返回创建Uint8Array的结果,这个thisrelevant realm

上述方法可能会因RangeError而被拒绝。

方法的步骤是:将this与以下步骤一起运行consume body,给定一个字节序列bytes

  1. mimeType设为使用this运行获取MIME类型的结果。

  2. 如果mimeType为非null,则切换mimeType精髓并运行相应的步骤:

    "multipart/form-data"
    1. 根据Returning Values from Forms: multipart/form-data中规定的规则,使用mimeType中的`boundary`参数的值来解析bytes[RFC7578]

      每个`Content-Disposition`头包含`filename`参数的部分,必须解析为一个条目,其值是一个File对象,该对象的内容是该部分的内容。name属性的值必须是该部分的`filename`参数的值。type属性的值必须是该部分的`Content-Type`头的值(如果该部分有此头),否则为`text/plain`([RFC7578]第4.4节定义的默认值)。

      每个`Content-Disposition`头不包含`filename`参数的部分,必须解析为一个条目,其值为该部分内容的UTF-8无BOM解码的内容。这与是否存在或具有`Content-Type`头以及`charset`参数的值无关。

      一个`Content-Disposition`头包含`name`参数,其值为`_charset_`的部分,解析方式与其他部分相同。它不会更改编码。

    2. 如果由于某种原因失败,则抛出TypeError

    3. 返回一个新的FormData对象,将解析操作产生的每个entry附加到其entry list

    上面是multipart/form-data的粗略近似,正在编写更详细的解析规范。欢迎志愿者。

    "application/x-www-form-urlencoded"
    1. entries设为解析bytes的结果。

    2. 如果entries失败,则抛出TypeError

    3. 返回一个新的FormData对象,其entry listentries

  3. 抛出TypeError

方法的步骤是:将this与以下步骤一起运行consume body从字节序列中解析JSON

上面的方法可能会以SyntaxError作为拒绝。

方法的步骤是:将this与以下步骤一起运行consume bodyUTF-8解码

5.4. Request类

typedef (Request or USVString) ;

[Exposed=(Window,Worker)]
interface  {
  constructor(RequestInfo , optional RequestInit  = {});

  readonly attribute ByteString method;
  readonly attribute USVString url;
  [SameObject] readonly attribute Headers headers;

  readonly attribute RequestDestination destination;
  readonly attribute USVString referrer;
  readonly attribute ReferrerPolicy referrerPolicy;
  readonly attribute RequestMode mode;
  readonly attribute RequestCredentials credentials;
  readonly attribute RequestCache cache;
  readonly attribute RequestRedirect redirect;
  readonly attribute DOMString integrity;
  readonly attribute boolean keepalive;
  readonly attribute boolean isReloadNavigation;
  readonly attribute boolean isHistoryNavigation;
  readonly attribute AbortSignal signal;
  readonly attribute RequestDuplex duplex;

  [NewObject] Request clone();
};
Request includes Body;

dictionary  {
  ByteString ;
  HeadersInit ;
  BodyInit? ;
  USVString ;
  ReferrerPolicy ;
  RequestMode ;
  RequestCredentials ;
  RequestCache ;
  RequestRedirect ;
  DOMString ;
  boolean ;
  AbortSignal? ;
  RequestDuplex ;
  RequestPriority ;
  any ; // can only be set to null
};

enum  { , , , , , , , , , , , , , , , , ,  , , ,  };
enum  { , , ,  };
enum  { , ,  };
enum  { , , , , ,  };
enum  { , ,  };
enum  {  };
enum  { , ,  };

"serviceworker" 从 RequestDestination 中省略了,因为它无法从 JavaScript 中观察到。实现仍然需要将其作为一个 destination 支持。"websocket" 从 RequestMode 中省略了,因为它既不能使用也不能从 JavaScript 中观察到。

一个 Request 对象有一个相关的 (一个 request)。

一个 Request 对象也有一个相关的 (null 或 一个 Headers 对象),初始值为 null。

一个 Request 对象有一个相关的 (null 或 一个 AbortSignal 对象),初始值为 null。

一个 Request 对象的 body 是它的 requestbody


request = new Request(input [, init])

返回一个新的 request,其 url 属性是 input 如果 input 是字符串,并且 inputurl 如果 input 是一个 Request 对象。

init 参数是一个对象,其属性可以按如下方式设置:

method
一个字符串,用于设置 requestmethod
headers
一个 Headers 对象、一个对象字面量或一个由两个项目数组组成的数组,用于设置 requestheaders
body
一个 BodyInit 对象或 null 用于设置 requestbody
referrer
一个字符串,其值为同源 URL、"about:client" 或空字符串,用于设置 requestreferrer
referrerPolicy
一个 referrer policy 用于设置 requestreferrerPolicy
mode
一个字符串,用于指示请求是使用 CORS,还是仅限于同源 URL。设置 requestmode。 如果 input 是一个字符串,它默认为 "cors"。
credentials
一个字符串,指示请求时是否始终、从不发送凭据,还是仅在发送到同源 URL 时发送——以及响应中返回的任何凭据是否始终、从不使用,还是仅在从同源 URL 接收到时使用。设置 requestcredentials。 如果 input 是一个字符串,它默认为 "same-origin"。
cache
一个字符串,指示请求将如何与浏览器的缓存交互,以设置 requestcache
redirect
一个字符串,指示 request 是遵循重定向,在遇到重定向时产生错误,还是返回重定向(以不透明方式)。设置 requestredirect
integrity
通过 request 获取的资源的加密哈希值。设置 requestintegrity
keepalive
一个布尔值,用于设置 requestkeepalive
signal
一个 AbortSignal 用于设置 requestsignal
window
只能为 null。用于将 request 与任何 Window 解除关联。
duplex
"half" 是唯一有效的值,它用于启动半双工 Fetch(即用户代理在处理响应之前发送整个请求)。 "full" 保留供将来使用,用于启动全双工 Fetch(即用户代理可以在发送整个请求之前处理响应)。当 bodyReadableStream 对象时需要设置该成员。参见 issue #1254 以定义 "full"。
priority
一个字符串,用于设置 requestpriority
request . method
返回 request 的 HTTP method,默认值为 "GET"。
request . url
以字符串形式返回 request 的 URL。
request . headers
返回一个 Headers 对象,该对象由与 request 关联的 headers 组成。 请注意,由用户代理在网络层添加的 headers 不会在此对象中计算,例如 "Host" header。
request . destination
返回 request 请求的资源种类,例如 "document" 或 "script"。
request . referrer
返回 request 的 referrer。如果在 init 中显式设置,其值可以是同源 URL、表示没有 referrer 的空字符串,以及默认为 global 默认值时的 "about:client"。这在 fetch 期间用于确定所发出请求的 Referer header 的值。
request . referrerPolicy
返回与 request 关联的 referrer policy。这在 fetch 期间用于计算 request 的 referrer 的值。
request . mode
返回与 request 关联的 mode,它是一个字符串,用于指示 请求是使用 CORS,还是仅限于同源 URL。
request . credentials
返回与 request 关联的 credentials mode,它是一个字符串, 指示请求时是否始终、从不发送凭据,还是仅在发送到同源 URL 时发送。
request . cache
返回与 request 关联的 cache mode,它是一个字符串,用于指示 请求在 fetch 时将如何与浏览器的缓存交互。
request . redirect
返回与 request 关联的 redirect mode,它是一个字符串,用于指示请求的重定向在 fetch 期间将如何处理。request 将默认跟随重定向。
request . integrity
返回 request 的子资源完整性元数据,它是 被 fetch 的资源的加密哈希。它的值由多个以空格分隔的哈希组成。[SRI]
request . keepalive
返回一个布尔值,指示 request 是否可以在其创建的 global 生命周期结束后继续存在。
request . isReloadNavigation
返回一个布尔值,指示 request 是否用于重新加载导航。
request . isHistoryNavigation
返回一个布尔值,指示 request 是否用于历史导航(即前进/后退导航)。
request . signal
返回与 request 关联的 signal,它是一个 AbortSignal 对象,指示 request 是否已被中止,以及其 abort 事件处理程序。
request . duplex
返回 "half",这意味着 fetch 将是半双工的(即用户代理在处理响应之前发送整个请求)。将来,它也可以返回 "full",这意味着 fetch 将是全双工的(即用户代理可以在发送整个请求之前处理响应),以指示 fetch 将是全双工的。参见 issue #1254 以 定义 "full"。
request . clone()

返回 request 的一个克隆。


一个 Request 对象,给定一个 request requestheaders guard guardAbortSignal 对象 signal,以及 realm realm

  1. requestObject 成为一个 新的 Request 对象,具有 realm

  2. requestObjectrequest 设置为 request

  3. requestObjectheaders 设置为一个 新的 Headers 对象,具有 realm,其 headers listrequestheaders listguardguard

  4. requestObjectsignal 设置为 signal

  5. 返回 requestObject


构造函数步骤如下:

  1. request 为 null。

  2. fallbackMode 为 null。

  3. baseURLthis相关设置对象API base URL

  4. signal 为 null。

  5. 如果 input 是字符串,则:

    1. parsedURL解析 inputbaseURL 的结果。

    2. 如果 parsedURL 失败,则 抛出 一个 TypeError

    3. 如果 parsedURL 包含凭据,则 抛出 一个 TypeError

    4. request 设置为一个新的 request,其 URLparsedURL

    5. fallbackMode 设置为 "cors"。

  6. 否则:

    1. 断言:input 是一个 Request 对象。

    2. request 设置为 inputrequest

    3. signal 设置为 inputsignal

  7. originthis相关设置对象origin

  8. window 为 "client"。

  9. 如果 requestwindow 是一个 环境设置对象 并且它的 originorigin 同源,则将 window 设置为 requestwindow

  10. 如果 init["window"] 存在 并且非 null,则 抛出 一个 TypeError

  11. 如果 init["window"] 存在,则将 window 设置为 "no-window"。

  12. request 设置为一个新的 request, 其属性如下:

    URL
    requestURL
    method
    requestmethod
    header list
    复制 requestheader list
    unsafe-request flag
    已设置。
    client
    This相关设置对象
    window
    window
    internal priority
    requestinternal priority
    origin
    requestorigin仅在服务工作线程处理导航请求时,origin 的传播才具有重要意义。在这种情况下,请求的 origin 可能与当前客户端不同。
    referrer
    requestreferrer
    referrer policy
    requestreferrer policy
    mode
    requestmode
    credentials mode
    requestcredentials mode
    cache mode
    requestcache mode
    redirect mode
    requestredirect mode
    integrity metadata
    requestintegrity metadata
    keepalive
    requestkeepalive
    reload-navigation flag
    requestreload-navigation flag
    history-navigation flag
    requesthistory-navigation flag
    URL list
    克隆 requestURL list
    initiator type
    "fetch"。
  13. 如果 init 不为空,则:

    1. 如果 requestmode 是 "navigate",则将其设置为 "same-origin"。

    2. 取消设置 requestreload-navigation flag

    3. 取消设置 requesthistory-navigation flag

    4. requestorigin 设置为 "client"。

    5. requestreferrer 设置为 "client"。

    6. requestreferrer policy 设置为空字符串。

    7. requestURL 设置为 requestcurrent URL

    8. requestURL list 设置为 « requestURL »。

    这样做是为了确保当服务工作线程 "重定向" 请求时,例如从跨域样式表中的 图片,并进行修改时,它不再看起来来自原始源(即跨域样式表),而是来自执行请求 "重定向" 的服务工作线程。这一点很重要,因为原始源可能甚至无法生成与服务工作线程相同类型的请求。因此,如果不这样做,则可能会利用信任原始源的服务,尽管这有些牵强。

  14. 如果 init["referrer"] 存在,则:

    1. referrerinit["referrer"]。

    2. 如果 referrer 是空字符串,则将 requestreferrer 设置为 "no-referrer"。

    3. 否则:

      1. parsedReferrer解析 referrerbaseURL 的结果。

      2. 如果 parsedReferrer 失败,则 抛出 一个 TypeError

      3. 如果以下任一情况成立

        则将 requestreferrer 设置为 "client"。

      4. 否则,将 requestreferrer 设置为 parsedReferrer

  15. 如果 init["referrerPolicy"] 存在,则将 requestreferrer policy 设置为该值。

  16. modeinit["mode"] ,如果该值 存在, 否则为 fallbackMode

  17. 如果 mode 是 "navigate",则 抛出 一个 TypeError

  18. 如果 mode 非 null,则将 requestmode 设置为 mode

  19. 如果 init["credentials"] 存在,则将 requestcredentials mode 设置为该值。

  20. 如果 init["cache"] 存在,则将 requestcache mode 设置为该值。

  21. 如果 requestcache mode 是 "only-if-cached" 并且 requestmode 不是 "same-origin",则 抛出 一个 TypeError

  22. 如果 init["redirect"] 存在,则将 requestredirect mode 设置为该值。

  23. 如果 init["integrity"] 存在,则将 requestintegrity metadata 设置为该值。

  24. 如果 init["keepalive"] 存在,则将 requestkeepalive 设置为该值。

  25. 如果 init["method"] 存在,则:

    1. methodinit["method"]。

    2. 如果 method 不是一个 methodmethod 是一个 forbidden method,则 抛出 一个 TypeError

    3. 标准化 method

    4. requestmethod 设置为 method

  26. 如果 init["signal"] 存在,则将 signal 设置为该值。

  27. 如果 init["priority"] 存在,则:

    1. 如果 requestinternal priority 非 null,则以 实现定义 的方式更新 requestinternal priority

    2. 否则,将 requestpriority 设置为 init["priority"]。

  28. thisrequest 设置为 request

  29. signals 为 « signal » 如果 signal 非 null;否则为 « »。

  30. thissignal 设置为 创建一个依赖的中止信号 的结果,使用 AbortSignalthis相关 realm

  31. thisheaders 设置为一个 新的 Headers 对象,使用 this相关 realm,其 header listrequestheader list 并且 guard 为 "request"。

  32. 如果 thisrequestmode 是 "no-cors",则:

    1. 如果 thisrequestmethod 不是一个 CORS-safelisted method,则 抛出 一个 TypeError

    2. thisheadersguard 设置为 "request-no-cors"。

  33. 如果 init 不为空,则:

    这些 headers 经过了消毒,因为它们可能包含此模式不允许的 headers。否则,它们之前已经经过消毒,或者自设置以来没有被修改,因为它们是由一个特权 API 设置的。

    1. headersthisheaders 和其 关联的 header list 的副本。

    2. 如果 init["headers"] 存在,则将 headers 设置为 init["headers"]。

    3. 清空 thisheadersheader list

    4. 如果 headers 是一个 Headers 对象,则 对于每个 header 在其 header list追加 headerthisheaders

    5. 否则,填充 thisheaders 使用 headers

  34. inputBodyinputrequestbody,如果 input 是一个 Request 对象;否则为 null。

  35. 如果 init["body"] 存在 并且非 null 或 inputBody 非 null,并且 requestmethod 是 `GET` 或 `HEAD`,则 抛出 一个 TypeError

  36. initBody 为 null。

  37. 如果 init["body"] 存在 并且非 null,则:

    1. bodyWithType提取 init["body"], 并设置 keepaliverequestkeepalive 的结果。

    2. initBody 设置为 bodyWithTypebody

    3. typebodyWithTypetype

    4. 如果 type 非 null 并且 thisheadersheader list 不包含 `Content-Type`,则 追加 (`Content-Type`, type) 到 thisheaders

  38. inputOrInitBodyinitBody 如果它非 null;否则为 inputBody

  39. 如果 inputOrInitBody 非 null 并且 inputOrInitBodysource 为 null,则:

    1. 如果 initBody 非 null 并且 init["duplex"] 不 存在,则抛出一个 TypeError

    2. 如果 thisrequestmode 既不是 "same-origin" 也不是 "cors",则抛出一个 TypeError

    3. thisrequestuse-CORS-preflight flag

  40. finalBodyinputOrInitBody

  41. 如果 initBody 为 null 并且 inputBody 非 null,则:

    1. 如果 input不可用, 则 抛出 一个 TypeError

    2. finalBody 设置为 创建一个代理 的结果给 inputBody

  42. thisrequestbody 设置为 finalBody

The getter 的步骤是返回 thisrequestmethod

The getter 的步骤是返回 thisrequestURL,并且序列化

The getter 的步骤是返回 thisheaders

The getter 的步骤是返回 thisrequestdestination

The getter 的步骤是:

  1. 如果 thisrequestreferrer 是 "no-referrer",则返回空字符串。

  2. 如果 thisrequestreferrer 是 "client",则返回 "about:client"。

  3. 返回 thisrequestreferrer,并且序列化

The getter 的步骤是返回 thisrequestreferrer policy

The getter 的步骤是返回 thisrequestmode

The getter 的步骤是返回 thisrequestcredentials mode

The getter 的步骤是返回 thisrequestcache mode

The getter 的步骤是返回 thisrequestredirect mode

The getter 的步骤是返回 thisrequestintegrity metadata

The getter 的步骤是返回 thisrequestkeepalive

The getter 的步骤是返回 true 如果 thisrequestreload-navigation flag 被设置; 否则返回 false。

The getter 的步骤是返回 true 如果 thisrequesthistory-navigation flag 被设置; 否则返回 false。

The getter 的步骤是返回 thissignal

The getter 的步骤是返回 "half"。


The method 的步骤是:

  1. 如果 thisunusable,则抛出一个TypeError

  2. clonedRequest 成为克隆thisrequest的结果。

  3. 断言thissignal 非空。

  4. clonedSignal 成为 « thissignal » 创建一个依赖中止信号的结果,使用AbortSignalthis相关领域

  5. clonedRequestObject 成为创建一个Request 对象的结果,给定 clonedRequestthisheadersguardclonedSignalthis相关领域

  6. 返回 clonedRequestObject

5.5. Response 类

[Exposed=(Window,Worker)]interface  {
  constructor(optional BodyInit?  = null, optional ResponseInit  = {});

  [NewObject] static Response error();
  [NewObject] static Response redirect(USVString , optional unsigned short  = 302);
  [NewObject] static Response json(any , optional ResponseInit  = {});

  readonly attribute ResponseType type;

  readonly attribute USVString url;
  readonly attribute boolean redirected;
  readonly attribute unsigned short status;
  readonly attribute boolean ok;
  readonly attribute ByteString statusText;
  [SameObject] readonly attribute Headers headers;

  [NewObject] Response clone();
};
Response includes Body;

dictionary  {
  unsigned short  = 200;
  ByteString  = "";
  HeadersInit ;
};

enum  { , , , , ,  };

一个 Response 对象有一个关联的(一个 response)。

一个 Response 对象也有一个关联的(null 或一个 Headers 对象),最初为 null。

一个 Response 对象的body是其responsebody


response = new Response(body = null [, init])

创建一个 Response ,其body为 body,状态、状态消息和 headers 由 init 提供。

response = Response . error()

创建网络错误 Response

response = Response . redirect(url, status = 302)

创建一个重定向 Response ,重定向到 url,状态为 status

response = Response . json(data [, init])

创建一个 Response ,其body是JSON编码的 data,状态、状态 消息和 headers 由 init 提供。

response . type

返回 response 的类型,例如 "cors"。

response . url

返回 response 的 URL(如果有);否则返回空字符串。

response . redirected

返回 response 是否通过重定向获得。

response . status

返回 response 的状态。

response . ok

返回 response 的状态是否为 ok 状态

response . statusText

返回 response 的状态消息。

response . headers

返回 response 的 headers 作为Headers

response . clone()

返回 response 的克隆。


一个 Response 对象,给定一个 response response、一个headers guard guard和一个realm realm,执行以下步骤:

  1. responseObject 成为一个 new Response 对象,带有 realm

  2. responseObjectresponse 设置为 response

  3. responseObjectheaders 设置为 一个 new Headers 对象,带有 realm,其headers listresponseheaders listguardguard

  4. 返回 responseObject

,给定一个 Response 对象 responseResponseInit init和null或带类型的 body body

  1. 如果 init["status"] 不在 200 到 599 范围内(含),则抛出一个 RangeError

  2. 如果 init["statusText"] 不匹配reason-phrase标记生成,则抛出一个 TypeError

  3. responseresponsestatus设置为 init["status"]。

  4. responseresponsestatus message设置为 init["statusText"]。

  5. 如果 init["headers"] 存在,则使用 init["headers"] 填充 responseheaders

  6. 如果 body 非 null,则:

    1. 如果 responsestatus是一个 null body status,则抛出一个 TypeError

      101 和 103 包含在 null body status 中是由于其在其他地方的使用。 它们不影响此步骤。

    2. responsebody 设置为 bodybody

    3. 如果 bodytype 非 null,且 responseheader list 不包含 `Content-Type`,则追加 (`Content-Type`, bodytype) 到 responseheader list


构造函数步骤如下:

  1. thisresponse 设置为一个新的 response

  2. thisheaders 设置为一个 new Headers 对象,带有 this相关 realm,其 header listthisresponseheader list,且 guard 为 "response"。

  3. bodyWithType 为 null。

  4. 如果 body 非 null,则将 bodyWithType 设置为提取 body 的结果。

  5. 执行 初始化 response,给定 thisinitbodyWithType

静态 方法步骤是返回 创建一个 Response 对象的结果,给定一个新的 网络错误, "immutable",和当前 realm

静态 方法 步骤如下:

  1. parsedURL 成为 解析 url 的结果,使用 当前设置对象API 基本 URL

  2. 如果 parsedURL 解析失败,则抛出一个 TypeError

  3. 如果 status 不是一个 重定向状态,则抛出一个 RangeError

  4. responseObject 成为 创建一个 Response 对象的结果,给定一个新的 response、"immutable"和当前 realm

  5. responseObjectresponsestatus 设置为 status

  6. value 设置为 parsedURL序列化同构编码

  7. 追加 (`Location`,value) 到 responseObjectresponseheader list

  8. 返回 responseObject

静态 方法步骤 如下:

  1. bytes 成为运行 将 JavaScript 值序列化为 JSON 字节data 上的结果。

  2. body 成为 提取 bytes 的结果。

  3. responseObject 成为 创建一个 Response 对象的结果,给定一个新的 response、"response"和当前 realm

  4. 执行 初始化 response,给定 responseObjectinit 和 (body,"application/json")。

  5. 返回 responseObject

getter步骤是返回thisresponsetype

getter步骤是返回 空字符串如果 thisresponseURL 为 null; 否则 thisresponseURL序列化排除片段设置 为 true。

getter步骤是返回 true,如果 thisresponseURL 列表大小大于1;否则为 false。

要过滤掉 responses 这些响应是 重定向的结果,请直接通过 API 执行此操作,例如,fetch(url, { redirect:"error" })。 这样,一个潜在不安全的 response 就不会意外泄漏。

getter步骤是返回 thisresponsestatus

getter步骤是返回 true 如果 thisresponsestatus 是一个 ok 状态; 否则为 false。

getter步骤是返回 thisresponsestatus message

getter步骤是返回 thisheaders


方法步骤如下:

  1. 如果 this不可用的,则抛出一个 TypeError

  2. clonedResponse 成为 克隆 thisresponse 的结果。

  3. 返回 创建一个 Response 对象的结果,给定 clonedResponsethisheadersguard, 和 this相关 realm

5.6. Fetch 方法

partial interface mixin WindowOrWorkerGlobalScope {
  [NewObject] Promise<Response> fetch(RequestInfo , optional RequestInit  = {});
};

方法的步骤如下:

  1. p 成为 一个新的 promise

  2. requestObject 成为调用初始值 Request 作为构造函数的结果,并将 inputinit 作为参数。如果抛出异常,拒绝 p 并返回 p

  3. request 成为 requestObjectrequest

  4. 如果 requestObjectsignal已中止,则:

    1. 中止 fetch() 调用,使用 prequest,null,以及 requestObjectsignal中止原因

    2. 返回 p

  5. globalObject 成为 requestclientglobal object
  6. 如果 globalObject 是一个 ServiceWorkerGlobalScope 对象, 则将 requestservice-workers 模式设置为 "none"。
  7. responseObject 为 null。

  8. relevantRealm 成为 thisrelevant realm

  9. locallyAborted 为 false。

    这使我们能够在从与调用 fetch 相同的线程发出中止请求时,以可预测的时间拒绝 promise。

  10. controller 为 null。

  11. 将以下中止步骤 添加到 requestObjectsignal

    1. locallyAborted 设置为 true。

    2. 断言controller 非 null。

    3. 中止 controller,使用 requestObjectsignal中止原因

    4. 中止 fetch() 调用,使用 prequestresponseObjectrequestObjectsignal中止原因

  12. controller 设置为调用 fetch 的结果,给定 requestprocessResponse,给定 response 为 以下步骤:

    1. 如果 locallyAborted 为 true,则中止这些步骤。

    2. 如果 response已中止标志 已设置,则:

      1. deserializedError 成为 反序列化已序列化的中止原因 的结果,给定 controller已序列化的中止原因relevantRealm

      2. 中止 fetch() 调用,使用 prequestresponseObjectdeserializedError

      3. 中止这些步骤。

    3. 如果 response网络错误,则拒绝 p ,使用 TypeError 并中止这些步骤。

    4. responseObject 设置为 创建一个 Response 对象的结果,给定 response、"immutable" 和 relevantRealm

    5. 解决 p,使用 responseObject

  13. 返回 p

,使用 promiserequestresponseObject 和一个 error

  1. 拒绝 promise,使用 error

    如果 promise 已经实现,这是无操作。

  2. 如果 requestbody 非 null 并且是 可读的,则取消 requestbody,使用 error

  3. 如果 responseObject 是 null,则返回。

  4. response 成为 responseObjectresponse

  5. 如果 responsebody 非 null 并且是 可读的,则使 responsebody 出现错误,使用 error

5.7. 垃圾回收

如果终止操作无法通过脚本观察到,用户代理可以终止正在进行的 fetch。

“通过脚本观察到”指的是通过 fetch() 的参数和返回值观察到。其他方式,例如通过侧信道与服务器通信,则不包括在内。

服务器能够观察到垃圾回收是有先例的,例如,WebSocketXMLHttpRequest 对象。

用户代理可以终止 fetch,因为终止操作无法被观察到。

fetch("https://www.example.com/")

用户代理无法终止 fetch,因为终止操作可以通过 promise 被观察到。

window.promise = fetch("https://www.example.com/")

用户代理可以终止 fetch,因为关联的 body 无法被观察到。

window.promise = fetch("https://www.example.com/").then(res => res.headers)

用户代理可以终止 fetch,因为终止操作无法被观察到。

fetch("https://www.example.com/").then(res => res.body.getReader().closed)

用户代理无法终止 fetch,因为可以通过为 promise 对象注册处理程序来观察到终止操作。

window.promise = fetch("https://www.example.com/")
  .then(res => res.body.getReader().closed)

用户代理无法终止 fetch,因为终止操作会通过已注册的处理程序被观察到。

fetch("https://www.example.com/")
  .then(res => {
    res.body.getReader().closed.then(() => console.log("stream closed!"))
  })

(以上关于不可观察性的示例假设内置属性和函数,例如 body.getReader(),未被重写。)

6. data: URLs

有关 data: URL 的说明,请参阅 RFC 2397。本节替换了该 RFC 的规范处理要求,以兼容已部署的内容。[RFC2397]

是一个结构体,包含一个 (一个MIME 类型)和一个(一个字节序列)。

接收一个 URLdataURL,并执行以下步骤:

  1. 断言:dataURLscheme 为 "data"。

  2. input 成为使用URL 序列化器处理 dataURL 的结果,且排除片段 设置为 true。

  3. input 中移除前导的 "data:"。

  4. position 指向 input 的起始位置。

  5. mimeType 成为根据 position 收集一系列代码点结果,条件是不等于 U+002C (,)。

  6. 去除 mimeType 中的前导和尾随 ASCII 空白。

    这将只移除 U+0020 空格代码点,如果有的话。

  7. 如果 position 超出了 input 的末尾,则返回失败。

  8. 使 position 前进 1。

  9. encodedBody 成为 input 的剩余部分。

  10. body 成为 encodedBody百分比解码的结果。

  11. 如果 mimeType 以 U+003B (;) 结尾,后跟零个或多个 U+0020 空格,后跟base64ASCII 大小写不敏感匹配,则:

    1. stringBody 成为 body同构解码结果。

    2. body 设置为 stringBody宽容的 base64 解码结果。

    3. 如果 body 是失败,则返回失败。

    4. mimeType 中移除最后 6 个代码点

    5. 移除 mimeType 中尾随的 U+0020 空格代码点,如果有的话。

    6. mimeType 中移除最后一个 U+003B (;)。

  12. 如果 mimeType ";"开头,则将 "text/plain" 前置到 mimeType

  13. mimeTypeRecord 成为 解析 mimeType 的结果。

  14. 如果 mimeTypeRecord 是失败,则将 mimeTypeRecord 设置为 text/plain;charset=US-ASCII

  15. 返回一个新的 data: URL 结构体,其MIME 类型mimeTypeRecord主体body

背景阅读

本节及其子节仅供参考。

在 Fetch 的上下文中,存在 API 层(HTML 的 img,CSS 的 background-image)、早期 Fetch 层、Service Worker 层以及网络与缓存层。`Accept` 和 `Accept-Language` 在早期 Fetch 层中设置(通常由用户代理设置)。大多数由用户代理控制的其他头,如 `Accept-Encoding`、`Host` 和 `Referer`,在网络与缓存层中设置。开发者可以在 API 层或 Service Worker 层(通常通过一个 Request 对象)设置头。开发者几乎无法控制禁止的请求头,但可以控制 `Accept`,并且能够限制和省略 `Referer` 之类的头。

重定向(响应状态内部响应(如果有) 的 状态重定向状态)不会暴露给 API。暴露重定向可能会泄露通过跨站脚本攻击无法获得的信息。

例如,发起到 https://example.org/auth 的 Fetch 请求,其中包含标记为 HttpOnlyCookie,可能会导致重定向到 https://other-origin.invalid/4af955781ea1c84a3b11。这个新的 URL 包含了一个秘密。如果我们暴露重定向,该秘密可能通过跨站脚本攻击被获取。

基本安全的 CORS 协议设置

对于通过 IP 认证或防火墙保护的数据资源(遗憾的是仍然相对常见),使用 CORS 协议不安全的。 (这就是CORS 协议必须被发明的原因。)

然而,使用以下 安全的

Access-Control-Allow-Origin: *

即使资源基于 Cookie 或 HTTP 认证暴露了额外的信息,使用上述 也不会泄露它。它会与 XMLHttpRequest 等 API 共享资源,就像它已经与 curlwget 共享资源一样。

因此,换句话说,如果资源不能通过连接到网络的随机设备使用 curlwget 访问,则不应包含上述 。然而,如果可以访问,则完全可以包含。

CORS 协议与 HTTP 缓存

如果CORS 协议要求比将 `Access-Control-Allow-Origin` 设置为 * 或静态 更加复杂,则应使用 `Vary`。[HTML] [HTTP] [HTTP-CACHING]

Vary: Origin

尤其是,考虑如果在上面描述的相同场景中没有使用 `Vary` 会发生什么情况,并且服务器配置为仅在响应 CORS 请求时才发送 `Access-Control-Allow-Origin`。当用户代理接收到非 CORS 请求的响应(例如,作为 导航请求的结果)时,该响应将缺少 `Access-Control-Allow-Origin`,用户代理将缓存该响应。然后,如果用户代理随后遇到该资源的 CORS 请求,它将使用先前非 CORS 请求的缓存响应,而不会包含 `Access-Control-Allow-Origin`。

但如果在上述场景中使用 `Vary: Origin`,它将使用户代理获取包含 `Access-Control-Allow-Origin` 的响应,而不是使用先前非 CORS 请求的缓存响应,该响应不包含 `Access-Control-Allow-Origin`。

然而,如果将 `Access-Control-Allow-Origin` 设置为 * 或特定资源的静态 ,则配置服务器以始终在该资源的响应中发送 `Access-Control-Allow-Origin`,无论是非 CORS 请求还是 CORS 请求,并且不要使用 `Vary`。

WebSocket

作为建立连接的一部分,WebSocket 对象会发起一种特殊的 fetch(使用 请求,其 模式 是 "websocket"),允许它共享许多 fetch 策略决策,例如 HTTP 严格传输安全 (HSTS)。最终,这导致 fetch 调用 WebSocket 以获得专用连接。[WEBSOCKETS] [HSTS]

Fetch 以前直接定义了获取 WebSocket 连接建立 WebSocket 连接,但现在这两个操作都在 WebSocket 中定义。[WEBSOCKETS]

在其他标准中使用 fetch

本质上,fetch 是一个交换 请求响应 的过程。实际上,这是一个相当复杂的机制,标准需要正确采用和使用。此部分旨在提供一些建议。

始终请领域专家进行审查。

这是一个正在进行的工作。

设置请求

fetch 的第一步是创建一个 请求,并填充其

首先设置 请求URL方法,如 HTTP 所定义的。如果你的 `POST` 或 `PUT` 请求 需要一个正文,你将 请求正文 设置为一个 字节序列,或一个新的 正文,其 是你创建的一个 ReadableStream[HTTP]

根据 目的地表 中的指导选择你的 请求目的地目的地 影响 内容安全政策,并有其他影响,如 `Sec-Fetch-Dest` 头,所以它们不仅仅是信息性元数据。如果一个新功能需要一个不在 目的地表 中的 目的地,请 提交问题 进行讨论。[CSP]

将你的 请求客户端 设置为你所操作的 环境设置对象。Web 公开的 API 通常使用 Web IDL 定义,因此每个实现 接口 的对象都有一个可以使用的 相关设置对象。例如,与 元素 关联的 请求 将把请求的 客户端 设置为元素的 节点文档相关设置对象。所有由 JavaScript、HTML、CSS 或其他 文档 子资源直接在网络上公开的功能都应该有一个 客户端

如果你的 fetch 不直接在网络上公开,例如,它是在后台发送的,不依赖于当前的 窗口工作者,则将请求的 客户端 保持为空,并将请求的 来源策略容器服务工作者模式引荐来源 设置为适当的值,例如,通过提前从 环境设置对象 复制它们。在这些更高级的情况下,请确保详细说明你的 fetch 如何处理 内容安全政策引荐来源政策。还要确保你处理并发性,因为回调(参见 调用 fetch 和处理响应)将在 并行队列 上发布。[REFERRER] [CSP]

仔细考虑你打算如何处理跨源资源。有些功能可能只能在 同源 中工作,在这种情况下,将你的请求的 请求模式 设置为 "same-origin"。否则,几乎所有新的 Web 公开功能都应该将它们的 模式 设置为 "cors"。如果你的功能不在网络上公开,或者你认为有其他原因使其无需 CORS 就能 fetch 跨源资源,请 提交问题 进行讨论。

对于跨源请求,还需确定是否应包含 凭证,在这种情况下,将你的请求的 请求凭证模式 设置为 "include"。

考虑你的 fetch 是否需要报告给 资源计时,以及使用哪个 发起者类型。通过将 发起者类型 传递给 请求,一旦 fetch 完成并且 响应 完全下载后,将自动报告给 资源计时[RESOURCE-TIMING]

如果你的请求需要额外的 HTTP 头,将其 头列表 设置为包含这些头的 头列表,例如 « (`My-Header-Name`, `My-Header-Value`) »。发送自定义头可能会有影响,例如需要一个 CORS 预检 fetch,因此要小心处理。

如果你想覆盖默认的缓存机制,例如,禁用此 请求 的缓存,将请求的 缓存模式 设置为 "default" 以外的值。

确定是否希望你的请求支持重定向。如果不希望,设置其 重定向模式 为 "error"。

浏览请求的其他参数,看看是否有其他与您相关的内容。这些参数很少使用,通常用于特殊目的,它们在本标准的 § 2.2.5 请求 部分中详细记录。

调用 fetch 和处理响应

除了一个 请求 之外,fetch 操作还接受几个可选参数。对于那些接受算法的参数:如果 useParallelQueue 为 true,则算法将从任务中调用(或在 并行队列 中调用)。

一旦设置好了 请求,为了确定传递给 fetch 的算法,首先确定你希望如何处理 响应,特别是你希望在哪个阶段接收到回调:

完成时

大多数调用者会这样处理 响应,例如 脚本样式资源响应正文将被完全读取为 字节序列,然后由调用者处理。

要在完成时处理 响应,将一个算法传递给 processResponseConsumeBody 参数。所给算法将传递一个 响应 和表示完全读取的 正文(响应的 内部响应)的参数。第二个参数的值具有以下含义:

null
由于响应是 网络错误 或具有 null 正文状态,因此响应的 正文为 null。
failure
尝试 完全读取响应正文的内容失败,例如,由于 I/O 错误。
一个 字节序列

成功 完全读取内部响应正文的内容。

对于 请求 模式为 "no-cors" 的情况,也会传递包含完整内容的字节序列。调用者在处理此类内容时必须谨慎,因为这些内容不应对请求的 来源可见。例如,调用者可以使用 "no-cors" 响应的内容直接向用户显示图像内容,但这些图像内容不应直接暴露给嵌入文档中的脚本。

  1. request 为一个请求,其 URLhttps://stuff.example.com/,并且其 客户端this相关设置对象

  2. Fetch request,其中 processResponseConsumeBody 设置为在给定响应 response 和 null、失败或字节序列 contents 的情况下执行以下步骤:

    1. 如果 contents 为 null 或失败,则向用户显示错误。

    2. 否则,根据 response 的元数据解析 contents,并进行相应操作。

先处理头部,然后逐块处理

在某些情况下,例如播放视频或渐进加载图像时,调用者可能希望以流式方式逐块处理响应。在处理完头部后,响应将交给 fetch 调用者,调用者从此继续处理。

要逐块处理响应,将一个算法传递给 processResponse 参数。所给算法在接收到响应的头部时传递一个响应,并负责读取响应正文的流以下载其余部分。为方便起见,你还可以将一个算法传递给 processResponseEndOfBody 参数,该算法在你完成读取响应及其正文后调用。请注意,与 processResponseConsumeBody 不同,传递 processResponseprocessResponseEndOfBody 参数并不保证响应将被完全读取,调用者需要自行读取。

processResponse 参数对于处理响应的头部列表和状态而不处理正文也很有用。例如,当处理没有 ok 状态 的响应时会使用此方式。

  1. request 为一个请求,其 URLhttps://stream.example.com/,并且其 客户端this相关设置对象

  2. Fetch request,其中 processResponse 设置为在给定响应 response 时执行以下步骤:

    1. 如果 response网络错误,则向用户显示错误。

    2. 否则,如果 response状态 不是 ok 状态,则向用户显示一些备用值。

    3. 否则,为响应正文的流获取一个读取器,并根据从响应头中提取的 MIME 类型适当处理。

忽略响应

在某些情况下,例如在 navigator.sendBeacon() 的情况下,根本不需要响应。处理响应并将回调传递给 fetch 是可选的,因此省略回调会在不期待响应的情况下调用 fetch。在这种情况下,响应的正文流将被丢弃,调用者无需担心不必要地下载内容。

Fetch 一个请求,其 URLhttps://fire-and-forget.example.com/,其 方法 为 `POST`,其 客户端this相关设置对象

除了处理响应的回调外,fetch 还接受用于高级情况的额外回调。processEarlyHintsResponse 专为状态为 103 的响应设计,目前仅由导航处理。processRequestBodyChunkLengthprocessRequestEndOfBody 通知调用者请求正文上传的进度。

请注意,fetch 操作从调用它的同一个线程开始,然后分离出来以并行运行其内部操作。上述回调将发布到给定的事件循环中,默认情况下是客户端的全局对象。要并行处理响应并自行处理与主线程的交互,请将 fetchuseParallelQueue 设置为 true。

操作正在进行的 fetch

要操作已经开始的 fetch 操作,可以使用调用 fetch 时返回的 fetch 控制器。例如,你可以由于用户或页面逻辑的原因 中止fetch 控制器,或由于浏览器内部的情况 终止它。

除了终止和中止之外,调用者还可以在未通过传递 initiator type 自动完成时 报告时序,或提取完整的时序信息并在调用者端处理(此操作仅由导航执行)。fetch 控制器还用于 处理下一个手动重定向,针对 请求 设置了重定向模式为 "manual" 的情况。

致谢

感谢 Adam Barth, Adam Lavin, Alan Jeffrey, Alexey Proskuryakov, Andreas Kling, Andrés Gutiérrez, Andrew Sutherland, Ángel González, Anssi Kostiainen, Arkadiusz Michalski, Arne Johannessen, Artem Skoretskiy, Arthur Barstow, Arthur Sonzogni, Asanka Herath, Axel Rauschmayer, Ben Kelly, Benjamin Gruenbaum, Benjamin Hawkes-Lewis, Bert Bos, Björn Höhrmann, Boris Zbarsky, Brad Hill, Brad Porter, Bryan Smith, Caitlin Potter, Cameron McCormack, Carlo Cannas, 白丞祐 (Cheng-You Bai), Chirag S Kumar, Chris Needham, Chris Rebert, Clement Pellerin, Collin Jackson, Daniel Robertson, Daniel Veditz, Dave Tapuska, David Benjamin, David Håsäther, David Orchard, Dean Jackson, Devdatta Akhawe, Domenic Denicola, Dominic Farolino, Dominique Hazaël-Massieux, Doug Turner, Douglas Creager, Eero Häkkinen, Ehsan Akhgari, Emily Stark, Eric Lawrence, Eric Orth, François Marier, Frank Ellerman, Frederick Hirsch, Frederik Braun, Gary Blackwood, Gavin Carothers, Glenn Maynard, Graham Klyne, Gregory Terzian, Hal Lockhart, Hallvord R. M. Steen, Harris Hancock, Henri Sivonen, Henry Story, Hiroshige Hayashizaki, Honza Bambas, Ian Hickson, Ilya Grigorik, isonmad, Jake Archibald, James Graham, Jamie Mansfield, Janusz Majnert, Jeena Lee, Jeff Carpenter, Jeff Hodges, Jeffrey Yasskin, Jensen Chappell, Jeremy Roman, Jesse M. Heines, Jianjun Chen, Jinho Bang, Jochen Eisinger, John Wilander, Jonas Sicking, Jonathan Kingston, Jonathan Watt, 최종찬 (Jongchan Choi), Jordan Stephens, Jörn Zaefferer, Joseph Pecoraro, Josh Matthews, jub0bs, Julian Krispel-Samsel, Julian Reschke, 송정기 (Jungkee Song), Jussi Kalliokoski, Jxck, Kagami Sascha Rosylight, Keith Yeung, Kenji Baheux, Lachlan Hunt, Larry Masinter, Liam Brummitt, Linus Groh, Louis Ryan, Luca Casonato, Lucas Gonze, Łukasz Anforowicz, 呂康豪 (Kang-Hao Lu), Maciej Stachowiak, Malisa, Manfred Stock, Manish Goregaokar, Marc Silbey, Marcos Caceres, Marijn Kruisselbrink, Mark Nottingham, Mark S. Miller, Martin Dürst, Martin O’Neal, Martin Thomson, Matt Andrews, Matt Falkenhagen, Matt Menke, Matt Oshry, Matt Seddon, Matt Womer, Mhano Harkness, Michael Ficarra, Michael Kohler, Michael™ Smith, Mike Pennisi, Mike West, Mohamed Zergaoui, Mohammed Zubair Ahmed, Moritz Kneilmann, Ms2ger, Nico Schlömer, Nicolás Peña Moreno, Nidhi Jaju, Nikhil Marathe, Nikki Bee, Nikunj Mehta, Noam Rosenthal, Odin Hørthe Omdal, Olli Pettay, Ondřej Žára, O. Opsec, Patrick Meenan, Perry Jiang, Philip Jägenstedt, R. Auburn, Raphael Kubo da Costa, Robert Linder, Rondinelly, Rory Hewitt, Ross A. Baker, Ryan Sleevi, Sam Atkins, Samy Kamkar, Sébastien Cevey, Sendil Kumar N, Shao-xuan Kang, Sharath Udupa, Shivakumar Jagalur Matt, Shivani Sharma, Sigbjørn Finne, Simon Pieters, Simon Sapin, Srirama Chandra Sekhar Mogali, Stephan Paul, Steven Salat, Sunava Dutta, Surya Ismail, Tab Atkins-Bittner, Takashi Toyoshima, 吉野剛史 (Takeshi Yoshino), Thomas Roessler, Thomas Steiner, Thomas Wisniewski, Tiancheng "Timothy" Gu, Tobie Langel, Tom Schuster, Tomás Aparicio, triple-underscore, 保呂毅 (Tsuyoshi Horo), Tyler Close, Ujjwal Sharma, Vignesh Shanmugam, Vladimir Dzhuvinov, Wayne Carr, Xabier Rodríguez, Yehuda Katz, Yoav Weiss, Youenn Fablet, Yoichi Osato, 平野裕 (Yutaka Hirano), and Zhenbin Xu 感谢你们的卓越贡献。

本标准由 Anne van KesterenAppleannevk@annevk.nl)撰写。

知识产权

版权所有 © WHATWG(Apple、Google、Mozilla、Microsoft)。本作品依据 知识共享署名4.0国际许可协议 授权。若其中部分内容被纳入源代码,这些部分在源代码中将依据 BSD 3-Clause License 授权。

这是现行标准。对专利审查版本感兴趣的读者请查阅 现行标准审查草案

索引

本规范定义的术语

Terms defined by reference

References

Normative References

[ABNF]
D. Crocker, Ed.; P. Overell. Augmented BNF for Syntax Specifications: ABNF. January 2008. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc5234
[BEACON]
Ilya Grigorik; Alois Reitbauer. Beacon. URL: https://w3c.github.io/beacon/
[COOKIES]
A. Barth. HTTP State Management Mechanism. April 2011. Proposed Standard. URL: https://httpwg.org/specs/rfc6265.html
[CSP]
Mike West; Antonio Sartori. Content Security Policy Level 3. URL: https://w3c.github.io/webappsec-csp/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. URL: https://drafts.csswg.org/css-values-4/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[ENCODING]
Anne van Kesteren. Encoding Standard. Living Standard. URL: https://encoding.spec.whatwg.org/
[FETCH-METADATA]
Mike West. Fetch Metadata Request Headers. URL: https://w3c.github.io/webappsec-fetch-metadata/
[FILEAPI]
Marijn Kruisselbrink. File API. URL: https://w3c.github.io/FileAPI/
[HR-TIME-3]
Yoav Weiss. High Resolution Time. URL: https://w3c.github.io/hr-time/
[HSTS]
J. Hodges; C. Jackson; A. Barth. HTTP Strict Transport Security (HSTS). November 2012. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc6797
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[HTTP]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTP Semantics. June 2022. Internet Standard. URL: https://httpwg.org/specs/rfc9110.html
[HTTP-CACHING]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTP Caching. June 2022. Internet Standard. URL: https://httpwg.org/specs/rfc9111.html
[HTTP1]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTP/1.1. June 2022. Internet Standard. URL: https://httpwg.org/specs/rfc9112.html
[HTTP3]
M. Bishop, Ed.. HTTP/3. June 2022. Proposed Standard. URL: https://httpwg.org/specs/rfc9114.html
[HTTP3-DATAGRAM]
D. Schinazi; L. Pardue. HTTP Datagrams and the Capsule Protocol. August 2022. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc9297
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[MIMESNIFF]
Gordon P. Hemsley. MIME Sniffing Standard. Living Standard. URL: https://mimesniff.spec.whatwg.org/
[MIX]
Emily Stark; Mike West; Carlos IbarraLopez. Mixed Content. URL: https://w3c.github.io/webappsec-mixed-content/
[REFERRER]
Jochen Eisinger; Emily Stark. Referrer Policy. URL: https://w3c.github.io/webappsec-referrer-policy/
[REPORTING]
Douglas Creager; Ian Clelland; Mike West. Reporting API. URL: https://w3c.github.io/reporting/
[RESOURCE-TIMING]
Yoav Weiss; Noam Rosenthal. Resource Timing. URL: https://w3c.github.io/resource-timing/
[RFC7405]
P. Kyzivat. Case-Sensitive String Support in ABNF. December 2014. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7405
[RFC7578]
L. Masinter. Returning Values from Forms: multipart/form-data. July 2015. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7578
[RFC8941]
M. Nottingham; P-H. Kamp. Structured Field Values for HTTP. February 2021. Proposed Standard. URL: https://httpwg.org/specs/rfc8941.html
[RFC9218]
K. Oku; L. Pardue. Extensible Prioritization Scheme for HTTP. June 2022. Proposed Standard. URL: https://httpwg.org/specs/rfc9218.html
[SRI]
Devdatta Akhawe; et al. Subresource Integrity. URL: https://w3c.github.io/webappsec-subresource-integrity/
[STALE-WHILE-REVALIDATE]
M. Nottingham. HTTP Cache-Control Extensions for Stale Content. May 2010. Informational. URL: https://httpwg.org/specs/rfc5861.html
[STREAMS]
Adam Rice; et al. Streams Standard. Living Standard. URL: https://streams.spec.whatwg.org/
[SVCB]
Ben Schwartz; Mike Bishop; Erik Nygren. Service binding and parameter specification via the DNS (DNS SVCB and HTTPS RRs). URL: https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https
[SW]
Jake Archibald; Marijn Kruisselbrink. Service Workers. URL: https://w3c.github.io/ServiceWorker/
[TLS]
E. Rescorla. The Transport Layer Security (TLS) Protocol Version 1.3. August 2018. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc8446
[UPGRADE-INSECURE-REQUESTS]
Mike West. Upgrade Insecure Requests. URL: https://w3c.github.io/webappsec-upgrade-insecure-requests/
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/
[WEBSOCKETS]
Adam Rice. WebSockets Standard. Living Standard. URL: https://websockets.spec.whatwg.org/
[WEBTRANSPORT-HTTP3]
V. Vasiliev. WebTransport over HTTP/3. URL: https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http3
[XHR]
Anne van Kesteren. XMLHttpRequest Standard. Living Standard. URL: https://xhr.spec.whatwg.org/

Informative References

[HTTPVERBSEC1]
Multiple vendors' web servers enable HTTP TRACE method by default.. URL: https://www.kb.cert.org/vuls/id/867593
[HTTPVERBSEC2]
Microsoft Internet Information Server (IIS) vulnerable to cross-site scripting via HTTP TRACK method.. URL: https://www.kb.cert.org/vuls/id/288308
[HTTPVERBSEC3]
HTTP proxy default configurations allow arbitrary TCP connections.. URL: https://www.kb.cert.org/vuls/id/150227
[NAVIGATION-TIMING]
Zhiheng Wang. Navigation Timing. 17 December 2012. REC. URL: https://www.w3.org/TR/navigation-timing/
[ORIGIN]
A. Barth. The Web Origin Concept. December 2011. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc6454
[RFC1035]
P. Mockapetris. Domain names - implementation and specification. November 1987. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc1035
[RFC2397]
L. Masinter. The "data" URL scheme. August 1998. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc2397
[RFC6960]
S. Santesson; et al. X.509 Internet Public Key Infrastructure Online Certificate Status Protocol - OCSP. June 2013. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc6960
[RFC7301]
S. Friedl; et al. Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension. July 2014. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7301
[RFC7918]
A. Langley; N. Modadugu; B. Moeller. Transport Layer Security (TLS) False Start. August 2016. Informational. URL: https://www.rfc-editor.org/rfc/rfc7918
[RFC8470]
M. Thomson; M. Nottingham; W. Tarreau. Using Early Data in HTTP. September 2018. Proposed Standard. URL: https://httpwg.org/specs/rfc8470.html
[RFC9163]
E. Stark. Expect-CT Extension for HTTP. June 2022. Experimental. URL: https://www.rfc-editor.org/rfc/rfc9163

IDL Index

typedef (sequence<sequence<ByteString>> or record<ByteString, ByteString>) HeadersInit;

[Exposed=(Window,Worker)]
interface Headers {
  constructor(optional HeadersInit init);

  undefined append(ByteString name, ByteString value);
  undefined delete(ByteString name);
  ByteString? get(ByteString name);
  sequence<ByteString> getSetCookie();
  boolean has(ByteString name);
  undefined set(ByteString name, ByteString value);
  iterable<ByteString, ByteString>;
};

typedef (Blob or BufferSource or FormData or URLSearchParams or USVString) XMLHttpRequestBodyInit;

typedef (ReadableStream or XMLHttpRequestBodyInit) BodyInit;
interface mixin Body {
  readonly attribute ReadableStream? body;
  readonly attribute boolean bodyUsed;
  [NewObject] Promise<ArrayBuffer> arrayBuffer();
  [NewObject] Promise<Blob> blob();
  [NewObject] Promise<Uint8Array> bytes();
  [NewObject] Promise<FormData> formData();
  [NewObject] Promise<any> json();
  [NewObject] Promise<USVString> text();
};
typedef (Request or USVString) RequestInfo;

[Exposed=(Window,Worker)]
interface Request {
  constructor(RequestInfo input, optional RequestInit init = {});

  readonly attribute ByteString method;
  readonly attribute USVString url;
  [SameObject] readonly attribute Headers headers;

  readonly attribute RequestDestination destination;
  readonly attribute USVString referrer;
  readonly attribute ReferrerPolicy referrerPolicy;
  readonly attribute RequestMode mode;
  readonly attribute RequestCredentials credentials;
  readonly attribute RequestCache cache;
  readonly attribute RequestRedirect redirect;
  readonly attribute DOMString integrity;
  readonly attribute boolean keepalive;
  readonly attribute boolean isReloadNavigation;
  readonly attribute boolean isHistoryNavigation;
  readonly attribute AbortSignal signal;
  readonly attribute RequestDuplex duplex;

  [NewObject] Request clone();
};
Request includes Body;

dictionary RequestInit {
  ByteString method;
  HeadersInit headers;
  BodyInit? body;
  USVString referrer;
  ReferrerPolicy referrerPolicy;
  RequestMode mode;
  RequestCredentials credentials;
  RequestCache cache;
  RequestRedirect redirect;
  DOMString integrity;
  boolean keepalive;
  AbortSignal? signal;
  RequestDuplex duplex;
  RequestPriority priority;
  any window; // can only be set to null
};

enum RequestDestination { "", "audio", "audioworklet", "document", "embed", "font", "frame", "iframe", "image", "json", "manifest", "object", "paintworklet", "report", "script", "sharedworker", "style",  "track", "video", "worker", "xslt" };
enum RequestMode { "navigate", "same-origin", "no-cors", "cors" };
enum RequestCredentials { "omit", "same-origin", "include" };
enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" };
enum RequestRedirect { "follow", "error", "manual" };
enum RequestDuplex { "half" };
enum RequestPriority { "high", "low", "auto" };

[Exposed=(Window,Worker)]interface Response {
  constructor(optional BodyInit? body = null, optional ResponseInit init = {});

  [NewObject] static Response error();
  [NewObject] static Response redirect(USVString url, optional unsigned short status = 302);
  [NewObject] static Response json(any data, optional ResponseInit init = {});

  readonly attribute ResponseType type;

  readonly attribute USVString url;
  readonly attribute boolean redirected;
  readonly attribute unsigned short status;
  readonly attribute boolean ok;
  readonly attribute ByteString statusText;
  [SameObject] readonly attribute Headers headers;

  [NewObject] Response clone();
};
Response includes Body;

dictionary ResponseInit {
  unsigned short status = 200;
  ByteString statusText = "";
  HeadersInit headers;
};

enum ResponseType { "basic", "cors", "default", "error", "opaque", "opaqueredirect" };

partial interface mixin WindowOrWorkerGlobalScope {
  [NewObject] Promise<Response> fetch(RequestInfo input, optional RequestInit init = {});
};

MDN

Headers/Headers

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js18.0.0+
MDN

Headers/append

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js18.0.0+
MDN

Headers/delete

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js18.0.0+
MDN

Headers/get

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js18.0.0+
MDN

Headers/getSetCookie

In all current engines.

Firefox112+Safari17+Chrome113+
Opera?Edge113+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js19.7.0+
MDN

Headers/has

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js18.0.0+
MDN

Headers/set

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js18.0.0+
MDN

Headers

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js18.0.0+
MDN

Request/Request

In all current engines.

Firefox39+Safari10.1+Chrome40+
Opera27+Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile27+
MDN

Request/arrayBuffer

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?

Response/arrayBuffer

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/blob

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?

Response/blob

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/body

FirefoxNoneSafari11.1+Chrome105+
Opera?Edge105+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?

Response/body

In all current engines.

Firefox65+Safari10.1+Chrome43+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/bodyUsed

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?

Response/bodyUsed

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/cache

In all current engines.

Firefox48+Safari10.1+Chrome64+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/clone

In all current engines.

Firefox39+Safari10.1+Chrome40+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/credentials

In all current engines.

Firefox39+Safari10.1+Chrome40+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/destination

In all current engines.

Firefox61+Safari10.1+Chrome65+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/formData

In all current engines.

Firefox39+Safari14.1+Chrome60+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?

Response/formData

In all current engines.

Firefox39+Safari14.1+Chrome60+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/headers

In all current engines.

Firefox39+Safari10.1+Chrome40+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/integrity

In all current engines.

Firefox51+Safari10.1+Chrome46+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/json

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?

Response/json

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/method

In all current engines.

Firefox39+Safari10.1+Chrome40+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/mode

In all current engines.

Firefox39+Safari10.1+Chrome40+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/redirect

In all current engines.

Firefox43+Safari10.1+Chrome46+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/referrer

In all current engines.

Firefox39+Safari10.1+Chrome40+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/referrerPolicy

In all current engines.

Firefox47+Safari10.1+Chrome52+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet7.2+Opera Mobile?
MDN

Request/signal

In all current engines.

Firefox57+Safari12.1+Chrome66+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/text

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?

Response/text

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Request/url

In all current engines.

Firefox39+Safari10.1+Chrome40+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile27+
MDN

Request

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js18.0.0+
MDN

Response/Response

In all current engines.

Firefox39+Safari10.1+Chrome40+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Response/clone

In all current engines.

Firefox39+Safari10.1+Chrome40+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Response/error_static

In all current engines.

Firefox39+Safari10.1+Chrome43+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Response/headers

In all current engines.

Firefox39+Safari10.1+Chrome40+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Response/json_static

Firefox115+SafariNoneChrome105+
Opera?Edge105+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Response/ok

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Response/redirect_static

In all current engines.

Firefox39+Safari10.1+Chrome44+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Response/redirected

In all current engines.

Firefox49+Safari10.1+Chrome57+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView60+Samsung Internet8.0+Opera Mobile?
MDN

Response/status

In all current engines.

Firefox39+Safari10.1+Chrome40+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Response/statusText

In all current engines.

Firefox39+Safari10.1+Chrome40+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Response/type

In all current engines.

Firefox39+Safari10.1+Chrome40+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Response/url

In all current engines.

Firefox39+Safari10.1+Chrome40+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Response

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js18.0.0+
MDN

fetch

In all current engines.

Firefox39+Safari10.1+Chrome42+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js18.0.0+
MDN

Headers/Access-Control-Allow-Credentials

In all current engines.

Firefox3.5+Safari4+Chrome4+
Opera12+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for AndroidYesAndroid WebView2+Samsung Internet?Opera Mobile12+
MDN

Headers/Access-Control-Allow-Headers

In all current engines.

Firefox3.5+Safari4+Chrome4+
Opera12+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for AndroidYesAndroid WebView2+Samsung Internet?Opera Mobile12+
MDN

Headers/Access-Control-Allow-Methods

In all current engines.

Firefox3.5+Safari4+Chrome4+
Opera12+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for AndroidYesAndroid WebView2+Samsung Internet?Opera Mobile12+
MDN

Headers/Access-Control-Allow-Origin

In all current engines.

Firefox3.5+Safari4+Chrome4+
Opera12+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for AndroidYesAndroid WebView2+Samsung Internet?Opera Mobile12+
MDN

Headers/Access-Control-Expose-Headers

In all current engines.

Firefox3.5+Safari4+Chrome4+
Opera12+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for AndroidYesAndroid WebView2+Samsung Internet?Opera Mobile12+
MDN

Headers/Access-Control-Max-Age

In all current engines.

Firefox3.5+Safari4+Chrome4+
Opera12+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for AndroidYesAndroid WebView2+Samsung Internet?Opera Mobile12+
MDN

Headers/Access-Control-Request-Headers

In all current engines.

Firefox3.5+Safari4+Chrome4+
Opera12+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for AndroidYesAndroid WebView2+Samsung Internet?Opera Mobile12+
MDN

Headers/Access-Control-Request-Method

In all current engines.

Firefox3.5+Safari4+Chrome4+
Opera12+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for AndroidYesAndroid WebView2+Samsung Internet?Opera Mobile12+
MDN

Headers/Cross-Origin-Resource-Policy

In all current engines.

Firefox74+Safari12+Chrome73+
OperaNoneEdge79+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS Safari?Chrome for Android?Android WebView?Samsung Internet11.0+Opera MobileNone
MDN

Headers/Origin

In all current engines.

Firefox70+SafariYesChromeYes
Opera?EdgeYes
Edge (Legacy)12+IEYes
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Headers/Sec-Purpose

In only one current engine.

Firefox115+SafariNoneChromeNone
Opera?EdgeNone
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera MobileNone
MDN

Headers/X-Content-Type-Options

In all current engines.

Firefox50+Safari11+Chrome64+
OperaYesEdge79+
Edge (Legacy)12+IE8+
Firefox for Android?iOS Safari?Chrome for Android64+Android WebView?Samsung Internet?Opera MobileYes