Fetch

現行標準 — 最終更新

参加方法:
GitHub whatwg/fetch新しいissueオープン中のissue
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、JavaScript APIであるnavigator.sendBeacon()self.importScripts()などです。Fetch標準は、これらの機能について統一的なアーキテクチャを提供し、リダイレクトやCORSプロトコルなどフェッチに関する様々な側面で一貫性を持たせます。

Fetch標準はまた、ほとんどのネットワーク機能を比較的低レベルの抽象化で公開するfetch() JavaScript APIも定義します。

2. インフラストラクチャー

本仕様はInfra標準に依存します。[INFRA]

本仕様では、ABNFEncodingHTMLHTTPMIME SniffingStreamsURLWeb IDLWebSocketsの用語を使用します。 [ABNF] [ENCODING] [HTML] [HTTP] [MIMESNIFF] [STREAMS] [URL] [WEBIDL] [WEBSOCKETS]

ABNF とは、HTTPによって拡張されたABNF(特に#の追加)およびRFC 7405を意味します。[RFC7405]


認証情報 とは、HTTPクッキー、TLSクライアント証明書、および認証エントリ(HTTP認証用)を指します。[COOKIES] [TLS] [HTTP]


fetch params は、構造体であり、 fetchアルゴリズムで帳簿管理の詳細として使われます。次の項目を持ちます:

request
request
process request body chunk length (初期値 null)
process request end-of-body(初期値 null)
process early hints response(初期値 null)
process response(初期値 null)
process response end-of-body(初期値 null)
process response consume body(初期値 null)
nullまたはアルゴリズム。
task destination(初期値 null)
null、グローバルオブジェクト、または並列キュー
cross-origin isolated capability(初期値 false)
真偽値。
controller(初期値 新しいfetch controller
fetch controller
timing info
fetch timing info
preloaded response candidate(初期値 null)
null、"pending"、またはresponse

fetch controllerは、 構造体であり、 fetchの呼び出し元が開始後に特定の操作を行うことを可能にします。次の項目を持ちます:

state(初期値 "ongoing")
"ongoing"、"terminated"、または"aborted"。
full timing info(初期値 null)
nullまたはfetch timing info
report timing steps(初期値 null)
nullまたはグローバルオブジェクトを受け取るアルゴリズム。
serialized abort reason(初期値 null)
nullまたはRecordStructuredSerializeの結果)。
next manual redirect steps(初期値 null)
nullまたは何も受け取らないアルゴリズム。

fetch controller controllerに対して、global object globalを与えて、report timingするには:

  1. Assert: controllerreport timing stepsがnullでないことを確認する。

  2. controllerreport timing stepsglobalで呼び出す。

fetch controller controllerに対してprocess the next manual redirectするには:

  1. Assert: controllernext manual redirect stepsが nullでないことを確認する。

  2. controllernext manual redirect stepsを呼び出す。

fetch controller controllerに対してextract full timing infoするには:

  1. Assert: controllerfull timing info がnullでないことを確認する。

  2. controllerfull timing infoを返す。

fetch controller controllerに対して、オプションのerrorabortするには:

  1. controllerstateを"aborted"に設定する。

  2. fallbackErrorを"AbortError" DOMExceptionとする。

  3. errorが与えられなければ、fallbackErrorを設定する。

  4. serializedErrorStructuredSerialize(error)とする。 例外が発生したら、それをキャッチしてserializedErrorStructuredSerialize(fallbackError)とする。

  5. controllerserialized abort reasonserializedErrorを設定する。

nullまたはRecord abortReasonrealm realmを与えて、serialized abort reasonをデシリアライズするには:

  1. fallbackErrorを"AbortError" DOMExceptionとする。

  2. deserializedErrorfallbackErrorとする。

  3. abortReasonがnullでなければ、 deserializedErrorStructuredDeserialize(abortReason, realm)を設定する。 例外が発生したりundefinedを返したら、deserializedErrorfallbackErrorに設定する。

  4. deserializedErrorを返す。

fetch controller controllerに対してterminateするには、controllerstateを "terminated"に設定する。

fetch params fetchParamsは、そのcontrollerstateが "aborted"であれば、abortedである。

fetch params fetchParamsは、そのcontrollerstateが "aborted"または"terminated"であれば、canceledである。

fetch timing infoは、 構造体であり、 Resource TimingNavigation Timingで必要なタイミング情報を保持します。次の項目を持ちます: [RESOURCE-TIMING] [NAVIGATION-TIMING]

start time(初期値 0)
redirect start time(初期値 0)
redirect end time(初期値 0)
post-redirect start time(初期値 0)
final service worker start time (初期値 0)
final network-request start time (初期値 0)
first interim network-response start time(初期値 0)
final network-response start time (初期値 0)
end time(初期値 0)
DOMHighResTimeStamp
final connection timing info(初期値 null)
nullまたはconnection timing info
server-timing headers(初期値 « »)
文字列のリスト
render-blocking(初期値 false)
真偽値。

response body info は、構造体であり、 Resource TimingNavigation Timingで必要な情報を保持します。次の項目を持ちます: [RESOURCE-TIMING] [NAVIGATION-TIMING]

encoded size (初期値 0)
decoded size (初期値 0)
数値。
content type(初期値 空文字列)
ASCII文字列
content encoding(初期値 空文字列)
ASCII文字列

fetch timing info timingInfoを与えてopaque timing infoを作成するには、 timingInfostart timeおよび post-redirect start timetimingInfostart timeとなる 新しいfetch timing infoを返す。

アルゴリズムalgorithmグローバルオブジェクトまたは並列キュー taskDestinationを与えてfetchタスクをキューするには、次の手順を実行する:

  1. taskDestination並列キューであれば、 enqueue algorithmtaskDestinationへ。

  2. それ以外の場合、グローバルタスクをキューする。networking task sourcetaskDestinationおよびalgorithmとともに。


整数を直列化するには、最も短い10進数の文字列として表現する。

これは今後、Infraでより詳細なアルゴリズムに置き換えられます。詳しくは infra/201を参照してください。

2.1. URL

ローカルスキームは 「about」、「blob」、または 「data」です。

URLは、そのスキームローカルスキームであれば、 ローカルです。

この定義はReferrer Policyでも使用されています。[REFERRER]

HTTP(S)スキームは 「http」または 「https」です。

fetchスキームは 「about」、「blob」、 「data」、「file」、またはHTTP(S)スキームです。

HTTP(S)スキームおよびfetchスキームHTMLでも使われます。 [HTML]

2.2. HTTP

フェッチはHTTPだけでなくより広い概念を含みますが、多くの概念をHTTPから借用し、それらを他の手段(例:data URL)で取得したリソースにも適用します。

HTTPタブまたはスペースは U+0009 TAB または U+0020 SPACE です。

HTTP空白はU+000A LF、U+000D CR、またはHTTPタブまたはスペースです。

HTTP空白は、HTTPヘッダー以外の文脈(例:MIMEタイプ)で再利用される特定の構文だけに役立ちます。HTTPヘッダー値ではHTTPタブまたはスペースの使用が推奨され、それ以外の文脈ではASCII空白の方が好まれます。ASCII空白とは異なり、U+000C FFは除外されます。

HTTP改行バイトは 0x0A (LF) または 0x0D (CR) です。

HTTPタブまたはスペースバイトは 0x09 (HT) または 0x20 (SP) です。

HTTP空白バイトは、HTTP改行バイトまたは HTTPタブまたはスペースバイトです。

文字列 input位置変数 position、および省略可能な真偽値extract-value(初期値はfalse)を与えて HTTP引用文字列を収集するには、次の手順を実行する:

  1. positionStartpositionとする。

  2. valueを空文字列とする。

  3. Assertinputposition符号位置が U+0022 (") であること。

  4. positionを1進める。

  5. 無限ループ:

    1. positionからU+0022 (") または U+005C (\) でない符号位置の列を収集し、その結果をvalueに追加する。

    2. positioninputの末尾を過ぎていれば break

    3. quoteOrBackslashinputposition符号位置とする。

    4. positionを1進める。

    5. quoteOrBackslashがU+005C (\) なら:

      1. positioninputの末尾を過ぎていれば、U+005C (\) をvalueに追加しbreak

      2. inputposition符号位置valueに追加する。

      3. positionを1進める。

    6. それ以外の場合:

      1. AssertquoteOrBackslashはU+0022 (") であること。

      2. break

  6. extract-valueがtrueなら、valueを返す。

  7. inputpositionStartからpositionまでの符号位置を返す。

入力 出力 extract-valueがtrueの場合の出力 最終的な位置変数の値
""\" ""\" "\" 2
""Hello" World" ""Hello"" "Hello" 7
""Hello \\ World\""" ""Hello \\ World\""" "Hello \ World"" 18

これらの例では位置変数は常に0から開始します。

2.2.1. メソッド

メソッドとは、バイト列であり、 methodトークン生成規則に一致するものです。

CORSセーフリストメソッドとは、 メソッドのうち、 `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では一般的に、ヘッダーを「フィールド」または「ヘッダーフィールド」と呼びます。ウェブプラットフォームでは、より口語的な「ヘッダー」という用語が使われます。[HTTP]

ヘッダーリストとは、ゼロ個以上のリストであり、 ヘッダーから成ります。初期値は « » です。

ヘッダーリストは本質的に特殊なマルチマップ、すなわち重複するキーを持つ可能性のある順序付きキー・バリューのリストです。`Set-Cookie`以外のヘッダーは常にクライアントサイドJavaScriptに公開される際に結合されるため、実装はより効率的な表現を選択しても問題ありませんが、`Set-Cookie`ヘッダー用の関連するデータ構造はサポートする必要があります。

ヘッダー名nameと文字列typeヘッダーリスト listから与えて、 構造化フィールド値を取得 するには、次の手順を実行します。返り値はnullまたは構造化フィールド値です。

  1. Assert: typeは"dictionary"、"list"、"item"のいずれかであること。

  2. valuelistからname取得した結果を格納する。

  3. valueがnullなら、nullを返す。

  4. resultinput_stringvalueheader_typetypeとしてstructured fieldsをパースした結果を格納する。

  5. パースに失敗した場合、nullを返す。

  6. resultを返す。

構造化フィールド値の取得は、ヘッダーが存在しない場合と、そののパースが 構造化フィールド値として失敗した場合を区別しません。これによりウェブプラットフォーム全体で一貫した処理が保証されます。

タプルヘッダー名 name構造化フィールド値 structuredValue)と ヘッダーリスト listを与えて 構造化フィールド値を設定するには:

  1. serializedValuestructured fieldsのシリアライズアルゴリズムをstructuredValueに対して実行した結果を格納する。

  2. 設定name, serializedValue)を listに行う。

構造化フィールド値はHTTPが(将来的に)興味深く効率的な方法でシリアライズできるオブジェクトとして定義されています。現時点では、Fetchはヘッダー値バイト列としてのみサポートしているため、これらのオブジェクトはシリアライズを通じてのみ ヘッダーリストに設定でき、 パースによってのみヘッダーリストから取得できます。将来的にはこれらがエンドツーエンドでオブジェクトとして保持される可能性があります。[RFC9651]


ヘッダーリスト listヘッダー名 name含むのは、 list含むとき、ヘッダーであって、 その名前バイト大小区別なしnameと一致する場合です。

ヘッダー名 nameヘッダーリスト listから 取得するには、次の手順を実行する。返り値はnullまたはヘッダー値

  1. list含まない場合、nullを返す。

  2. list内の、ヘッダー名前バイト大小区別なしnameと一致するものすべての を、0x2C 0x20で区切って順番通りに返す。

ヘッダー名 nameヘッダーリスト listから 取得・デコード・分割するには、次の手順を実行する。返り値はnullまたは文字列のリスト

  1. valueに、listからname取得した結果を格納する。

  2. valueがnullなら、nullを返す。

  3. value取得・デコード・分割した結果を返す。

取得・デコード・分割が、`A`をname引数として実際にどのように動作するかを示します:

ヘッダー(ネットワーク上) 出力
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. inputvalueisomorphic decodeした結果を格納する。

  2. positioninput位置変数として、先頭位置に設定する。

  3. values文字列のリストとして初期化する(初期値 « »)。

  4. temporaryValueを空文字列とする。

  5. 無限ループ:

    1. positionからU+0022 (") または U+002C (,) でない符号位置の列を収集し、その結果をtemporaryValueに追加する。

      この結果は空文字列でもよい。

    2. positioninputの末尾を過ぎておらず、かつinputposition符号位置がU+0022 (")なら:

      1. inputpositionHTTP引用文字列を収集し、その結果をtemporaryValueに追加する。

      2. positionがまだ末尾を過ぎていなければcontinue
    3. temporaryValueの先頭および末尾からすべてのHTTPタブまたはスペースを除去する。

    4. 追加 temporaryValuevaluesに。

    5. temporaryValueを空文字列に戻す。

    6. positioninputの末尾を過ぎていれば、valuesを返す。

    7. Assertinputposition符号位置はU+002C (,)であること。

    8. positionを1だけ進める。

祝福された呼び出し箇所以外では、このアルゴリズムは直接呼び出してはいけません。代わりに取得・デコード・分割を使ってください。

ヘッダー (name, value) をヘッダーリスト list追加するには:

  1. listname含む場合、nameを最初に該当するヘッダー名前に設定する。

    これによって、既存のヘッダー名前の大文字・小文字が再利用されます。複数一致する場合、すべてのヘッダー名前は同一になります。

  2. 追加 (name, value) をlistに。

ヘッダー名 nameヘッダーリスト listから削除するには、 削除 ヘッダーすべて(名前バイト大小区別なしnameと一致するもの)をlistから取り除く。

ヘッダー (name, value) をヘッダーリスト list設定するには:

  1. listname含む場合、最初の該当ヘッダーvalueに設定し、他の該当ヘッダーは削除する。

  2. それ以外の場合、追加 (name, value) をlistに。

ヘッダー (name, value) をヘッダーリスト list結合するには:

  1. listname含む場合、最初の該当ヘッダーの後ろに0x2C 0x20を挟んでvalueを追加する。

  2. それ以外の場合、追加 (name, value) をlistに。

結合XMLHttpRequest および WebSocketプロトコルハンドシェイクで使われます。

名前のリスト headerNamesを与えてソート済み小文字集合へ変換するには、次の手順を実行する。返り値は順序付き集合ヘッダー名)。

  1. headerNamesSetを新しい順序付き集合とする。

  2. headerNamesnameについて、追加として、バイト小文字化したnameheaderNamesSetに加える。

  3. 昇順ソートheaderNamesSetに対してバイト小なりで行い、その結果を返す。

ヘッダーリスト listソートおよび結合するには、次の手順を実行する。返り値はヘッダーリスト

  1. headersヘッダーリストとして初期化する。

  2. namesに、list内の全名前ソート済み小文字集合へ変換した結果を格納する。

  3. namesnameについて:

    1. nameが`set-cookie`なら:

      1. valueslist内でnameバイト大小区別なしで一致するヘッダーすべてのを順番通り格納するリストとする。

      2. valuesvalueについて:

        1. 追加 (name, value) をheadersに。

    2. それ以外の場合:

      1. valuelistからname取得した結果を格納する。

      2. Assertvalueはnullでないこと。

      3. 追加 (name, value) をheadersに。

  4. headersを返す。


ヘッダーは、タプルであり、 名前ヘッダー名)と ヘッダー値)から構成されます。

ヘッダー名は、バイト列であり、 field-nameトークン生成規則に一致するものです。

ヘッダー値は、バイト列であり、次の条件を満たすものです。

ヘッダー値の定義は、field-valueトークン生成規則に基づいていません。これは既存のコンテンツとの非互換性があるためです。

バイト列 potentialValue正規化するには、potentialValueから先頭および末尾のHTTP空白バイトを除去する。


ヘッダーname, value)がCORSセーフリストリクエストヘッダーかどうかを判定するには、次の手順を実行する:

  1. value長さが128より大きい場合、falseを返す。

  2. バイト小文字化したnameで次の分岐を行う:

    `accept`

    valueCORS-unsafeリクエストヘッダーバイトが含まれていれば、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. valueCORS-unsafeリクエストヘッダーバイトが含まれていれば、falseを返す。

    2. mimeTypeMIMEタイプのパースisomorphic decodeしたvalueに対して行った結果を格納する。

    3. mimeTypeがfailureならfalseを返す。

    4. mimeTypeessenceが "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がfailureならfalseを返す。

    3. rangeValue[0]がnullならfalseを返す。

      ウェブブラウザは歴史的に `bytes=-500` のようなレンジは出さないため、このアルゴリズムはそれらをセーフリスト化しません。

    その他

    falseを返す。

  3. trueを返す。

`Content-Type`ヘッダーのセーフリストには限定的な例外があり、CORSプロトコルの例外に記載されています。

CORS-unsafeリクエストヘッダーバイトとは、バイトbyteが次のいずれかに該当する場合です:

CORS-unsafeリクエストヘッダー名は、ヘッダーリスト headersに対して次の手順で決定します:

  1. unsafeNamesを新しいリストとする。

  2. potentiallyUnsafeNamesを新しいリストとする。

  3. safelistValueSizeを0とする。

  4. headersheader について:

    1. headerCORSセーフリストリクエストヘッダーでなければ、appendheader名前unsafeNamesに加える。

    2. それ以外の場合、appendheader名前potentiallyUnsafeNamesに加え、safelistValueSizeheader長さを加算する。

  5. safelistValueSizeが1024より大きければ、 potentiallyUnsafeNamesnameについて、appendnameunsafeNamesに加える。

  6. ソート済み小文字集合へ変換したunsafeNamesを返す。

CORSノンワイルドカードリクエストヘッダー名は、ヘッダー名であり、バイト大小区別なしで`Authorization`と一致するものです。

特権no-CORSリクエストヘッダー名は、ヘッダー名であり、 バイト大小区別なしで以下のいずれかと一致するものです。

これらは特権APIによって設定できるヘッダーであり、関連するリクエストオブジェクトがコピーされた場合は保持されますが、非特権APIによってリクエストが変更された場合には削除されます。

`Range`ヘッダーは、ダウンロードメディアの取得によく使われます。

特定のリクエストにRangeヘッダーを追加するためのヘルパーも用意されています。

CORSセーフリストレスポンスヘッダー名は、リスト ヘッダー名 list を与えて、以下のいずれかにバイト大小区別なしで一致するヘッダー名です。

no-CORSセーフリストリクエストヘッダー名は、ヘッダー名であり、 バイト大小区別なしで以下のいずれかと一致するものです。

ヘッダーname, value)がno-CORSセーフリストリクエストヘッダーかどうかを判定するには、次の手順を実行します:

  1. nameno-CORSセーフリストリクエストヘッダー名でなければfalseを返す。

  2. name, value)がCORSセーフリストリクエストヘッダーかどうかを返す。

ヘッダーname, value)が禁止リクエストヘッダーかどうかは、次の手順でtrueなら該当します:

  1. nameが、次のいずれかにバイト大小区別なしで一致すればtrueを返す:

    該当すればtrueを返す。

  2. nameバイト小文字化し、`proxy-`または`sec-`で始まる場合、trueを返す。

  3. nameが、次のいずれかにバイト大小区別なしで一致すれば:

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

    その場合:

    1. parsedValues取得・デコード・分割したvalueの結果を格納する。

    2. parsedValuesmethodについて、 そのisomorphic encode禁止メソッドであればtrueを返す。

  4. falseを返す。

これらはユーザーエージェントが完全に制御できるようにするために禁止されています。

ヘッダー名が`Sec-`で始まるものは、新しいヘッダーをAPIで開発者が制御できるfetch系API(例:XMLHttpRequest)で安全に追加できるように予約されています。[XHR]

`Set-Cookie`ヘッダーは意味的にはレスポンスヘッダーであり、リクエストには不要です。また、`Set-Cookie`ヘッダーは結合できないため、Headersオブジェクトではより複雑な処理が必要となります。ここで禁止することで、この複雑さがリクエストに漏れないようにしています。

禁止レスポンスヘッダー名は、ヘッダー名であり、バイト大小区別なしで以下のいずれかに一致するものです。

リクエストボディヘッダー名は、ヘッダー名であり、バイト大小区別なしで以下のいずれかに一致するものです。


ヘッダー headerに対してヘッダー値を抽出するには次の手順を実行します:

  1. headerを、そのheader名前に該当するABNFでパースして失敗したらfailureを返す。

  2. headerを、そのheader名前に該当するABNFでパースした結果の1つ以上の値を返す。

ヘッダー名 nameヘッダーリスト listを与えてヘッダーリスト値を抽出するには次の手順を実行します:

  1. listname含まない場合、nullを返す。

  2. nameに該当するABNFが単一のヘッダーしか許可しない場合、かつlistが複数含む場合はfailureを返す。

    異なるエラー処理が必要な場合は、先に必要なヘッダーを抽出してください。

  3. valuesを空のリストとする。

  4. listnameヘッダーを含む各headerについて:

    1. extractheaderからヘッダー値を抽出した結果を格納する。

    2. extractがfailureならfailureを返す。

    3. extract内の各を順番にvaluesへ追加する。

  5. valuesを返す。

整数rangeStart、整数rangeEnd、整数fullLengthを与えてコンテンツレンジを構築するには、次の手順を実行します:

  1. contentRangeを`bytes `とする。

  2. rangeStart直列化し、isomorphic encodeしてcontentRangeに追加する。

  3. 0x2D (-) をcontentRangeに追加する。

  4. rangeEnd直列化し、isomorphic encodeしてcontentRangeに追加する。

  5. 0x2F (/) をcontentRangeに追加する。

  6. fullLength直列化し、isomorphic encodeしてcontentRangeに追加する。

  7. contentRangeを返す。

バイト列 valueと真偽値allowWhitespaceを与えて単一レンジヘッダー値のパースを行うには、次の手順を実行します:

  1. datavalueisomorphic decodeした結果を格納する。

  2. dataが"bytes"で始まらない場合、failureを返す。

  3. positiondataの5番目の符号位置を指す位置変数として初期化する。

  4. allowWhitespaceがtrueなら、HTTPタブまたはスペースdatapositionから収集する。

  5. positiondataにおける符号位置がU+003D (=)でなければfailureを返す。

  6. positionを1進める。

  7. allowWhitespaceがtrueなら、HTTPタブまたはスペースdatapositionから収集する。

  8. rangeStartdatapositionからASCII数字の列を収集した結果を格納する。

  9. rangeStartValuerangeStartが空でなければ10進数として解釈した値を、空ならnullを格納する。

  10. allowWhitespaceがtrueなら、HTTPタブまたはスペースdatapositionから収集する。

  11. positiondataにおける符号位置がU+002D (-)でなければfailureを返す。

  12. positionを1進める。

  13. allowWhitespaceがtrueなら、HTTPタブまたはスペースdatapositionから収集する。

  14. rangeEnddatapositionからASCII数字の列を収集した結果を格納する。

  15. rangeEndValuerangeEndが空でなければ10進数として解釈した値を、空ならnullを格納する。

  16. positiondataの末尾を過ぎていなければfailureを返す。

  17. rangeEndValuerangeStartValueが両方nullならfailureを返す。

  18. rangeStartValuerangeEndValueが数値で、rangeStartValuerangeEndValueより大きければfailureを返す。

  19. (rangeStartValue, rangeEndValue)を返す。

    rangeのendまたはstartは省略可能であり、`bytes=0-`や`bytes=-500`も有効なレンジです。

単一レンジヘッダー値のパースは許可されるレンジヘッダー値の一部でしか成功しませんが、ユーザーエージェントがメディアやダウンロード再開時に使用する最も一般的な形式です。この形式のレンジヘッダー値はRangeヘッダーを追加で設定できます。


デフォルト`User-Agent`値は、`User-Agent`ヘッダーに対する実装依存ヘッダー値です。

ドキュメント`Accept`ヘッダー値は `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8`です。

2.2.3. ステータス

ステータスは、0から999までの整数です。

HTTP/1のstatus-codeをこの概念にマッピングする際の様々な端ケースについては、issue #1156で対応中です。

nullボディステータスは、 ステータスが101、103、204、205、または304の場合です。

OKステータスは、ステータスが200から299までの範囲の場合です。

リダイレクトステータスは、ステータスが301、302、303、307、または308の場合です。

2.2.4. ボディ

ボディは次の要素から成ります:

ボディ body複製するには、次の手順を実行します:

  1. « out1, out2 »をbodyストリームに対してteeした結果とする。

  2. bodyストリームout1に設定する。

  3. 他のメンバーはbodyからコピーし、ボディstreamout2のものを返す。

バイト列 bytesボディとして取得するには、安全に抽出したbytesボディを返す。


ボディ body逐次的に読み込むには、アルゴリズムprocessBodyChunk、アルゴリズムprocessEndOfBody、アルゴリズムprocessBodyError、および省略可能なnull/並列キューまたはグローバルオブジェクト taskDestination(デフォルトnull)を与えて、次の手順を実行します。 processBodyChunkバイト列を受け取るアルゴリズム、processEndOfBodyは引数なしアルゴリズム、processBodyErrorは例外を受け取るアルゴリズムでなければなりません。

  1. taskDestinationがnullなら、新しい並列キューの開始の結果をtaskDestinationに設定する。

  2. readerbodyストリームに対してリーダーの取得を実行した結果を格納する。

    この操作で例外はスローされません。

  3. 逐次読み込みループreadertaskDestinationprocessBodyChunkprocessEndOfBodyprocessBodyErrorで実行する。

ReadableStreamDefaultReader オブジェクトreader並列キューまたはグローバルオブジェクト taskDestination、アルゴリズムprocessBodyChunk、アルゴリズムprocessEndOfBody、アルゴリズムprocessBodyErrorを与えて逐次読み込みループを実行するには:

  1. readRequestを次の読取リクエストとする:

    chunk stepschunkを与えて)
    1. continueAlgorithmをnullとする。

    2. chunkUint8Array オブジェクトでなければ、continueAlgorithmを「processBodyErrorTypeErrorを与えて実行する」に設定する。

    3. それ以外の場合:

      1. byteschunkコピーを格納する。

        実装側は可能な限りこのコピーを避ける戦略を推奨します。

      2. continueAlgorithmを次の手順に設定する:

        1. processBodyChunkbytesを与えて実行する。

        2. 逐次読み込みループreadertaskDestinationprocessBodyChunkprocessEndOfBodyprocessBodyErrorで実行する。

    4. fetchタスクをキューcontinueAlgorithmtaskDestinationを与えて実行する。

    close steps
    1. fetchタスクをキューprocessEndOfBodytaskDestinationを与えて実行する。

    error stepseを与えて)
    1. fetchタスクをキューprocessBodyErroreを与え、taskDestinationで実行する。

  2. チャンクの読み取りreaderreadRequestを与えて実行する。

ボディ body完全に読み込むには、アルゴリズムprocessBody、アルゴリズムprocessBodyError、および省略可能なnull/並列キューまたはグローバルオブジェクト taskDestination(デフォルトnull)を与えて、次の手順を実行します。processBodyバイト列を受け取るアルゴリズム、processBodyErrorはオプションで例外を受け取るアルゴリズムでなければなりません。

  1. taskDestinationがnullなら、新しい並列キューの開始の結果をtaskDestinationに設定する。

  2. successStepsバイト列 bytesを受け取り、 fetchタスクをキューprocessBodybytesを与えtaskDestinationで実行する手順とする。

  3. errorStepsを(オプションの例外 exceptionを受け取り) fetchタスクをキューprocessBodyErrorexceptionを与えtaskDestinationで実行する手順とする。

  4. readerbodyストリームに対してリーダーの取得を実行した結果を格納する。例外が発生した場合、errorStepsをその例外で実行し終了する。

  5. 全バイトの読み取りreadersuccessStepserrorStepsを与えて実行する。


型付きボディは、タプルであり、 ボディボディ)と ヘッダー値またはnull)から構成されます。


codingsbytesを与えてコンテンツ符号化の処理を行うには、次の手順を実行します:

  1. codingsがサポートされていなければ、bytesを返す。

  2. HTTPの説明通りにcodingsbytesをデコードした結果(エラーでなければ)を返し、デコードに失敗したらfailureを返す。[HTTP]

2.2.5. リクエスト

この節ではリクエストの詳細な動作を記述します。導入は リクエストのセットアップを参照してください。

fetchの入力はリクエストです。

リクエストには、関連付けられたメソッドメソッド)があります。特に記載がない限り、`GET`です。

これはリダイレクト時にGETへ更新される場合があります。詳細はHTTP fetchを参照。

リクエストには、関連付けられたURLURL)があります。

実装はこれをURLのリストの最初の要素へのポインタとしてもよいです。これはFetchにフックする他仕様の便宜のためだけに独立したフィールドとして提供されています。

リクエストには、関連付けられたローカルURLのみフラグがあります。特に記載がない限り、未設定です。

リクエストには、関連付けられたヘッダーリストヘッダーリスト)があります。特に記載がない限り、« » です。

リクエストには、関連付けられたunsafe-requestフラグがあります。特に記載がない限り、未設定です。

unsafe-requestフラグは、 fetch()XMLHttpRequest などのAPIによって設定され、指定されたメソッドヘッダーリストに基づいて CORSプリフライトフェッチが確実に行われるようにします。 ただし、APIが禁止メソッド禁止リクエストヘッダーを認めない義務から解放されるわけではありません。

リクエストには、関連付けられたボディ(null、バイト列、またはボディ)があります。特に記載がない限り、nullです。

バイト列は、安全に抽出されて早い段階でボディになります。HTTP fetchの一部として、特定のリダイレクトでこのフィールドがnullになる場合があります。


リクエストには、関連付けられたクライアント(nullまたは環境設定オブジェクト)があります。

リクエストには、関連付けられた予約クライアント(null、環境、または環境設定オブジェクト)。特に記載がない限り、nullです。

これはナビゲーションリクエストやワーカーリクエストのみで使われ、サービスワーカリクエストでは使われません。ナビゲーションリクエストでは環境、ワーカーリクエストでは環境設定オブジェクトを参照します。

リクエストには、関連付けられたクライアント置換ID(文字列)があります。特に記載がない限り、空文字列です。

これはナビゲーションリクエストでのみ使われます。IDは、ターゲット閲覧コンテキストアクティブドキュメント環境設定オブジェクトのIDです。

リクエストには、関連付けられたユーザプロンプト用トラバーサブルがあり、 "no-traversable"、"client"、またはトラバーサブルナビゲーブルです。特に記載がない限り"client"です。

これは、認証プロンプトやクライアント証明書ダイアログなど、リクエストに関連するUIを表示するか、どこに表示するかを決定するために使われます。

"no-traversable"
UIは表示されません。通常、このリクエストはネットワークエラーで失敗します。
"client"
この値は、トラバーサブルナビゲーブルまたは"no-traversable"にfetch処理中に自動的に変更されます。これによって他の標準仕様が明示的に設定しなくても済みます。
トラバーサブルナビゲーブル
表示されるUIは、そのトラバーサブルナビゲーブルを表示しているブラウザインターフェース要素に関連付けられます。

リクエストに関連するユーザーインターフェースをそのリクエストのユーザプロンプト用トラバーサブルで表示する場合、ユーザーエージェントはアドレスバーをリクエストの現在のURLに由来する値(例えば、リクエストの発起元のURLではなく)で更新すべきです。また、特にクロスオリジンリクエストの場合、ユーザーエージェントはプロンプトの背後にリクエストの発起元コンテンツを表示しないようにすべきです。このようなプロンプトの背後は空白ページにするのがよいでしょう。これらの指針に従わないと、どのオリジンがプロンプトの責任を持つのかユーザーが混乱します。

リクエストには、関連付けられたboolean型のkeepaliveがあります。特に記載がない限り、falseです。

これは、例えばnavigator.sendBeacon()やHTMLのimg要素のように、リクエストが環境設定オブジェクトより長寿命になることを許可するために使われます。これがtrueの場合、追加の処理要件が課されます。

リクエストには、関連付けられたinitiator typeがあり、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]

リクエストには、関連付けられたservice-workersモードがあり、"all"または"none"です。特に記載がない限り、"all"です。

これは、このフェッチに対してどのサービスワーカーがfetchイベントを受け取るかを決定します。

"all"
関連するサービスワーカーはこのフェッチに対するfetchイベントを受け取ります。
"none"
どのサービスワーカーもこのフェッチに対してイベントを受け取りません。

リクエストには、関連付けられたinitiatorがあり、空文字列、"download"、"imageset"、"manifest"、"prefetch"、"prerender"、または"xslt"のいずれかです。特に記載がない限り空文字列です。

リクエストinitiatorは今のところあまり細かく分かれていません。他の仕様がそれを必要としていないためです。これは主にCSPや混在コンテンツを定義するための仕様上の補助的な属性です。JavaScriptには公開されません。[CSP] [MIX]

destination typeは、空文字列、"audio"、"audioworklet"、"document"、"embed"、"font"、"frame"、"iframe"、"image"、"json"、"manifest"、"object"、"paintworklet"、"report"、"script"、"serviceworker"、"sharedworker"、"style"、"track"、"video"、"webidentity"、"worker"、または"xslt"のいずれかです。

リクエストには、関連付けられたdestinationdestination type)があります。特に記載がない限り空文字列です。

これらはRequestDestinationで反映されますが、"serviceworker"と"webidentity"は該当しません。これらのdestinationではサービスワーカーをスキップします。

リクエストdestinationscript-likeとなるのは、"audioworklet"、"paintworklet"、"script"、"serviceworker"、"sharedworker"、または"worker"の場合です。

script-likeを利用するアルゴリズムは、"xslt"もスクリプト実行の原因となり得るため考慮すべきです。ただし、常に該当するとは限らず異なる動作が必要な場合があるためリストには含まれていません。

次の表は、リクエストinitiatordestination、CSPディレクティブ、および各機能との関係を示しています。機能については網羅的ではありません。各機能は、それぞれの現行標準で関連値を定義する必要があります。

Initiator Destination CSPディレクティブ 機能
"" "report" CSP、NELレポート
"document" HTMLのnavigateアルゴリズム(トップレベルのみ)
"frame" child-src HTMLの<frame>
"iframe" child-src HTMLの<iframe>
"" connect-src navigator.sendBeacon()EventSource、 HTMLの<a ping="">および<area ping="">fetch()fetchLater()XMLHttpRequestWebSocket、 Cache 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 requests
"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のnavigateやフォーム送信アルゴリズムに直接フックする必要があります。

CSPはまた、リクエストクライアントグローバルオブジェクト対応するDocument祖先ナビゲーブルも、さまざまなCSPディレクティブで確認する必要があります。


リクエストには、関連付けられた priorityがあり、"high"、"low"、"auto"のいずれかです。特に記載がない限り"auto"です。

リクエストには、関連付けられた 内部priority(nullまたは 実装依存オブジェクト)があります。特に記載がない限りnullです。

リクエストには、関連付けられた originがあり、 "client"またはオリジンです。特に記載がない限り"client"です。

"client"はオリジンにfetch処理中に変更されます。これにより、他の標準が リクエストoriginを明示的に設定しなくても済みます。

リクエストには、関連付けられた トップレベルナビゲーションinitiatorのoriginがあり、 オリジン またはnullです。特に記載がない限りnullです。

リクエストには、関連付けられた ポリシーコンテナがあり、 "client"またはポリシーコンテナです。特に記載がない限り"client"です。

"client"はポリシーコンテナにfetch処理中に変更されます。これにより、他の標準が リクエストポリシーコンテナを明示的に設定しなくても済みます。

リクエストには、関連付けられた referrerがあり、 "no-referrer"、"client"またはURLです。特に記載がない限り "client"です。

"client"はfetch処理中に"no-referrer"またはURLに変更されます。これにより、他の標準が リクエストreferrerを明示的に設定しなくても済みます。

リクエストには、関連付けられた referrer policyがあり、 referrer policyです。特に記載がない限り空文字列です。[REFERRER]

これは、このリクエストに使うreferrer policyを上書きするために使えます。

リクエストには、関連付けられた modeがあり、 "same-origin"、"cors"、"no-cors"、 "navigate"、または"websocket"です。特に記載がない限り "no-cors"です。

"same-origin"
同一オリジンのURLへのリクエストを保証するために使われます。fetchは、リクエストが同一オリジンURLでない場合、ネットワークエラーを返します。
"cors"
レスポンスタインティングが"cors"に設定されるリクエストの場合、このリクエストをCORSリクエストとし、リソースがCORSプロトコルに対応しなかったり、意図的に不参加の場合はネットワークエラーを返します。
"no-cors"
CORSセーフリストメソッドおよびCORSセーフリストリクエストヘッダーのみ利用可能に制限。成功時はopaque filtered responseを返します。
"navigate"
これは、ドキュメントのナビゲーション時にのみ使われる特別なモードです。
"websocket"
これは、WebSocket接続の確立時にのみ使われる特別なモードです。

デフォルトのリクエストmodeは"no-cors"ですが、新しい機能ではこれを使わないことが強く推奨されます。これは非常に安全ではありません。

リクエストには、関連付けられた use-CORS-preflightフラグがあります。特に記載がない限り、未設定です。

use-CORS-preflightフラグが設定されている場合、CORSプリフライトリクエストとなる条件の一つです。このフラグは、XMLHttpRequestUpload オブジェクトに1つ以上のイベントリスナーが登録されている場合や、リクエストにReadableStream オブジェクトが使用されている場合に設定されます。

リクエストには、関連付けられた credentials modeがあり、 "omit"、"same-origin"、"include"のいずれかです。特に記載がない限り、"same-origin"です。

"omit"
このリクエストから認証情報(credentials)を除外し、レスポンスで送信された認証情報も無視します。
"same-origin"
同一オリジンのURLへのリクエストには認証情報を含め、同一オリジンからのレスポンスの認証情報も利用します。
"include"
常にこのリクエストに認証情報を含め、レスポンスに含まれる認証情報も常に利用します。

リクエストcredentials modeは、認証情報fetch中の流れを制御します。リクエストmodeが"navigate"の場合、そのcredentials modeは"include"とみなされ、fetchは現状他の値を考慮しません。HTML側の仕様変更があれば、この標準も対応が必要です。

リクエストには、関連付けられた use-URL-credentialsフラグがあります。特に記載がない限り、未設定です。

このフラグが設定されている場合、リクエストURLユーザー名パスワードがあり、利用可能な認証エントリがある場合、URLの認証情報が認証エントリより優先されます。URLに認証情報を含めることは推奨されていないため、現行の仕様ではこのフラグを設定しないことが多いですが、互換性のため古い機能で設定される場合があります。

リクエストには、関連付けられた cache modeがあり、 "default"、"no-store"、"reload"、"no-cache"、"force-cache"、"only-if-cached"のいずれかです。特に記載がない限り"default"です。

"default"
Fetchはネットワークに行く前にHTTPキャッシュを確認します。HTTPキャッシュに一致する新鮮なレスポンスがあればそれを返します。一致するstale-while-revalidateレスポンスがあればそれを返しつつ条件付きネットワークリクエストを送りキャッシュを更新します。一致する古いレスポンスがあれば条件付きネットワークリクエストを返します。それ以外は非条件付きネットワークリクエストを返します。[HTTP] [HTTP-CACHING] [STALE-WHILE-REVALIDATE]
"no-store"
FetchはHTTPキャッシュがまったく存在しないかのように動作します。
"reload"
Fetchはネットワークに行く前にHTTPキャッシュがないかのように動作します。つまり、通常のリクエストを作成し、レスポンスでHTTPキャッシュを更新します。
"no-cache"
HTTPキャッシュにレスポンスがあれば条件付きリクエストを作成し、なければ通常のリクエストを作成します。その後レスポンスでHTTPキャッシュを更新します。
"force-cache"
Fetchはリクエストに一致するHTTPキャッシュ内のレスポンスを鮮度に関係なく使用します。なければ通常のリクエストを作成し、レスポンスでキャッシュを更新します。
"only-if-cached"
Fetchはリクエストに一致するHTTPキャッシュ内のレスポンスを鮮度に関係なく使用します。なければネットワークエラーを返します(このモードはリクエストmodeが"same-origin"の場合のみ使用可能)。キャッシュされたリダイレクトはリクエストredirect modeが"follow"で、そのリダイレクトがリクエストmodeに違反しない場合にのみ追従されます。

ヘッダーリスト含む `If-Modified-Since`, `If-None-Match`, `If-Unmodified-Since`, `If-Match`, または `If-Range` のいずれかが含まれる場合、fetchcache modeを"default"なら"no-store"に設定します。

リクエストには、関連付けられた redirect modeがあり、 "follow"、"error"、"manual"のいずれかです。特に記載がない限り"follow"です。

"follow"
リソースのフェッチ時に発生したすべてのリダイレクトを追従します。
"error"
リクエストがリダイレクトに遭遇した場合、ネットワークエラーを返します。
"manual"
サービスワーカーがリダイレクトをオフラインで再現できるよう、リダイレクトに遭遇した際にopaque-redirect filtered responseを返します。それ以外はネットワークエラーと区別できません。atomic HTTPリダイレクト処理に違反しないようにしています。

リクエストには、関連付けられた integrity metadata (文字列)があります。特に記載がない限り、空文字列です。

リクエストには、関連付けられた 暗号ノンスmetadata (文字列)があります。特に記載がない限り、空文字列です。

リクエストには、関連付けられた パーサmetadata (空文字列、"parser-inserted"、または"not-parser-inserted")があります。特に記載がない限り、空文字列です。

リクエスト暗号ノンスmetadataおよびパーサmetadataは、通常、リクエストを生成したHTML要素の属性やフラグから設定されます。これらはContent Security Policyの様々なアルゴリズムで、リクエストやレスポンスが特定のコンテキストでブロックされるかどうかの判定に使われます。[CSP]

リクエストには、関連付けられた reload-navigationフラグがあります。特に記載がない限り、未設定です。

このフラグはHTMLのnavigateアルゴリズム専用です。[HTML]

リクエストには、関連付けられた history-navigationフラグがあります。特に記載がない限り、未設定です。

このフラグはHTMLのnavigateアルゴリズム専用です。[HTML]

リクエストには、関連付けられた boolean型のuser-activationがあります。特に記載がない限り、falseです。

これはHTMLのnavigateアルゴリズム専用です。[HTML]

リクエストには、関連付けられた boolean型のrender-blockingがあります。特に記載がない限り、falseです。

このフラグはHTMLのrender-blockingメカニズム専用です。[HTML]


リクエストには、関連付けられた URLリストURLのリスト)があります。特に記載がない限り、リクエストURLのコピー1つを含むリストです。

リクエストには、関連付けられた 現在のURLがあります。これはリクエストURLリストの最後のURLを指します。

リクエストには、関連付けられた リダイレクトカウントがあります。特に記載がない限り、0です。

リクエストには、関連付けられた レスポンスタインティングがあり、 "basic"、"cors"、"opaque"のいずれかです。特に記載がない限り"basic"です。

リクエストには、関連付けられた prevent no-cache cache-control header modificationフラグがあります。特に記載がない限り、未設定です。

リクエストには、関連付けられた doneフラグがあります。特に記載がない限り、未設定です。

リクエストには、関連付けられた timing allow failedフラグがあります。特に記載がない限り、未設定です。

リクエストURLリスト現在のURLリダイレクトカウントレスポンスタインティングdoneフラグ、およびtiming allow failedフラグは、fetchアルゴリズムの帳簿管理用です。


サブリソースリクエストとは、リクエストであり、そのdestinationが"audio"、"audioworklet"、"font"、"image"、"json"、"manifest"、"paintworklet"、"script"、"style"、"track"、"video"、"xslt"または空文字列の場合です。

非サブリソースリクエストとは、リクエストであり、そのdestinationが"document"、"embed"、"frame"、"iframe"、"object"、"report"、"serviceworker"、"sharedworker"、または"worker"の場合です。

ナビゲーションリクエストとは、リクエストであり、そのdestinationが"document"、"embed"、"frame"、"iframe"、または"object"の場合です。

これらの用語の使われ方は、handle fetchを参照。[SW]


リクエスト requestredirect-taintを計算するには、次の手順を実行します。返り値は"same-origin"、"same-site"、または"cross-site"です。

  1. Assert: requestoriginは"client"ではないこと。

  2. lastURLをnullとする。

  3. taintを"same-origin"とする。

  4. requestURLリストurlについて:

    1. lastURLがnullなら、lastURLurlとし、continue

    2. urloriginlastURLoriginsame siteでなく、かつrequestoriginlastURLsame siteでなければ、"cross-site"を返す。

    3. urloriginlastURLoriginsame originでなく、かつrequestoriginlastURLsame originでなければ、taintを"same-site"とする。

    4. lastURLurlとする。

  5. taintを返す。

request requestに対してリクエストoriginの直列化を行うには、次の手順を実行します:

  1. Assert: requestoriginは"client"ではないこと。

  2. requestredirect-taintが"same-origin"でなければ、"null"を返す。

  3. requestorigin直列化して返す。

request requestに対してリクエストoriginのバイト直列化を行うには、リクエストoriginの直列化の結果をisomorphic encodeしたものを返す。


リクエスト request複製するには、次の手順を実行します:

  1. newRequestrequestのコピー(ただしbodyは除く)とする。

  2. requestbodyがnullでなければ、newRequestbody複製したrequestbodyを設定する。

  3. newRequestを返す。


リクエスト requestに整数first、オプションで整数lastを与えてRangeヘッダーを追加するには、次の手順を実行します:

  1. Assert: lastが与えられていないか、firstlast以下であること。

  2. rangeValueを`bytes=`とする。

  3. 直列化し、isomorphic encodeしたfirstrangeValueに追加する。

  4. 0x2D (-) をrangeValueに追加する。

  5. lastが与えられていれば、それを直列化してisomorphic encodeした結果をrangeValueに追加する。

  6. 追加(`Range`、rangeValue)をrequestヘッダーリストに行う。

Rangeヘッダーはバイト範囲(両端を含む)を表します。たとえば、firstが0、lastが500の場合、501バイトの範囲になります。

複数のレスポンスを1つの論理リソースに結合する機能は、歴史的にセキュリティバグの原因となってきました。部分レスポンスを扱う機能を設計する場合は、必ずセキュリティレビューを受けてください。


response responseに対して報告用レスポンスURLの直列化を行うには、次の手順を実行します:

  1. Assert: responseURLリスト空でないこと。

  2. urlresponseURLリスト[0]のコピーとする。

    これはresponseURLではありません。リダイレクト先の情報漏えいを防ぐためです(CSP報告の同様の考慮事項も参照)。[CSP]

  3. ユーザー名を空文字列に設定する(urlに対して)。

  4. パスワードを空文字列に設定する(urlに対して)。

  5. 直列化したurlを、フラグメント除外をtrueにして返す。

request requestに対してCross-Origin-Embedder-Policyが認証情報を許可するか確認するには、次の手順を実行します:

  1. Assert: requestoriginは"client"ではないこと。

  2. requestmodeが"no-cors"でなければtrueを返す。

  3. requestclientがnullであればtrueを返す。

  4. requestclientポリシーコンテナembedder policyが"credentialless"でなければtrueを返す。

  5. requestoriginrequest現在のURLoriginsame originであり、かつrequestredirect-taintが"same-origin"でなければtrueを返す。

  6. falseを返す。

2.2.6. レスポンス

fetchの結果はレスポンスです。レスポンスは時間とともに変化します。つまり、すべてのフィールドがすぐに利用できるとは限りません。

レスポンスには、関連付けられたtypeがあります。 "basic"、 "cors"、 "default"、 "error"、 "opaque"、または "opaqueredirect"。 特に記載がない限り、"default"です。

レスポンスには、関連付けられたabortedフラグがあります。初期値は未設定です。

これはリクエストが開発者またはエンドユーザーによって意図的に中断されたことを示します。

レスポンスには、関連付けられたURLがあります。これはURLのリストの最後の要素を指します。レスポンスURLリストの場合はnullです。

レスポンスには、関連付けられたURLリストURLのリスト、0個以上)があります。特に記載がない限り、« »です。

1つ目と最後のURL以外は、レスポンスURLリストはスクリプトに直接公開されません。これはアトミックなHTTPリダイレクト処理に反するからです。

レスポンスには、関連付けられたstatusステータス)があります。特に記載がない限り200です。

レスポンスには、関連付けられたstatus messageがあります。特に記載がない限り、空のバイト列です。

HTTP/2接続上のレスポンスは常に空のバイト列をstatus messageとします。HTTP/2ではサポートされていません。

レスポンスには、関連付けられたヘッダーリストヘッダーリスト)があります。特に記載がない限り、« »です。

レスポンスには、関連付けられたボディ(nullまたはボディ)があります。特に記載がない限り、nullです。

ネットワーク由来のレスポンスボディについては、sourceおよびlengthの概念は常にnullです。

レスポンスには、関連付けられたキャッシュ状態(空文字列、"local"、"validated")があります。特に記載がない限り空文字列です。

これはService WorkersResource Timingで使われます。[SW][RESOURCE-TIMING]

レスポンスには、関連付けられたCORS公開ヘッダー名リスト(0個以上のヘッダー名前のリスト)があります。特に記載がない限り空です。

レスポンスCORS公開ヘッダー名リストは通常、`Access-Control-Expose-Headers`ヘッダーからヘッダー値を抽出して設定されます。このリストはCORSフィルタ済みレスポンスが公開するヘッダーを決定するのに使われます。

レスポンスには、関連付けられたrange-requestedフラグがあります。初期値は未設定です。

これは、事前の範囲リクエストによる部分レスポンスが、範囲リクエストを行っていないAPIに提供されるのを防ぐために使われます。攻撃の詳細な説明についてはフラグの使われ方を参照してください。

レスポンスには、関連付けられたrequest-includes-credentials (boolean型)があります。初期値はtrueです。

レスポンスには、関連付けられたtiming allow passedフラグがあります。初期値は未設定です。

これはfetchの呼び出し元が、取得したリソースに対してセンシティブなタイミングデータが許可されているかをレスポンスのフラグで判定できるようにするためです。リダイレクトチェーン上の前のレスポンスでこのフラグが設定されていた場合、リダイレクトされたレスポンスにも引き継がれるため、リクエストのtiming allow failedフラグでも内部追跡されます。

レスポンスには、関連付けられたbody inforesponse body info)があります。特に記載がない限り、新しいresponse body infoです。

レスポンスには、関連付けられたservice worker timing info(nullまたはservice worker timing info)があります。初期値はnullです。

レスポンスには、関連付けられたredirect taint ("same-origin"、"same-site"、"cross-site")があります。初期値は"same-origin"です。


ネットワークエラーとは、レスポンスであり、そのtypeが"error"、statusが0、status messageが空のバイト列、ヘッダーリストが« »、ボディがnull、body infoが新しいresponse body infoであるものです。

中断されたネットワークエラーとは、ネットワークエラーであって、abortedフラグが設定されているものです。

fetch params fetchParamsを与えて適切なネットワークエラーを作るには:

  1. Assert: fetchParamscanceledであること。

  2. fetchParamsabortedなら中断されたネットワークエラーを、それ以外ならネットワークエラーを返す。


フィルタ済みレスポンスとは、関連付けられたレスポンスへの限定的なビューを提供するレスポンスです。この関連するレスポンスは、フィルタ済みレスポンス内部レスポンスネットワークエラーフィルタ済みレスポンスでないレスポンス)としてアクセスできます。

特に記載がない限り、フィルタ済みレスポンスの各概念(例:ボディ)は、内部レスポンスの対応する概念を参照します(例外はこの後、フィルタ済みレスポンスの具体的な型の定義部分で記載)。

fetchアルゴリズムは、processResponseや同等のパラメータを通じて、呼び出し元にフィルタ済みレスポンスを公開し、情報が誤って漏れないようにしています。レガシー理由で情報を公開する必要がある場合(例:デコーダーに画像データを渡す)、内部レスポンスを仕様アルゴリズムで利用できます。

新しい仕様では、opaqueフィルタ済みレスポンスopaque-redirectフィルタ済みレスポンスを拡張しないようにしてください。これらはレガシーな構造であり、現代のコンピュータアーキテクチャにおいて十分に保護できるとは限りません。

basicフィルタ済みレスポンスは、フィルタ済みレスポンスであり、typeが"basic"で、内部レスポンスヘッダーリストに含まれるヘッダーのうち、禁止レスポンスヘッダー名であるものを除外したものです。

CORSフィルタ済みレスポンスは、フィルタ済みレスポンスであり、typeが"cors"で、内部レスポンスヘッダーリストに含まれるヘッダーのうち、CORSセーフリストレスポンスヘッダー名内部レスポンスCORS公開ヘッダー名リストを与える)でないものを除外したものです。

opaqueフィルタ済みレスポンスは、フィルタ済みレスポンスであり、typeが"opaque"、URLリストが« »、statusが0、status messageが空のバイト列、ヘッダーリストが« »、ボディがnull、body infoが新しいresponse body infoです。

opaque-redirectフィルタ済みレスポンスは、 フィルタ済みレスポンスであって、 typeが"opaqueredirect"、 statusが0、 status messageが空のバイト列、 ヘッダーリストが« »、 ボディがnull、 そして body infoが新しい response body info であるものです。

URLリストopaque-redirectフィルタ済みレスポンスで公開しても、リダイレクトは辿られないため問題ありません。

言い換えると、opaqueフィルタ済みレスポンスopaque-redirectフィルタ済みレスポンスネットワークエラーとほとんど区別がつきません。 新しいAPIを導入する際は、内部レスポンスを内部仕様アルゴリズムで使わないでください。情報漏えいにつながります。

これはまた、response.okのようなJavaScript APIの結果がほとんど役に立たないことも意味します。

typeレスポンスtype getterを通じてスクリプトに公開されます:

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. newResponseresponseのコピー(ただしボディを除く)とする。

  3. responseボディがnullでなければ、newResponseボディ複製したresponseボディを設定する。

  4. newResponseを返す。


新鮮なレスポンスは、 レスポンスであって、 現在エージが、その 鮮度寿命以内であるものです。

stale-while-revalidateレスポンスは、 レスポンスであって、 新鮮なレスポンスでなく、 現在エージstale-while-revalidate寿命以内であるものです。 [HTTP-CACHING] [STALE-WHILE-REVALIDATE]

古いレスポンスは、 レスポンスであって、 新鮮なレスポンスでも stale-while-revalidateレスポンスでもないものです。


レスポンス responselocation URLは、 nullまたはASCII文字列 requestFragmentを与えて、 次の手順で決定されます。返り値はnull・failure・またはURLです。

  1. responsestatusリダイレクトステータスでなければnullを返す。

  2. locationヘッダーリスト値を抽出(`Location`・responseヘッダーリスト)の結果とする。

  3. locationヘッダー値なら、 locationパースlocationresponseURL)の結果に置き換える。

    responseResponseコンストラクターで生成された場合、 responseURLはnullとなるため、 location絶対URL+フラグメント文字列でなければパースに成功しません。

  4. locationURLで、 そのfragmentがnullなら、 locationfragmentrequestFragmentを設定する。

    これにより、合成レスポンス(実際には全てのレスポンス)がHTTPで定義されるリダイレクトの処理モデルに従うことが保証されます。[HTTP]

  5. locationを返す。

location URLアルゴリズムは、この標準と、リダイレクトを手動で処理するHTMLのnavigateアルゴリズム専用です。[HTML]

2.2.7. その他

潜在的なdestinationは、"fetch"または空文字列でないdestinationです。

潜在的なdestination potentialDestination変換するには、次の手順を実行します:

  1. potentialDestinationが"fetch"なら空文字列を返す。

  2. Assert: potentialDestinationdestinationであること。

  3. potentialDestinationを返す。

2.3. 認証エントリ

認証エントリおよびプロキシ認証エントリは、ユーザー名・パスワード・レルムからなるタプルであり、HTTP認証およびHTTPプロキシ認証に使われ、1つ以上のリクエストに関連付けられます。

ユーザーエージェントは、認証エントリとHTTPクッキーや同様のトラッキング機能を一括してクリアできるようにすべきです。

詳細はHTTPで定義されています。[HTTP] [HTTP-CACHING]

2.4. Fetchグループ

環境設定オブジェクトには、関連付けられたfetchグループがあり、fetchグループを保持します。

fetchグループは、fetchに関する情報を保持します。

fetchグループには次が関連付けられています:

fetchレコード
fetchレコードのリスト。
遅延fetchレコード
遅延fetchレコードのリスト。

fetchレコードは、次の構造体項目を持ちます:

request
リクエスト
controller
fetchコントローラーまたはnull。

遅延fetchレコードは、後でfetchを呼び出すための状態を保持する構造体であり、例えばドキュメントがunloadされた場合や 完全にアクティブでなくなった場合などに使われます。次の項目を持ちます:

request
リクエスト
notify invoked
引数なしアルゴリズム。
invoke state(初期値"pending")
"pending"、"sent"、または"aborted"。

フェッチグループ fetchGroup終了された場合:

  1. fetchレコード recordについて、 fetchGroupfetchレコードのうち、 recordcontrollerがnullでなく、 recordrequestdoneフラグが未設定で、 keepaliveがfalseの場合、 terminate recordcontroller

  2. 遅延fetchを処理する(fetchGroupに対して)。

2.5. ドメインの解決

(This is a tracking vector.) ネットワークパーティションキー keyオリジン originを与えて オリジンを解決するには、次の手順を実行します:

  1. originhostIPアドレスであれば、 « originhost » を返す。

  2. originhostパブリックスフィックスが"localhost"または"localhost."であれば、 « ::1, 127.0.0.1 » を返す。

  3. originを1つ以上のIPアドレス集合に変換する 実装依存の操作を行う。

    他にも、IPアドレス以外の 接続情報を取得するために他の操作を行うかどうかも 実装依存です。例えば、 originスキームHTTP(S)スキームの場合、実装はHTTPS RRのためのDNSクエリを行うかもしれません。[SVCB]

    この操作が成功した場合、IPアドレスの集合および 追加の実装依存情報を返す。

  4. failureを返す。

オリジンを解決するの結果はキャッシュしてもよい。キャッシュする場合はkeyをキャッシュキーの一部として用いるべきである。

通常この操作はDNSを伴い、DNSサーバー側でkeyを考慮せずキャッシュされる場合があります。実装によってはローカルでkeyを考慮することもできない場合があります。[RFC1035]

IPアドレスの順序は、 オリジンを解決するアルゴリズムの呼び出しごとに異なる場合があります。

(キャッシュキー以外の)詳細は、Fetch標準が定めるシステムに直接関係しないため拘束されません。他の文書がこのプリミティブに依存して拡張する場合は、まずFetch標準コミュニティと十分に議論するべきです。

2.6. コネクション

ユーザーエージェントは、関連付けられたコネクションプールを持ちます。 コネクションプールは、 0個以上の順序付き集合としてのコネクションです。各コネクションは、関連付けられたキーネットワークパーティションキー)、 オリジンオリジン)、および認証情報 (boolean)で識別されます。

コネクションは、関連付けられた タイミング情報コネクションタイミング情報)を持ちます。

コネクションタイミング情報は、 コネクション取得処理に関するタイミング情報を保持するための 構造体です。以下の項目があります:

ドメインルックアップ開始時刻(初期値0)
ドメインルックアップ終了時刻(初期値0)
コネクション開始時刻(初期値0)
コネクション終了時刻(初期値0)
セキュアコネクション開始時刻(初期値0)
DOMHighResTimeStamp
ALPNネゴシエートプロトコル(初期値:空のバイト列
バイト列

コネクションタイミング情報のclampおよびcoarsenを行うには、 コネクションタイミング情報 timingInfoDOMHighResTimeStamp defaultStartTime、boolean crossOriginIsolatedCapabilityを与えて次の手順を実行する:

  1. timingInfoコネクション開始時刻defaultStartTimeより小さければ、新しいコネクションタイミング情報を返す(全ての時刻がdefaultStartTime、ALPNネゴシエートプロトコルはtimingInfoの値)。

  2. 新しいコネクションタイミング情報を返す(各時刻はcoarsen timeの結果、ALPNネゴシエートプロトコルはtimingInfoの値)。


新規コネクション設定は、"no"、"yes"、"yes-and-dedicated"のいずれかです。

コネクションを取得するには、 ネットワークパーティションキー keyURL url、 boolean credentials、 任意の新規コネクション設定 new(初期値"no")、 任意のboolean requireUnreliable(初期値false)を与え、次の手順を実行する:

  1. newが"no"なら:

    1. connectionsをユーザーエージェントのコネクションプール内の、 キーkeyオリジンurlオリジン認証情報credentialsであるコネクションの集合とする。

    2. connectionsが空でなく、requireUnreliableがfalseなら、その中の1つを返す。

    3. connections内に、例えばHTTP/3など、unreliable transport対応のコネクションがあれば、それを返す。

  2. proxiesを実装依存の方法でurlのプロキシとして探索した結果とする。なければ« "DIRECT" »とする。

    ここで非標準技術(WPADPAC)が使われる可能性があります。"DIRECT"は、このurlでプロキシを使わないことを意味します。

  3. timingInfoを新しいコネクションタイミング情報とする。

  4. proxiesproxyについて:

    1. timingInfoドメインルックアップ開始時刻unsafe shared current timeに設定する。

    2. hostsを« urlオリジンhost »とする。

    3. proxyが"DIRECT"なら、hostskeyurlオリジンを与えてオリジンを解決するの結果に設定する。

    4. hostsがfailureなら、continue

    5. timingInfoドメインルックアップ終了時刻unsafe shared current timeに設定する。

    6. connectionを、以下の手順で得られた結果とする:コネクション作成に、keyurlオリジンcredentialsproxyhostsから実装依存で選択したhosttimingInforequireUnreliableを与え、実装依存の回数だけ並列で実行し、少なくとも1つの値を待つ。実装依存で返す値を選び、それを返す。他の値(コネクション)は閉じてよい。

      本質的には、オリジンを解決するproxyが"DIRECT"の場合)から返された複数のIPアドレスを競わせたり、IPv6優先したり、タイムアウトで再試行したりできることを意味します。

    7. connectionがfailureなら、continue

    8. newが"yes-and-dedicated"でなければ、 append connectionをユーザーエージェントのコネクションプールに追加する。

    9. connectionを返す。

  5. failureを返す。

コネクション管理には多くの微妙な点があるため、詳細は実装者の裁量に任せています。これを記述することで、<link rel=preconnect>コネクション認証情報でキーされることを明確にできます。例えば、TLSセッションIDは認証情報がfalseのコネクションとtrueのコネクション間で再利用されません。


コネクション作成は、 ネットワークパーティションキー keyオリジン origin、 boolean credentials、string proxyhost hostコネクションタイミング情報 timingInfo、 boolean requireUnreliableを与え、次の手順を実行する:

  1. timingInfoコネクション開始時刻unsafe shared current timeに設定する。

  2. connectionを新しいコネクションとし、 キーkeyオリジンorigin認証情報credentialsタイミング情報timingInfoを持たせる。 コネクションタイミング情報記録を行い、 connectionを使ってhostにHTTPコネクションを確立する(proxyoriginを考慮)。以下の注意点あり: [HTTP] [HTTP1] [TLS]

    • requireUnreliableがtrueなら、unreliable transport対応(例:HTTP/3)のコネクションを確立する。[HTTP3]

    • unreliable transport対応コネクションの場合、WebTransport用オプション(HTTP/3の場合、SETTINGS_ENABLE_WEBTRANSPORT1H3_DATAGRAM1で初期SETTINGSフレームに含める)を有効化する。[WEBTRANSPORT-HTTP3] [HTTP3-DATAGRAM]

    • credentialsがfalseなら、TLSクライアント証明書を送信しない。

    • コネクション確立に失敗した場合(UDP/TCP/TLSエラー等)は、failureを返す。

  3. timingInfoALPNネゴシエートプロトコルconnectionのALPN Protocol IDに設定する。以下の注意点あり:[RFC7301]

    • プロキシ利用時は、トンネルが確立されていればそのプロトコルのALPN Protocol ID、そうでなければ最初のプロキシへのALPN Protocol IDとする。

    • 実験的・非登録プロトコルの場合、利用したALPN Protocol ID(あれば)を使う。ALPNを使っていない場合は別の説明的な文字列でもよい。

      timingInfoALPNネゴシエートプロトコルは、実際のネゴシエーション方法に関わらず利用中のネットワークプロトコルを識別するためのものです。

    IANAはALPN Protocol IDのリストを管理しています。

  4. connectionを返す。


コネクションタイミング情報記録は、 コネクション connectionを受け取り、 timingInfoconnectionタイミング情報として次を満たすこと:

コネクションタイミング情報のclampおよびcoarsenアルゴリズムは、再利用コネクションの詳細やタイム値の丸めを保証します。

2.7. ネットワークパーティションキー

ネットワークパーティションキーは、サイトと、nullまたは実装依存の値からなるタプルです。

environment environmentを与え、ネットワークパーティションキーを決定するには、次の手順を実行します:

  1. topLevelOriginenvironmentトップレベルオリジンとする。

  2. topLevelOriginがnullなら、topLevelOriginenvironmentトップレベル生成URLオリジンとする。

  3. Assert: topLevelOriginオリジンである。

  4. topLevelSitetopLevelOriginを与えてサイト取得の結果とする。

  5. secondKeyをnullまたは実装依存の値とする。

    second keyは意図的に曖昧にされています。詳細は今後詰められます。issue #1035参照。

  6. (topLevelSite, secondKey)を返す。

request requestを与え、ネットワークパーティションキーを決定するには、次の手順を実行します:

  1. requestreserved clientがnullでなければ、 requestreserved clientを与えて ネットワークパーティションキーを決定するの結果を返す。

  2. requestclientがnullでなければ、 requestclientを与えて ネットワークパーティションキーを決定するの結果を返す。

  3. nullを返す。

2.8. HTTPキャッシュパーティション

HTTPキャッシュパーティションを決定するには、リクエスト requestを与えて次の手順を実行する:

  1. keyrequestを与えてネットワークパーティションキーを決定するの結果とする。

  2. keyがnullならnullを返す。

  3. keyに関連付けられた一意なHTTPキャッシュを返す。[HTTP-CACHING]

2.9. ポートブロッキング

新しいプロトコルは、TLSを用いたALPNでプロトコルをネゴシエートすることで、ポートブロックの必要性を回避できます。その場合、プロトコルはHTTPリクエストを通して偽装されることはありません。 [RFC7301]

リクエスト requestについて悪いポートによるブロックが必要か判定するには:

  1. urlrequest現在のURLとする。

  2. urlスキームHTTP(S)スキームであり、かつurlポート悪いポートであれば、blockedを返す。

  3. allowedを返す。

ポートが 次の表の最初の列に記載されている場合、悪いポートです。

ポート 主なサービス
0 —​
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

2.10. responserequestへのレスポンスとしてMIMEタイプのためにブロックすべきか?

次の手順を実行する:

  1. mimeTypeを、responseヘッダーリストからMIMEタイプ抽出した結果とする。

  2. mimeTypeがfailureなら、allowedを返す。

  3. destinationrequestdestinationとする。

  4. destinationスクリプト系で、以下のいずれかが真ならblockedを返す:

  5. allowedを返す。

3. HTTP拡張

3.1. Cookie

`Cookie`リクエストヘッダーおよび`Set-Cookie`レスポンスヘッダーは主にそれぞれの仕様で定義されています。ここでは、それらを便利に利用できるよう補助的なインフラを定義します。[COOKIES]

リクエスト`Cookie`ヘッダーを付加するには、リクエスト requestを与えて、次の手順を実行する:

  1. ユーザーエージェントがrequestについてCookieを無効化している場合、何もせず戻る。

  2. sameSiterequestに対してsame-siteモードを決定するの結果とする。

  3. isSecurerequest現在のURLスキームが"https"ならtrue、そうでなければfalseとする。

  4. httpOnlyAllowedをtrueとする。

    これはfetchから呼ばれるためtrueとなる。たとえばdocument.cookieのgetter手順とは異なる。

  5. cookiesisSecurerequest現在のURLホストrequest現在のURLパスhttpOnlyAllowedsameSiteを与えてCookie取得の結果とする。

    Cookieストアは順序付きのCookieリストを返す。

  6. cookiesであれば、何もせず戻る。

  7. valuecookiesを与えてCookie直列化の結果とする。

  8. 追加 (`Cookie`, value) を requestヘッダーリスト に追加する。

レスポンス`Set-Cookie`ヘッダーの解析および保存は、 リクエスト requestレスポンス responseを与えて、次の手順を実行する:

  1. ユーザーエージェントがrequestについてCookieを無効化している場合、何もせず戻る。

  2. allowNonHostOnlyCookieForPublicSuffixをfalseとする。

  3. isSecurerequest現在のURLスキームが"https"ならtrue、そうでなければfalseとする。

  4. httpOnlyAllowedをtrueとする。

    これはfetchから呼ばれるためtrueとなる。たとえばdocument.cookieのgetter手順とは異なる。

  5. sameSiteStrictOrLaxAllowedを、requestに対してsame-siteモードを決定するの結果が"strict-or-less"ならtrue、そうでなければfalseとする。

  6. headerresponseヘッダーリストから順に処理する:

    1. header名前Set-Cookieバイト単位で大文字小文字を区別せず一致しなければ、continue

    2. Cookieの解析および保存headerisSecurerequest現在のURLホストrequest現在のURLパスhttpOnlyAllowedallowNonHostOnlyCookieForPublicSuffixsameSiteStrictOrLaxAllowedを与えて実行する。

    3. Cookieのガベージコレクトrequest現在のURLホストを与えて実行する。

    他の場所でも指摘されているとおり、`Set-Cookie`ヘッダーは結合できず、各出現ごとに個別に処理される。他のヘッダーではこれは許可されない。

same-siteモードを決定するには、リクエスト requestを与えて次の手順を実行する:

  1. Assert: requestメソッドが"GET" または"POST"である。

  2. requestトップレベルナビゲーションイニシエータオリジンがnullでなく、かつrequestURLオリジンsame siteでなければ、"unset-or-less"を返す。

  3. requestメソッドが"GET"かつ requestdestinationが"document"なら、"lax-or-less"を返す。

  4. requestclientcross-site ancestorを持つがtrueなら、"unset-or-less"を返す。

  5. requestredirect-taintが"cross-site"なら、"unset-or-less"を返す。

  6. "strict-or-less"を返す。

シリアライズされたCookieデフォルトパスを、URL urlから取得するには、以下を行う:

  1. cloneURLurlのクローンとして作成する。

  2. cloneURLパスを、CookieデフォルトパスcloneURLパスの)に設定する。

  3. cloneURLURLパスのシリアライズを返す。

3.2. `Origin` ヘッダー

`Origin`リクエストヘッダーは、 fetchがどこから発生したかを示します。

`Origin`ヘッダーは、パスを公開しない`Referer` [sic] ヘッダーのバージョンです。 HTTPフェッチで、 リクエストレスポンステインティングが"cors"の場合や、 リクエストメソッドが`GET`または`HEAD`以外の場合に利用されます。 互換性上の理由から、すべてのfetchに含まれるわけではありません。

そのとしては、リクエストオリジンのバイト列シリアライズリクエストを与える)で得られるすべての値が許可されます。

これはThe Web Origin Conceptの定義に取って代わります。[ORIGIN]


リクエスト`Origin`ヘッダーを付加する には、リクエスト requestを与えて次の手順を実行する:

  1. Assert: requestoriginは"client"でない。

  2. serializedOriginを、requestを与えてリクエストオリジンのバイト列シリアライズの結果とする。

  3. もし requestレスポンステインティング が "cors" または requestモード が "websocket" の場合、 追加 (`Origin`, serializedOrigin) を requestヘッダーリスト に追加する。

  4. さもなければ、requestメソッドが`GET`でも`HEAD`でもない場合:

    1. requestmodeが"cors"でなければ、 requestreferrer policyに応じて次を行う:

      "no-referrer"

      serializedOriginを`null`に設定する。

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

      requestoriginタプルオリジンで、 そのschemeが"https"、かつrequest現在のURLschemeが"https"でなければ serializedOriginを`null`に設定する。

      "same-origin"

      requestoriginrequest現在のURLオリジン同一オリジンでなければ serializedOriginを`null`に設定する。

      その他
      何もしない。
    2. 追加 (`Origin`, serializedOrigin) を requestヘッダーリスト に追加する。

リクエストreferrer policyは、 フェッチャーがサーバーとオリジンを共有することを明示的に選択していないすべてのfetchで考慮されます(例:CORSプロトコルの利用)。

3.3. CORSプロトコル

レスポンスをオリジン間で共有し、HTMLの form 要素よりも多様なfetchを可能にするために、CORSプロトコルが存在します。 これはHTTPの上にレイヤー化されており、レスポンスが他のオリジンと共有できることを宣言できます。

これはファイアウォール(イントラネット)内のレスポンスからデータが漏洩するのを防ぐため、オプトインの仕組みである必要があります。また、リクエスト認証情報が含まれる場合も、機密データ漏洩防止のためオプトインが必要です。

この節はサーバー開発者向けにCORSプロトコルを説明します。 ユーザーエージェントの要件はfetchアルゴリズムの一部ですが、 新しいHTTPヘッダー構文を除きます。

3.3.1. 一般

CORSプロトコルは、レスポンスがオリジン間で共有できるかどうかを示す一連のヘッダーから成ります。

HTMLの form 要素で可能なものよりも複雑なリクエストの場合、 CORSプリフライトリクエストが実行され、 リクエスト現在のURLCORSプロトコルに対応しているか確認されます。

3.3.2. HTTPリクエスト

CORSリクエストとは、`Origin`ヘッダーを含むHTTPリクエストです。 ただし、CORSプロトコルに参加しているかどうかは確実には判別できません。 なぜなら、`Origin`ヘッダーは リクエストメソッドが`GET`または`HEAD`以外の時も常に含まれるためです。

CORSプリフライトリクエストは、CORSリクエストのうち、 CORSプロトコルが理解されているか確認するためのものです。 これはOPTIONSメソッドとして使い、次のヘッダーを含みます:

`Access-Control-Request-Method`

将来のCORSリクエストがそのリソースに対して使用するであろうメソッドを示す。

CORSプリフライトリクエストは、次のヘッダーも含むことがあります:

`Access-Control-Request-Headers`

将来のCORSリクエストがそのリソースに対して使用するであろうヘッダーを示す。

3.3.3. HTTPレスポンス

CORSリクエストへのHTTPレスポンスには、以下のヘッダーを含めることができます:

`Access-Control-Allow-Origin`

レスポンスが共有可能かどうかを示します。リクエストの`Origin`ヘッダーのリテラル (`null`も含む)または`*`をレスポンスで返すことができます。

`Access-Control-Allow-Credentials`

リクエスト認証情報モードが"include"の場合にレスポンスが共有可能かどうかを示します。

CORSプリフライトリクエストの場合、リクエスト認証情報モードは常に"same-origin"(認証情報は含まれない)ですが、その後のCORSリクエストではそうとは限りません。そのため、このサポートはCORSプリフライトリクエストへのHTTPレスポンスにも明示する必要があります。

CORSプリフライトリクエストへのHTTPレスポンスには、以下のヘッダーを含めることができます:

`Access-Control-Allow-Methods`

CORSプロトコルの目的で、 レスポンスURLがサポートするメソッドを示します。

`Allow`ヘッダーは、CORSプロトコルの目的には関係ありません。

`Access-Control-Allow-Headers`

CORSプロトコルの目的で、 レスポンスURLがサポートするヘッダーを示します。

`Access-Control-Max-Age`

`Access-Control-Allow-Methods`および `Access-Control-Allow-Headers`ヘッダーで提供された情報がキャッシュ可能な秒数(デフォルト5秒)を示します。

CORSプリフライトリクエストでない CORSリクエストへのHTTPレスポンスは、次のヘッダーも含めることができます:

`Access-Control-Expose-Headers`

レスポンスの一部として公開できるヘッダーを、その名前で列挙して示します。


サーバー開発者が共有の意図を持つCORSリクエストへの成功したHTTPレスポンスは、 上記のヘッダーとリクエストと一致したを含める限り、任意のステータスを利用できます。

CORSプリフライトリクエストへの成功したHTTPレスポンスも同様ですが、okステータス(例: 200や204)に制限されます。

他の種類のHTTPレスポンスは成功とは見なされず、共有されないかCORSプリフライトリクエストが失敗します。サーバーが明示的に示したい場合は、403ステータスと該当するヘッダーの省略を組み合わせて使うこともできます。

「失敗」も共有したい場合は可能ですが、それは成功したHTTPレスポンスとなります。そのため、CORSプリフライトリクエストでないCORSリクエストへの成功したHTTPレスポンスのステータスは、403も含めて何でもよいです。

最終的に、サーバー開発者はHTTPレスポンスの扱いにおいて多くの自由があります。これらの戦略はCORSプリフライトリクエストと、その後のCORSリクエストで異なる場合があります:

3.3.4. HTTP新ヘッダー構文

CORSプロトコルで使われるヘッダーABNF

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.3.5. CORSプロトコルと認証情報

リクエスト認証情報モードが"include"の場合、認証情報fetchで含める以外にも、CORSプロトコルの動作に影響を与えます。

かつては、XMLHttpRequest を使ってリクエスト認証情報モードを"include"に設定できました:

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

現在は、fetch("./", { credentials:"include" }).then(/* … */)だけで充分です。

リクエスト認証情報モードは、サーバ側で常に観測できるわけではありません。認証情報が含まれるリクエストのみ、認証情報が含まれていることで観測可能です。なお、CORSプリフライトリクエストでは認証情報は決して含まれません。

したがってサーバー開発者は、認証情報付きレスポンスを共有するかどうか、またCORSプリフライトリクエストが必要なリクエスト認証情報を含めるかどうかの判断が必要です。一般的に、レスポンスの共有もリクエストの許可も認証情報付きの場合は極めて危険であり、confused deputy問題を回避するために細心の注意が必要です。

認証情報付きでレスポンスを共有するには、`Access-Control-Allow-Origin`と `Access-Control-Allow-Credentials`ヘッダーが重要です。以下の表は、https://rabbit.invalid/へのリクエストにおける合法・非合法の組み合わせ例です:

リクエストの認証情報モード `Access-Control-Allow-Origin` `Access-Control-Allow-Credentials` 共有可? 備考
"omit" `*` 省略
"omit" `*` `true` credentials modeが"include"でなければ`Access-Control-Allow-Credentials`は無視される。
"omit" `https://rabbit.invalid/` 省略 直列化されたオリジンは後ろにスラッシュが付かない。
"omit" `https://rabbit.invalid` 省略
"include" `*` `true` credentials modeが"include"の場合、`Access-Control-Allow-Origin`は`*`を使えない。
"include" `https://rabbit.invalid` `true`
"include" `https://rabbit.invalid` `True` `true`は(バイト単位で)大文字小文字が区別される。

同様に、`Access-Control-Expose-Headers`、`Access-Control-Allow-Methods`、`Access-Control-Allow-Headers`レスポンスヘッダーも、リクエスト認証情報モードが"include"でない場合のみ値に`*`を使えます。

3.3.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

これら2つのヘッダーがこの値で含まれていなければ、failureコールバックが呼ばれます。ただし、`Set-Cookie`レスポンスヘッダーは尊重されます。

3.3.7. CORSプロトコルの例外

仕様では、CORS safelist 以外の`Content-Type`ヘッダー値に対して限定的な例外が認められています。これらの例外は、ウェブコンテンツによって発生可能だが、ヘッダーやボディをウェブコンテンツからは最小限しか制御できないリクエストに対して設けられています。そのため、サーバー側は、クロスオリジンのウェブコンテンツによって以下の非プリフライトな非safelistな`Content-Type`ヘッダー値でリクエストされうることを想定する必要があります:

仕様は新たな例外の導入を避けるべきであり、慎重なセキュリティ検討の上でのみ追加するべきです。新しい例外の提案は issueの提出で行えます。

3.4. `Content-Length` ヘッダー

`Content-Length`ヘッダーは主にHTTPで定義されています。その処理モデルはHTTPで定義されたものがウェブコンテンツと互換性がないため、ここで定義されています。[HTTP]

長さを抽出するには、 ヘッダーリスト headersを与えて次の手順を実行する:

  1. valuesを、headersから`Content-Length`を取得・デコード・分割した結果とする。

  2. valuesがnullならnullを返す。

  3. candidateValueをnullとする。

  4. valuesvalue について:

    1. candidateValueがnullなら、candidateValuevalueを設定する。

    2. そうでなければ、valuecandidateValueと異なれば、failureを返す。

  5. candidateValueが空文字列か、コードポイントASCII数字でないものが含まれていれば、nullを返す。

  6. candidateValueを10進数として解釈して返す。

3.5. `Content-Type` ヘッダー

`Content-Type`ヘッダーは主にHTTPで定義されています。その処理モデルはHTTPで定義されたものがウェブコンテンツと互換性がないため、ここで定義されています。[HTTP]

MIMEタイプを抽出するには、 ヘッダーリスト headersを与えて次の手順を実行する。これらはfailureまたはMIMEタイプを返す。

  1. charsetをnullとする。

  2. essenceをnullとする。

  3. mimeTypeをnullとする。

  4. valuesを、headersから`Content-Type`を取得・デコード・分割した結果とする。

  5. valuesがnullならfailureを返す。

  6. valuesvalue について:

    1. temporaryMimeTypevalueMIMEタイプとして構文解析した結果とする。

    2. temporaryMimeTypeがfailure、またはそのエッセンスが"*/*"なら、continue

    3. mimeTypetemporaryMimeTypeを設定する。

    4. mimeTypeエッセンスessenceと異なる場合:

      1. charsetをnullに設定する。

      2. mimeTypeparameters["charset"]が存在すれば、charsetにその値を設定する。

      3. essencemimeTypeエッセンスを設定する。

    5. そうでなければ、mimeTypeparameters["charset"]が存在せず、かつcharsetがnullでなければ、mimeTypeparameters["charset"]にcharsetを設定する。

  7. mimeTypeがnullならfailureを返す。

  8. mimeTypeを返す。

MIMEタイプを抽出するがfailureを返した場合や、MIMEタイプエッセンスが与えられたフォーマットに不適切な場合は、致命的エラーとして扱うこと。既存のウェブプラットフォーム機能はこのパターンに従っていないことが多く、長年にわたりセキュリティ脆弱性の主な原因となっています。一方で、MIMEタイプパラメータは通常無視しても安全です。

MIMEタイプを抽出するの実際の動作例:

Headers(ネットワーク上の値) 出力(直列化
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:

レガシーエンコーディング抽出は、failureまたはMIMEタイプ mimeTypeエンコーディング fallbackEncodingを与えて次の手順を実行する:

  1. mimeTypeがfailureならfallbackEncodingを返す。

  2. mimeType["charset"]が存在しなければ、fallbackEncodingを返す。

  3. tentativeEncodingmimeType["charset"]からエンコーディング取得した結果とする。

  4. tentativeEncodingがfailureならfallbackEncodingを返す。

  5. tentativeEncodingを返す。

このアルゴリズムはmimeTypeがfailureでも受け付けるため、MIMEタイプを抽出すると容易に組み合わせられます。

これが"legacy"とされるのは、現代のフォーマットはUTF-8のみ使うことが推奨されているためです。

3.6. `X-Content-Type-Options` ヘッダー

`X-Content-Type-Options` レスポンスヘッダーは、リクエストdestinationに対して レスポンスの`Content-Type`ヘッダーのチェックを要求するために使用できます。

nosniffを判定するには、ヘッダーリスト listを与えて次の手順を実行する:

  1. valueslistから`X-Content-Type-Options`を取得・デコード・分割した結果とする。

  2. valuesがnullならfalseを返す。

  3. values[0]が"nosniff"とASCII大文字・小文字を区別せず一致するならtrueを返す。

  4. falseを返す。

ウェブ開発者および適合性チェッカーは、`X-Content-Type-Options`のに次のABNFを使わなければなりません:

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

3.6.1. responserequestへのレスポンスとしてnosniffのためにブロックすべきか?

次の手順を実行する:

  1. responseヘッダーリストに対してnosniffを判定するがfalseなら、allowedを返す。

  2. mimeTyperesponseヘッダーリストからMIMEタイプを抽出するの結果とする。

  3. destinationrequestdestinationとする。

  4. destinationスクリプト系で、mimeTypeがfailureまたはJavaScript MIMEタイプでなければ、blockedを返す。

  5. destinationが"style"で、mimeTypeがfailureまたはそのエッセンスが"text/css"でなければ、blockedを返す。

  6. allowedを返す。

スクリプト系または"style"のdestinationだけが考慮されます。なぜならそれらに関連する攻撃があるためです。また、"image"は既存コンテンツとの互換性がありませんでした。

3.7. `Cross-Origin-Resource-Policy` ヘッダー

`Cross-Origin-Resource-Policy` レスポンスヘッダーは、リクエスト現在のURLオリジンリクエストoriginと比較して確認するために使用できます。これはリクエストmodeが"no-cors"の時です。

そのABNF

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

クロスオリジンリソースポリシーチェックを行うには、origin origin環境設定オブジェクト settingsObject、文字列destinationresponse response、および省略可能なboolean forNavigationを与えて次の手順を実行する:

  1. forNavigationが与えられていなければfalseとする。

  2. embedderPolicysettingsObjectポリシーコンテナ埋め込み者ポリシーとする。

  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 origin埋め込み者ポリシー値 embedderPolicyValueresponse response、boolean forNavigationを与えて次の手順を実行する:

  1. forNavigationがtrueでembedderPolicyValueが"unsafe-none"ならallowedを返す。

  2. policyresponseヘッダーリストから`Cross-Origin-Resource-Policy`を取得した結果とする。

    これは、`Cross-Origin-Resource-Policy: same-site, same-origin`のような場合は、embedderPolicyValueが"unsafe-none"である限り、下で何にも一致しないのでallowedとなる、という意味です。`Cross-Origin-Resource-Policy`ヘッダーが2つ以上あっても同様です。

  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`

    originresponseURLorigin同一オリジンならallowedを返す。

    そうでなければblockedを返す。

    `same-site`

    以下がすべて真なら

    このときallowedを返す。

    そうでなければblockedを返す。

    `Cross-Origin-Resource-Policy: same-site`は、セキュアな伝送で配信されたレスポンスが、たとえホストが同一サイトでも非セキュアなリクエスト元とは一致しないことに注意。セキュアなレスポンスはセキュアなイニシエータとだけ一致する。

クロスオリジン埋め込み者ポリシーCORP違反レポートをキューするには、 response response環境設定オブジェクト settingsObject、文字列destination、boolean reportOnlyを与えて次の手順を実行する:

  1. endpointsettingsObjectポリシーコンテナ埋め込み者ポリシーreport only reporting endpointreportOnlyがtrueかつ settingsObjectポリシーコンテナ埋め込み者ポリシーの時)、それ以外はreporting endpointとする。

  2. serializedURLresponsereporting用レスポンスURLの直列化した結果とする。

  3. dispositionreportOnlyがtrueなら"reporting"、そうでなければ"enforce"とする。

  4. bodyを次のプロパティを持つ新しいオブジェクトとする:

    key value
    "type" "corp"
    "blockedURL" serializedURL
    "destination" destination
    "disposition" disposition
  5. レポートの生成とキューを、settingsObjectグローバルオブジェクト"coep"レポートタイプendpointbodyで実行する。[REPORTING]

3.8. `Sec-Purpose` ヘッダー

`Sec-Purpose` HTTPリクエストヘッダーは、そのリクエストがユーザーによる即時利用以外の目的でリソースを要求していることを示します。

`Sec-Purpose` ヘッダーフィールドはstructured headerであり、その値はトークンでなければなりません。

定義されているトークンprefetchのみです。これはリクエストの目的が、近いうちに必要になると予想されるリソースを取得することであることを示します。

サーバーはこれを利用して、プリフェッチ用のキャッシュ有効期限を調整したり、プリフェッチを拒否したり、ページ訪問回数のカウント時に別扱いすることができます。

4. フェッチング

以下のアルゴリズムはフェッチングを定義しています。大まかに言えば、リクエストと、操作のさまざまなポイントで実行される一つ以上のアルゴリズムを受け取ります。レスポンスは、下記の最後の二つのアルゴリズムに渡されます。最初の二つのアルゴリズムは、アップロードのキャプチャに利用できます。

フェッチするには、リクエストrequest、オプションのアルゴリズムprocessRequestBodyChunkLength、オプションのアルゴリズムprocessRequestEndOfBody、オプションのアルゴリズムprocessEarlyHintsResponse、オプションのアルゴリズムprocessResponse、オプションのアルゴリズムprocessResponseEndOfBody、オプションのアルゴリズムprocessResponseConsumeBody、およびオプションのブール値useParallelQueue(デフォルトはfalse)を受け取り、以下の手順を実行します。processRequestBodyChunkLengthが指定されている場合、送信されたバイト数を表す整数を受け取るアルゴリズムでなければなりません。processRequestEndOfBodyが指定されている場合、引数なしで受け取るアルゴリズムでなければなりません。processEarlyHintsResponseが指定されている場合、レスポンスを受け取るアルゴリズムでなければなりません。processResponseが指定されている場合、レスポンスを受け取るアルゴリズムでなければなりません。processResponseEndOfBodyが指定されている場合、レスポンスを受け取るアルゴリズムでなければなりません。processResponseConsumeBodyが指定されている場合、レスポンスとnull、失敗、またはバイト列を受け取るアルゴリズムでなければなりません。

ユーザーエージェントは進行中のフェッチを一時停止するように要求される場合があります。ユーザーエージェントは一時停止要求を受け入れるか、無視することができます。一時停止されたフェッチは再開できます。リクエストのHTTPキャッシュ内のレスポンスを更新している場合、ユーザーエージェントは一時停止要求を無視するべきです。

ユーザーエージェントは、リクエストのキャッシュモードが "no-store" である場合や、レスポンスに `Cache-Control: no-store` ヘッダーが含まれている場合、HTTPキャッシュのエントリを更新しません。[HTTP-CACHING]

  1. アサートrequestmodeが"navigate"であるか、processEarlyHintsResponseがnullである。

    early hints(レスポンスstatusが103であるもの)の処理は、ナビゲーションのみで認められます。

  2. taskDestinationをnullとする。

  3. crossOriginIsolatedCapabilityをfalseとする。

  4. クライアントからリクエストを埋め込むrequestを指定して実行。

  5. requestclientがnullでなければ:

    1. taskDestinationrequestclientグローバルオブジェクトを設定する。

    2. crossOriginIsolatedCapabilityrequestclientクロスオリジン分離機能を設定する。

  6. useParallelQueueがtrueであれば、taskDestination新しい並列キューの開始の結果を設定する。

  7. timingInfoを新しいフェッチタイミング情報として生成し、その開始時刻リダイレクト後開始時刻粗化された共有現在時刻crossOriginIsolatedCapabilityを指定)で設定し、レンダーブロッキングrequestレンダーブロッキングで設定する。

  8. fetchParamsを新しいフェッチパラメータとして生成し、requestrequesttiming infotimingInfoprocess request body chunk lengthprocessRequestBodyChunkLengthprocess request end-of-bodyprocessRequestEndOfBodyprocess early hints responseprocessEarlyHintsResponseprocess responseprocessResponseprocess response consume bodyprocessResponseConsumeBodyprocess response end-of-bodyprocessResponseEndOfBodytask destinationtaskDestinationcross-origin isolated capabilitycrossOriginIsolatedCapabilityを設定する。

  9. requestbodyバイト列であれば、requestbodyrequestbodyボディとしてで設定する。

  10. 以下すべての条件を満たす場合:

    この場合:

    1. アサートrequestoriginrequestclientorigin同一オリジンである。

    2. onPreloadedResponseAvailableに、レスポンスresponseを受け取ったとき、fetchParamspreloaded response candidateresponseに設定するアルゴリズムを割り当てる。

    3. foundPreloadedResourceに、プリロード済みリソースを消費するrequestclientrequestURLrequestdestinationrequestmoderequestcredentials moderequestintegrity metadata、およびonPreloadedResponseAvailableを指定して呼び出した結果を設定する。

    4. foundPreloadedResourceがtrueであり、かつfetchParamspreloaded response candidateがnullであれば、fetchParamspreloaded response candidateを"pending"に設定する。

  11. requestheader list`Accept`を含まない場合:

    1. valueを `*/*` にする。

    2. requestinitiatorが"prefetch"であれば、valueドキュメント`Accept`ヘッダー値に設定する。

    3. それ以外の場合、ユーザーエージェントはrequestdestinationに応じて、下記の最初に一致する項目でvalueを設定するべきです:

      "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ヘッダーリストに追加する。

  12. もし requestヘッダーリスト`Accept-Language` を含まない場合、ユーザーエージェントは 追加(`Accept-Language`, 適切な ヘッダー値)を requestヘッダーリストに追加するべきです。

  13. request内部優先度がnullであれば、requestpriorityinitiatordestination、およびレンダーブロッキングを用いて、実装定義の方法でrequest内部優先度実装定義のオブジェクトを設定する。

    実装定義のオブジェクトは、HTTP/2のストリーム重みや依存性、HTTP/3などのトランスポートで利用されるExtensible Prioritization Scheme for HTTPの優先度、またはHTTP/1フェッチのディスパッチ・処理の優先度などを含む場合があります。[RFC9218]

  14. requestサブリソースリクエストであれば:

    1. recordを新しいフェッチレコードとして生成し、requestrequestcontrollerfetchParamscontrollerを設定する。

    2. recordrequestclientフェッチグループフェッチレコードリストに追加する。

  15. メインフェッチfetchParamsで実行する。

  16. fetchParamscontrollerを返す。

クライアントからリクエストを埋め込むには、リクエストrequestを指定して以下を実行します:

  1. requestユーザープロンプト用トラバーサブルが"client"であれば:

    1. requestユーザープロンプト用トラバーサブルを"no-traversable"に設定する。

    2. requestclientがnullでなければ:

      1. globalrequestclientグローバルオブジェクトを設定する。

      2. globalWindowオブジェクトであり、かつglobalnavigableがnullでなければ、requestユーザープロンプト用トラバーサブルglobalnavigabletraversable navigableで設定する。

  2. requestoriginが"client"であれば:

    1. アサートrequestclientがnullでないこと。

    2. requestoriginrequestclientoriginに設定する。

  3. requestポリシーコンテナが"client"であれば:

    1. requestclientがnullでなければ、requestpolicy containerrequestclientポリシーコンテナ複製に設定する。[HTML]

    2. それ以外の場合、requestpolicy containerを新しいポリシーコンテナに設定する。

4.1. メインフェッチ

メインフェッチするには、フェッチパラメータfetchParamsとオプションのブール値recursive(デフォルトはfalse)を指定して、以下の手順を実行します:

  1. requestfetchParamsrequestを設定する。

  2. responseをnullとする。

  3. requestlocal-URLs-only flagがセットされていて、かつrequestcurrent URLローカルでなければ、responseネットワークエラーを設定する。

  4. Content Security Policy違反をrequestに対して報告する。

  5. 必要に応じてrequestを信頼できるURLにアップグレードする。

  6. 必要に応じて混在コンテンツrequestを信頼できるURLにアップグレードする。

  7. 悪いポートのためrequestをブロックすべきか混在コンテンツとしてrequestのフェッチをブロックすべきかContent Security Policyによりrequestをブロックすべきか整合性ポリシーによりrequestをブロックすべきかblockedを返した場合、responseネットワークエラーを設定する。

  8. requestreferrer policyが空文字列であれば、requestreferrer policyrequestpolicy containerreferrer policyに設定する。

  9. requestreferrerが"no-referrer"でなければ、requestreferrerリクエストのreferrerを決定するの結果に設定する。[REFERRER]

    Referrer Policyに記載されている通り、ユーザーエージェントはエンドユーザーに"no-referrer"に上書きする、またはより機微な情報のみを公開するオプションを提供できます。

  10. 以下すべての条件を満たす場合、requestcurrent URLschemeを"https"に設定する:

    すべてのDNS操作は通常実装定義であるため、DNS解決にHTTPS RRが含まれているかどうかの判定も実装定義です。DNS操作は伝統的にコネクション取得の試行まで行われないため、ユーザーエージェントはDNS操作を早期に実施したり、ローカルDNSキャッシュを参照したり、フェッチアルゴリズムの後段で判明した場合に論理を巻き戻す必要があるかもしれません。

  11. recursiveがfalseであれば、残りの手順を並列で実行する。

  12. responseがnullであれば、最初に一致する条件の手順を実行してresponseを設定する:

    fetchParamspreloaded response candidateがnullでない
    1. fetchParamspreloaded response candidateが"pending"でなくなるまで待つ。

    2. アサートfetchParamspreloaded response candidateレスポンスである。

    3. fetchParamspreloaded response candidateを返す。

    requestcurrent URLoriginrequestorigin同一オリジンで、かつrequestresponse taintingが"basic"である
    requestcurrent URLschemeが"data"である
    requestmodeが"navigate"または"websocket"である
    1. requestresponse taintingを"basic"に設定する。

    2. スキームフェッチfetchParamsで実行した結果を返す。

    HTMLは、URLschemeが"data"のものから作成されるドキュメントやワーカーに一意の不透明オリジンを割り当てます。Service WorkerはURLschemeHTTP(S)スキームのもののみから作成可能です。[HTML] [SW]

    requestmodeが"same-origin"である

    ネットワークエラーを返す。

    requestmodeが"no-cors"である
    1. requestredirect modeが"follow"でなければネットワークエラーを返す。

    2. requestresponse taintingを"opaque"に設定する。

    3. スキームフェッチfetchParamsで実行した結果を返す。

    requestcurrent URLschemeHTTP(S)スキームでない

    ネットワークエラーを返す。

    requestuse-CORS-preflight flagがセットされている
    requestunsafe-request flagがセットされていて、かつrequestmethodCORS安全リストメソッドでない、またはCORS安全でないリクエストヘッダー名requestheader list空でない
    1. requestresponse taintingを"cors"に設定する。

    2. corsWithPreflightResponseHTTPフェッチfetchParamsとtrueで実行した結果を設定する。

    3. corsWithPreflightResponseネットワークエラーであれば、キャッシュエントリをクリアrequestで実行する。

    4. corsWithPreflightResponseを返す。

    その他
    1. requestresponse taintingを"cors"に設定する。

    2. HTTPフェッチfetchParamsで実行した結果を返す。

  13. recursiveがtrueであれば、responseを返す。

  14. responseネットワークエラーでなく、かつresponseフィルタ済みレスポンスでなければ、以下を実行する:

    1. requestresponse taintingが"cors"であれば、以下を実行する:

      1. headerNamesヘッダーリスト値の抽出を`Access-Control-Expose-Headers`とresponseheader listで実行した結果を設定する。

      2. requestcredentials modeが"include"でなく、かつheaderNamesが`*`を含んでいれば、responseCORS公開ヘッダー名リストresponseheader listに含まれるすべての一意なヘッダーを設定する。

      3. それ以外でheaderNamesがnullまたは失敗でなければ、responseCORS公開ヘッダー名リストheaderNamesを設定する。

        headerNamesのうち1つは`*`である場合がありますが、この時点ではヘッダーが`*`の場合のみ一致します。

    2. 以下に応じてresponseresponse内部レスポンスとするフィルタ済みレスポンスに設定する:

      "basic"
      基本フィルタ済みレスポンス
      "cors"
      CORSフィルタ済みレスポンス
      "opaque"
      不透明フィルタ済みレスポンス
  15. internalResponseresponseを設定する。ただしresponseネットワークエラーならresponse、それ以外ならresponse内部レスポンスを設定する。

  16. internalResponseURLリストであれば、requestURLリスト複製を設定する。

    レスポンスURLリストは空の場合があり、例えばabout:URLのフェッチ時などです。

  17. internalResponseリダイレクト汚染requestredirect-taintを設定する。

  18. requesttiming allow failed flagが未設定なら、internalResponsetiming allow passed flagを設定する。

  19. responseネットワークエラーでなく、かつ下記のどれかがblockedを返す場合

    この場合responseinternalResponseネットワークエラーに設定する。

  20. responsetypeが"opaque"で、internalResponsestatusが206で、internalResponserange-requested flagがセットされていて、かつrequestheader list`Range`を含まない場合、responseinternalResponseネットワークエラーに設定する。

    従来、APIは範囲指定がなくても範囲レスポンスを受け入れます。これは、以前の範囲リクエストからの部分レスポンスがAPIに提供されることを防ぎます。

    詳細

    上記の手順は以下の攻撃を防ぎます:

    メディア要素でクロスオリジンHTMLリソースの範囲をリクエストします(これは無効なメディア)。ただしレスポンスのクローン参照をService Workerに保持できます。後でこの部分レスポンスをscript要素のfetchレスポンスとして利用できます。もし部分レスポンスが有効なJavaScriptなら(リソース全体はそうでなくても)、実行するとプライベートデータが漏洩します。

  21. responseネットワークエラーでなく、かつrequestmethodが`HEAD`または`CONNECT`である、またはinternalResponsestatusnullボディステータスであれば、internalResponsebodyをnullに設定し、以降のエンキューは無視する。

    この処理はHTTP違反サーバへのエラー処理の標準化です。

  22. requestintegrity metadataが空文字列でなければ、以下を実行する:

    1. processBodyErrorにこの手順:fetch response handoverfetchParamsネットワークエラーで実行する。

    2. responsebodyがnullならprocessBodyErrorを実行し、以降の手順を中止する。

    3. processBodybytesを受け取った場合の手順を設定する:

      1. bytes一致しない場合、requestintegrity metadataに、processBodyErrorを実行し以降の手順を中止する。[SRI]

      2. responsebodybytesボディとしてを設定する。

      3. fetch response handoverfetchParamsresponseで実行する。

    4. 完全に読み取るresponsebodyに対してprocessBodyprocessBodyErrorで実行する。

  23. それ以外の場合、fetch response handoverfetchParamsresponseで実行する。


フェッチレスポンス引き渡しは、フェッチパラメータfetchParamsレスポンスresponseを指定して、以下の手順を実行します:

  1. timingInfofetchParamsタイミング情報を設定する。

  2. responseネットワークエラーでなく、かつfetchParamsrequestclientセキュアコンテキストなら、timingInfoserver-timing headersresponse内部レスポンスヘッダーリストから`Server-Timing`を取得・デコード・分割した結果を設定する。

    response内部レスポンスを用いるのは安全です。`Server-Timing`ヘッダー情報の公開は`Timing-Allow-Origin`ヘッダーによって制御されます。

    ユーザーエージェントは非セキュアコンテキストのリクエストにも`Server-Timing`ヘッダーを公開する場合があります。

  3. fetchParamsrequestdestinationが"document"であれば、fetchParamscontrollerfull timing infofetchParamsタイミング情報を設定する。

  4. processResponseEndOfBodyに以下の手順を設定する:

    1. unsafeEndTimeunsafe shared current timeを設定する。

    2. fetchParamscontrollerreport timing stepsに、グローバルオブジェクトglobalを受け取る手順として以下を設定する:

      1. fetchParamsrequestURLschemeHTTP(S)スキームでなければreturnする。

      2. timingInfoend timerelative high resolution timeunsafeEndTime, globalを指定)で設定する。

      3. cacheStateresponsecache stateを設定する。

      4. bodyInforesponsebody infoを設定する。

      5. responsetiming allow passed flagが未設定なら、timingInfo不透明タイミング情報の作成timingInfoを指定)の結果を設定し、cacheStateを空文字列に設定する。

        これはresponseネットワークエラーの場合を含みます。

      6. responseStatusを0に設定する。

      7. fetchParamsrequestmodeが"navigate"でない、またはresponseredirect taintが"same-origin"であれば:

        1. responseStatusresponsestatusを設定する。

        2. mimeTypeMIMEタイプの抽出responseheader listを指定)の結果を設定する。

        3. mimeTypeが失敗でなければ、bodyInfocontent typeサポートされているMIMEタイプの最小化mimeType)の結果を設定する。

      8. fetchParamsrequestinitiator typeがnullでなければ、mark resource timingtimingInfo, fetchParamsrequestURL, fetchParamsrequestinitiator type, global, cacheState, bodyInfo, responseStatus)を実行する。

    3. processResponseEndOfBodyTaskに以下の手順を設定する:

      1. fetchParamsrequestdone flagを設定する。

      2. fetchParamsprocess response end-of-bodyがnullでなければ、fetchParamsprocess response end-of-bodyresponse)を実行する。

      3. fetchParamsrequestinitiator typeがnullでなく、かつfetchParamsrequestclientグローバルオブジェクトfetchParamstask destinationであれば、fetchParamscontrollerreport timing stepsfetchParamsrequestclientグローバルオブジェクト)を実行する。

    4. フェッチタスクをキューし、processResponseEndOfBodyTaskfetchParamstask destinationで実行する。

  5. fetchParamsprocess responseがnullでなければ、フェッチタスクをキューし、fetchParamsprocess responseresponse)をfetchParamstask destinationで実行する。

  6. internalResponseresponseを設定する。ただしresponseネットワークエラーならresponse、それ以外ならresponse内部レスポンスを設定する。

  7. internalResponsebodyがnullなら、processResponseEndOfBodyを実行する。

  8. それ以外の場合:

    1. transformStreamに新しいTransformStreamを設定する。

    2. identityTransformAlgorithmに、chunkを受け取ったときtransformStreamchunkenqueueするアルゴリズムを設定する。

    3. transformStreamのセットアップを行い、transformAlgorithmidentityTransformAlgorithmに、flushAlgorithmprocessResponseEndOfBodyに設定する。

    4. internalResponsebodystreamに、internalResponsebodystreampipe throughした結果をtransformStreamで設定する。

    このTransformStreamは、ストリームの終端到達時の通知目的で必要です。それ以外は恒等変換ストリームです。

  9. fetchParamsprocess response consume bodyがnullでなければ、以下を実行する:

    1. processBodynullOrBytesを受け取ったときfetchParamsprocess response consume bodyresponse, nullOrBytes)を実行する手順を設定する。

    2. processBodyErrorfetchParamsprocess response consume bodyresponse, failure)を実行する手順を設定する。

    3. internalResponsebodyがnullなら、フェッチタスクをキューし、processBody(null)をfetchParamstask destinationで実行する。

    4. それ以外の場合、完全に読み取るinternalResponsebodyに対してprocessBody, processBodyError, fetchParamstask destinationで実行する。

4.2. スキームフェッチ

スキームフェッチするには、フェッチパラメータfetchParamsを指定して以下を実行する:

  1. fetchParamsキャンセル済みなら、fetchParamsに対する適切なネットワークエラーを返す。

  2. requestfetchParamsrequestを設定する。

  3. requestcurrent URLschemeに応じて下記を実行:

    "about"

    requestcurrent URLpathが"blank"なら、新しいレスポンスstatus messageが`OK`、header listが« (`Content-Type`, `text/html;charset=utf-8`) »、bodyが空バイト列ボディとして)を返す。

    URL(例: "about:config")はナビゲーション中に処理され、フェッチング時にはネットワークエラーとなる。

    "blob"
    1. blobURLEntryrequestcurrent URLblob URLエントリを設定する。

    2. requestmethodが`GET`でない、またはblobURLEntryがnullならネットワークエラーを返す。[FILEAPI]

      `GET`メソッドの制限は相互運用のためのみで有用性はない。

    3. requestEnvironment環境決定request)の結果を設定する。

    4. isTopLevelNavigationrequestdestinationが"document"ならtrue、そうでなければfalseを設定する。

    5. isTopLevelNavigationがfalseかつrequestEnvironmentがnullならネットワークエラーを返す。

    6. navigationOrEnvironmentisTopLevelNavigationがtrueなら文字列"navigation"、そうでなければrequestEnvironmentを設定する。

    7. blobblobオブジェクト取得blobURLEntry, navigationOrEnvironment)の結果を設定する。

    8. blobBlobでなければネットワークエラーを返す。

    9. responseに新しいレスポンスを設定する。

    10. fullLengthblobsizeを設定する。

    11. serializedFullLengthfullLength直列化同型エンコードした値を設定する。

    12. typeblobtypeを設定する。

    13. requestheader list`Range`を含まない場合:

      1. bodyWithType安全抽出blob)の結果を設定する。

      2. responsestatus messageを`OK`に設定する。

      3. responsebodybodyWithTypebodyを設定する。

      4. responseheader listに« (`Content-Length`, serializedFullLength), (`Content-Type`, type) »を設定する。

    14. それ以外の場合:

      1. responserange-requested flagを設定する。

      2. rangeHeader取得(`Range`, requestheader list)の結果を設定する。

      3. rangeValue単一レンジヘッダー値解析rangeHeader, true)の結果を設定する。

      4. rangeValueが失敗ならネットワークエラーを返す。

      5. (rangeStart, rangeEnd)にrangeValueを設定する。

      6. rangeStartがnullなら:

        1. rangeStartfullLengthrangeEndを設定する。

        2. rangeEndrangeStart + rangeEnd − 1を設定する。

      7. それ以外の場合:

        1. rangeStartfullLength以上ならネットワークエラーを返す。

        2. rangeEndがnullまたはfullLength以上ならrangeEndfullLength − 1を設定する。

      8. slicedBlobスライスblobblob, rangeStart, rangeEnd + 1, type)の結果を設定する。

        Rangeヘッダーは両端含むバイト範囲だが、slice blobアルゴリズムは非包含なのでrangeEndを+1する必要あり。

      9. slicedBodyWithType安全抽出slicedBlob)の結果を設定する。

      10. responsebodyslicedBodyWithTypebodyを設定する。

      11. serializedSlicedLengthslicedBlobsize直列化同型エンコードした値を設定する。

      12. contentRangeContent-Range構築rangeStart, rangeEnd, fullLength)の結果を設定する。

      13. responsestatusを206に設定する。

      14. responsestatus messageを`Partial Content`に設定する。

      15. responseheader listに« (`Content-Length`, serializedSlicedLength), (`Content-Type`, type), (`Content-Range`, contentRange) »を設定する。

    15. responseを返す。

    "data"
    1. dataURLStructdata:URLプロセッサrequestcurrent URL)の結果を設定する。

    2. dataURLStructが失敗ならネットワークエラーを返す。

    3. mimeTypedataURLStructMIME type直列化したものを設定する。

    4. 新しいレスポンスstatus messageが`OK`、header listが« (`Content-Type`, mimeType) »、bodydataURLStructbodyボディとして)を返す。

    "file"

    現段階ではfile:URLは読者の演習に委ねます。

    不明な場合はネットワークエラーを返すこと。

    HTTP(S)スキーム

    HTTPフェッチfetchParams)の結果を返す。

  4. ネットワークエラーを返す。

環境決定は、リクエストrequestに対して以下を実行する:

  1. requestreserved clientがnullでなければ、requestreserved clientを返す。

  2. requestclientがnullでなければ、requestclientを返す。

  3. nullを返す。

4.3. HTTPフェッチ

HTTPフェッチするには、フェッチパラメータfetchParamsとオプションのブール値makeCORSPreflight(デフォルトはfalse)を指定して、以下の手順を実行する:

  1. requestfetchParamsrequestを設定する。

  2. responseinternalResponseをnullに設定する。

  3. requestservice-workers modeが"all"なら:

    1. requestForServiceWorkerrequestクローンを設定する。

    2. requestForServiceWorkerbodyがnullでなければ:

      1. transformStreamに新しいTransformStreamを設定する。

      2. transformAlgorithmchunkを受け取ったときの以下の手順を設定する:

        1. fetchParamsキャンセル済みなら以降を中止する。

        2. chunkUint8ArrayでなければfetchParamscontrollerterminateする。

        3. それ以外の場合、enqueuechunktransformStreamに追加する。ユーザーエージェントはchunkを実装定義のサイズに分割し、それぞれenqueueしても良い。あるいはchunkを実装定義のサイズに連結してenqueueしても良い。

      3. transformStreamのセットアップを行い、transformAlgorithmtransformAlgorithmに設定する。

      4. requestForServiceWorkerbodystreamに、requestForServiceWorkerbodystreampipe throughした結果をtransformStreamで設定する。

    3. serviceWorkerStartTime粗化された共有現在時刻fetchParamscross-origin isolated capability)を設定する。

    4. responsehandle fetchrequestForServiceWorkerfetchParamscontrollercross-origin isolated capability)の結果を設定する。[HTML] [SW]

    5. responseがnullでなければ:

      1. fetchParamstiming infofinal service worker start timeserviceWorkerStartTimeを設定する。

      2. requestbodyがnullでなければcancelrequestbody、undefined)を実行する。

      3. internalResponseresponseフィルタ済みレスポンスでなければresponse、そうであればresponse内部レスポンスを設定する。

      4. 以下のいずれかがtrueなら:

        • responsetypeが"error"である

        • requestmodeが"same-origin"で、かつresponsetypeが"cors"である

        • requestmodeが"no-cors"でなく、かつresponsetypeが"opaque"である

        • requestredirect modeが"manual"でなく、かつresponsetypeが"opaqueredirect"
        • requestredirect modeが"follow"でなく、かつresponseURLリストが2つ以上ある

        この場合ネットワークエラーを返す。

  4. responseがnullなら:

    1. makeCORSPreflightがtrueで、以下のいずれかがtrueなら:

      この場合:

      1. preflightResponseCORSプリフライトフェッチrequest)の結果を設定する。

      2. preflightResponseネットワークエラーならpreflightResponseを返す。

      この手順はCORSプリフライトキャッシュを確認し、適切なエントリがなければCORSプリフライトフェッチを実施し、成功すればキャッシュを更新する。CORSプリフライトフェッチの目的は取得したリソースがCORSプロトコルを理解しているか確認すること。キャッシュはCORSプリフライトフェッチを最小限にするためにある。

    2. requestredirect modeが"follow"ならrequestservice-workers modeを"none"に設定する。

      ネットワーク由来のリダイレクト(Service Worker由来でない)はService Workerに露出してはならない。

    3. HTTP-network-or-cache fetchfetchParams)の結果をresponseinternalResponseに設定する。

    4. requestresponse taintingが"cors"で、CORSチェックrequest, response)が失敗ならネットワークエラーを返す。

      CORSチェックは304/407ステータスやService Worker由来レスポンスには適用されないが、ここでは適用する。

    5. TAOチェックrequest, response)が失敗ならrequesttiming allow failed flagを設定する。

  5. requestresponse tainting、またはresponsetypeが"opaque"で、かつcross-origin resource policy checkrequestoriginrequestclientrequestdestinationinternalResponse)がblockedを返す場合、ネットワークエラーを返す。

    cross-origin resource policy checkはネットワーク由来とService Worker由来両方のレスポンスに適用される。CORSチェックとは異なり、requestclientとService Workerは埋め込みポリシーが異なる可能性がある。

  6. internalResponsestatusリダイレクトステータスなら:

    1. internalResponsestatusが303以外で、requestbodyがnullでなく、かつconnectionがHTTP/2を使う場合、ユーザーエージェントはRST_STREAMフレームを送信してもよい(推奨)。

      303は一部コミュニティで特別視されるため除外されている。

    2. requestredirect modeにより下記を実行:

      "error"
      1. responseネットワークエラーを設定する。

      "manual"
      1. requestmodeが"navigate"ならfetchParamscontrollernext manual redirect stepsHTTP-redirect fetchfetchParams, response)を設定する。

      2. それ以外の場合、responseopaque-redirectフィルタ済みレスポンス(内部レスポンスがinternalResponse)を設定する。

      "follow"
      1. responseHTTP-redirect fetchfetchParams, response)の結果を設定する。

  7. responseを返す。通常はinternalResponsebodystreamへのenqueueは返却後も継続している。

4.4. HTTPリダイレクトフェッチ

HTTPリダイレクトフェッチは、フェッチパラメータfetchParamsレスポンスresponseを指定して以下を実行します:

  1. requestfetchParamsrequestを設定する。

  2. internalResponseresponseフィルタ済みレスポンスでなければresponse、そうであればresponse内部レスポンスを設定する。

  3. locationURLinternalResponselocation URLrequestcurrent URLfragmentを指定)を設定する。

  4. locationURLがnullならresponseを返す。

  5. locationURLが失敗ならネットワークエラーを返す。

  6. locationURLschemeHTTP(S)スキームでなければネットワークエラーを返す。

  7. requestredirect countが20ならネットワークエラーを返す。

  8. requestredirect countを1増やす。

  9. requestmodeが"cors"で、locationURL資格情報を含むで、requestoriginlocationURLorigin同一オリジンでなければネットワークエラーを返す。

  10. requestresponse taintingが"cors"で、locationURL資格情報を含むならネットワークエラーを返す。

    これはクロスオリジンリソースが同一オリジンURLへリダイレクトする場合を捕捉します。

  11. internalResponsestatusが303以外で、requestbodyがnullでなく、かつrequestbodysourceがnullならネットワークエラーを返す。

  12. 以下のいずれかがtrueなら:

    • internalResponsestatusが301または302で、requestmethodが`POST`

    • internalResponsestatusが303で、requestmethodが`GET`または`HEAD`でない

    この場合:

    1. requestmethodを`GET`に、requestbodyをnullに設定する。

    2. headerNamerequest-body-header name)についてrequestheader listから削除する。

  13. requestcurrent URLoriginlocationURLorigin同一オリジンでなければ、headerNameCORS非ワイルドカードリクエストヘッダー名)についてrequestheader listから削除する。

    初回リクエスト以降に他のオリジンが現れた時点で`Authorization`ヘッダーは削除されます。

  14. requestbodyがnullでなければ、requestbodybody安全抽出requestbodysource)の結果)を設定する。

    requestbodysourceがnullかどうかはすでに判定済みです。

  15. timingInfofetchParamstiming infoを設定する。

  16. timingInforedirect end timepost-redirect start time粗化された共有現在時刻fetchParamscross-origin isolated capability)を設定する。

  17. timingInforedirect start timeが0なら、timingInforedirect start timetimingInfostart timeを設定する。

  18. locationURLrequestURLリストに追加する。

  19. リダイレクト時のreferrer policy設定requestinternalResponseで実行する。[REFERRER]

  20. recursiveにtrueを設定する。

  21. requestredirect modeが"manual"なら:

    1. アサートrequestmodeが"navigate"である。

    2. recursiveをfalseに設定する。

  22. メインフェッチfetchParams, recursive)の結果を返す。

    これはrequestresponse taintingを正しくするためにメインフェッチを呼び出す必要があります。

4.5. HTTPネットワークまたはキャッシュフェッチ

HTTPネットワークまたはキャッシュフェッチは、フェッチパラメータfetchParams、オプションのブール値isAuthenticationFetch(デフォルトはfalse)、オプションのブール値isNewConnectionFetch(デフォルトはfalse)を指定して以下を実行します:

一部の実装ではHTTPキャッシュに従って部分コンテンツのキャッシュをサポートする場合がありますが、ブラウザのキャッシュでは広くサポートされていません。 [HTTP-CACHING]

  1. requestfetchParamsrequestを設定する。

  2. httpFetchParamsをnullに設定する。

  3. httpRequestをnullに設定する。

  4. responseをnullに設定する。

  5. storedResponseをnullに設定する。

  6. httpCacheをnullに設定する。

  7. revalidatingFlagを未設定にする。

  8. 以下の手順を実行するが、abort when fetchParamsキャンセル済みの場合は中止する:

    1. requesttraversable for user promptsが"no-traversable"で、かつrequestredirect modeが"error"なら、httpFetchParamsfetchParamshttpRequestrequestに設定する。

    2. それ以外の場合:

      1. httpRequestrequestクローンを設定する。

        実装はrequestbodystreamをteeすることを避けることが推奨されます。requestbodysourceがnullの場合、単一ボディで十分です。例:bodyのsourceがnullの場合、リダイレクトや認証はフェッチ失敗となります。

      2. httpFetchParamsfetchParamsのコピーを設定する。

      3. httpFetchParamsrequesthttpRequestを設定する。

      ユーザープロンプトやリダイレクトが発生する場合、ユーザーの応答やリダイレクト先が決まった後で再送する必要があるため、元のリクエストボディが部分的に送信されている場合を考慮して、事前にリクエスト(ボディ含む)を複製して予備を持っておく必要があります。

    3. includeCredentialsを以下いずれかがtrueならtrue、それ以外ならfalseに設定:

      がtrueの場合のみtrue。

    4. Cross-Origin-Embedder-Policyがcredentialsを許可するかrequest)がfalseならincludeCredentialsをfalseに設定する。

    5. contentLengthhttpRequestbodylength(bodyがnullでなければ)を設定し、そうでなければnull。

    6. contentLengthHeaderValueをnullに設定する。

    7. httpRequestbodyがnullで、かつhttpRequestmethodが`POST`または`PUT`なら、contentLengthHeaderValueに`0`を設定する。

    8. contentLengthがnullでなければ、contentLengthHeaderValuecontentLength直列化同型エンコードしたものを設定する。

    9. contentLengthHeaderValueがnullでなければ、Content-Length(value:contentLengthHeaderValue)をhttpRequestheader listに追加する。

    10. contentLengthがnullでなく、かつhttpRequestkeepaliveがtrueなら:

      1. inflightKeepaliveBytesを0に設定する。

      2. grouphttpRequestclientfetch groupを設定する。

      3. inflightRecordsgroup内でfetch recordのうち、requestのkeepaliveがtrue・done flagが未設定のものの集合を設定する。

      4. fetchRecordinflightRecordsの要素)について:

        1. inflightRequestfetchRecordrequestを設定する。

        2. inflightKeepaliveBytesinflightRequestbodylengthを加算する。

      5. contentLengthinflightKeepaliveBytesが64KiBを超える場合はネットワークエラーを返す。

      上記の制限により、bodyを持ち環境設定オブジェクトの存続後も生存できるリクエストのサイズが制限され、無限に生存するのを防ぎます。

    11. httpRequestreferrerURLなら:

      1. referrerValuehttpRequestreferrer直列化同型エンコードしたものを設定する。

      2. RefererreferrerValue)をhttpRequestheader listに追加する。

    12. OriginヘッダーをhttpRequestに追加する。

    13. FetchメタデータヘッダーhttpRequestに追加する。 [FETCH-METADATA]

    14. httpRequestinitiatorが"prefetch"なら、Sec-Purpose(値:token prefetch)をhttpRequestheader listに構造化フィールド値として設定する。

    15. httpRequestheader listUser-Agentを含まない場合、ユーザーエージェントはUser-Agentデフォルト値)をhttpRequestheader listに追加するべきです。

    16. httpRequestcache modeが"default"かつhttpRequestheader listIf-Modified-SinceIf-None-MatchIf-Unmodified-SinceIf-MatchIf-Rangeのいずれかを含む場合はhttpRequestcache modeを"no-store"に設定する。

    17. httpRequestcache modeが"no-cache"で、httpRequestprevent no-cache cache-control header modification flagが未設定、かつhttpRequestheader listCache-Controlを含まない場合は、Cache-Control(value:max-age=0)をhttpRequestheader listに追加する。

    18. httpRequestcache modeが"no-store"または"reload"なら:

      1. httpRequestheader listPragmaを含まない場合、Pragma(value:no-cache)をhttpRequestheader listに追加する。

      2. httpRequestheader listCache-Controlを含まない場合、Cache-Control(value:no-cache)をhttpRequestheader listに追加する。

    19. httpRequestheader listRangeを含む場合、Accept-Encoding(value:identity)をhttpRequestheader listに追加する。

      これはコンテンツ符号化を扱う際、符号化済みレスポンスの一部取得による失敗を回避します。

      さらに、多くのサーバーが非identity符号化を受け入れる場合Rangeヘッダーを無視する誤った実装があります。

    20. HTTPに従ってhttpRequestheader listを修正する。同名ヘッダーが既に存在する場合は追加しない。

      より規範的にしたい部分。ここでAccept-EncodingConnectionDNTHostヘッダーは必要なら追加される。

      AcceptAccept-CharsetAccept-Languageは含めてはいけない。

      AcceptAccept-Languageは既に含まれており(fetch()使用時は後者はデフォルトで含まれない)、Accept-Charsetは無駄。詳細はHTTPヘッダー階層分離参照。

    21. includeCredentialsがtrueなら:

      1. CookieヘッダーをhttpRequestに追加する。

      2. httpRequestheader listAuthorizationを含まない場合:

        1. authorizationValueをnullに設定する。

        2. httpRequestに対する認証エントリがあり、かつhttpRequestuse-URL-credentials flagが未設定またはhttpRequestcurrent URL資格情報を含まない場合、authorizationValue認証エントリを設定する。

        3. それ以外でhttpRequestcurrent URL資格情報を含むかつisAuthenticationFetchがtrueならauthorizationValuehttpRequestcurrent URLAuthorization値に変換)を設定する。

        4. authorizationValueがnullでなければ、Authorization(value:authorizationValue)をhttpRequestheader listに追加する。

    22. プロキシ認証エントリがあれば適切に利用する。

      これはhttpRequestcredentials modeには依存しません。

    23. httpCacheHTTPキャッシュパーティション判定httpRequest)の結果を設定する。

    24. httpCacheがnullならhttpRequestcache modeを"no-store"に設定する。

    25. httpRequestcache modeが"no-store"でも"reload"でもない場合:

      1. storedResponsehttpCacheからレスポンス選択(場合によって検証が必要)結果を設定する。詳細はHTTPキャッシュの「Constructing Responses from Caches」章参照。 [HTTP-CACHING]

        HTTPによりVaryヘッダーも考慮されます。

      2. storedResponseがnullでなければ:

        1. cache modeが"default"、かつstoredResponsestale-while-revalidate response、かつhttpRequestclientがnullでなければ:

          1. responsestoredResponseを設定する。

          2. responsecache stateを"local"に設定する。

          3. revalidateRequestrequestクローンを設定する。

          4. revalidateRequestcache modeを"no-cache"に設定する。

          5. revalidateRequestprevent no-cache cache-control header modification flagを設定する。

          6. revalidateRequestservice-workers modeを"none"に設定する。

          7. 並列で新しいfetch params(request:revalidateRequest)でメインフェッチを実行する。

            このフェッチはhttpCacheの状態更新のみが目的で、現在のリクエストへのレスポンスとしては利用されません。クライアント文脈で発行されるため、クライアントが消失すればリクエストも終了します。

        2. それ以外の場合:

          1. storedResponsestale responseならrevalidatingFlagを設定する。

          2. revalidatingFlagが設定済み、かつhttpRequestcache modeが"force-cache"でも"only-if-cached"でもない場合:

            1. storedResponseheader listETagを含む場合、If-None-Match(value:ETagの値)をhttpRequestheader listに追加する。

            2. storedResponseheader listLast-Modifiedを含む場合、If-Modified-Since(value:Last-Modifiedの値)をhttpRequestheader listに追加する。

            詳細はHTTPキャッシュの「Sending a Validation Request」章参照。 [HTTP-CACHING]

          3. それ以外の場合、responsestoredResponseを設定し、responsecache stateを"local"に設定する。

  9. もし中断された場合fetchParamsに対して適切なネットワークエラーを返す。

  10. responseがnullなら:

    1. httpRequestcache modeが"only-if-cached"ならネットワークエラーを返す。

    2. forwardResponseHTTPネットワークフェッチhttpFetchParamsincludeCredentialsisNewConnectionFetch)の結果を設定する。

    3. httpRequestmethodunsafeで、forwardResponsestatusが200〜399なら、httpCache内の適切な保存レスポンスをHTTPキャッシュ「Invalidating Stored Responses」章に従い無効化し、storedResponseをnullに設定する。 [HTTP-CACHING]

    4. revalidatingFlagが設定済み、かつforwardResponsestatusが304なら:

      1. storedResponseheader listforwardResponseheader listで更新する。詳細はHTTPキャッシュ「Freshening Stored Responses upon Validation」章参照。 [HTTP-CACHING]

        キャッシュ内の保存レスポンスも更新されます。

      2. responsestoredResponseを設定する。

      3. responsecache stateを"validated"に設定する。

    5. responseがnullなら:

      1. responseforwardResponseを設定する。

      2. httpRequestforwardResponseHTTPキャッシュ「Storing Responses in Caches」章に従いhttpCacheに保存する。 [HTTP-CACHING]

        forwardResponseネットワークエラーなら、これはいわゆる「ネガティブキャッシュ」としてエラーもキャッシュされます。

        関連するbody infoもレスポンスと一緒にキャッシュに保存されます。

  11. responseURLリストhttpRequestURLリスト複製を設定する。

  12. httpRequestheader listRangeを含む場合、responserange-requested flagを設定する。

  13. responserequest-includes-credentialsincludeCredentialsを設定する。

  14. responsestatusが401、かつhttpRequestresponse taintingが"cors"でなく、includeCredentialsがtrue、かつrequesttraversable for user promptstraversable navigableの場合:

    1. 要検証:複数WWW-Authenticateヘッダー、欠落、パース問題。

    2. requestbodyがnullでなければ:

      1. requestbodysourceがnullならネットワークエラーを返す。

      2. requestbodybody安全抽出requestbodysource)の結果)を設定する。

    3. requestuse-URL-credentials flagが未設定、またはisAuthenticationFetchがtrueなら:

      1. fetchParamsキャンセル済みならfetchParamsに対する適切なネットワークエラーを返す。

      2. usernamepasswordrequesttraversable for user promptsでエンドユーザーに入力を促して取得する。

      3. set the usernamerequestcurrent URL, username)を実行する。

      4. set the passwordrequestcurrent URL, password)を実行する。

    4. responseHTTPネットワークまたはキャッシュフェッチfetchParams, true)を実行した結果を設定する。

  15. responsestatusが407の場合:

    1. requesttraversable for user promptsが"no-traversable"ならネットワークエラーを返す。

    2. 要検証:複数Proxy-Authenticateヘッダー、欠落、パース問題。

    3. fetchParamsキャンセル済みならfetchParamsに対する適切なネットワークエラーを返す。

    4. requesttraversable for user promptsで適切にユーザー入力を促し、proxy-authentication entryとして保存する。[HTTP]

      プロキシ認証に関する追加詳細はHTTPで定義されています。

    5. responseHTTPネットワークまたはキャッシュフェッチfetchParams)の結果を設定する。

  16. 以下すべてがtrueの場合:

    • responsestatusが421

    • isNewConnectionFetchがfalse

    • requestbodyがnull、またはrequestbodyがnullでなくrequestbodysourceがnullでない

    この場合:

    1. fetchParamsキャンセル済みならfetchParamsに対する適切なネットワークエラーを返す。

    2. responseHTTPネットワークまたはキャッシュフェッチfetchParamsisAuthenticationFetch、true)の結果を設定する。

  17. isAuthenticationFetchがtrueならrequestとrealmに対する認証エントリを作成する。

  18. responseを返す。通常はresponsebodystreamへのenqueueは返却後も継続している。

4.6. HTTPネットワークフェッチ

HTTPネットワークフェッチは、フェッチパラメータfetchParams、オプションのブール値includeCredentials(デフォルトfalse)、オプションのブール値forceNewConnection(デフォルトfalse)を指定して以下を実行します:

  1. requestfetchParamsrequestを設定する。

  2. responseをnullに設定する。

  3. timingInfofetchParamsタイミング情報を設定する。

  4. networkPartitionKeyネットワークパーティションキー決定request)の結果を設定する。

  5. newConnectionforceNewConnectionがtrueなら"yes"、そうでなければ"no"を設定する。

  6. requestmodeに応じて分岐:

    "websocket"

    connectionWebSocket接続取得requestcurrent URL)の結果を設定する。

    それ以外

    connection接続取得networkPartitionKeyrequestcurrent URLincludeCredentialsnewConnection)の結果を設定する。

  7. 以下の手順を実行するが、abort when fetchParamsキャンセル済みの場合は中止する:

    1. connectionが失敗ならネットワークエラーを返す。

    2. timingInfofinal connection timing info接続タイミング情報のクランプ・粗化connectiontiming infotimingInfopost-redirect start timefetchParamscross-origin isolated capability)の結果を設定する。

    3. connectionがHTTP/1.x接続で、requestbodyがnullでなく、かつrequestbodysourceがnullならネットワークエラーを返す。

    4. timingInfofinal network-request start time粗化された共有現在時刻fetchParamscross-origin isolated capability)を設定する。
    5. connection上でrequestを使ってHTTPリクエストを行い、responseを設定する。ただし下記の注意点あり:

      FetchとHTTPのレイヤリングは今後整理が必要で、この時点ではresponseが両方の意味を持ちます。

      HTTPリクエストがTLSクライアント証明書ダイアログを要求した場合:

      1. requesttraversable for user promptstraversable navigableなら、そのダイアログをrequesttraversable for user promptsで利用可能にする。

      2. それ以外の場合、ネットワークエラーを返す。

      requestbodybody)の送信は以下の手順で実行:

      1. bodyがnullかつfetchParamsprocess request end-of-bodyがnullでなければ、fetchタスクをキューし、fetchParamsprocess request end-of-bodyfetchParamstask destinationで実行する。

      2. それ以外でbodyがnullでなければ:

        1. processBodyChunkbytes)で以下の手順:

          1. fetchParamsキャンセル済みなら中止。

          2. 並列bytesを送信。

          3. fetchParamsprocess request body chunk lengthがnullでなければ、fetchParamsprocess request body chunk lengthbyteslengthで実行。

        2. processEndOfBodyで以下の手順:

          1. fetchParamsキャンセル済みなら中止。

          2. fetchParamsprocess request end-of-bodyがnullでなければ、fetchParamsprocess request end-of-bodyを実行。

        3. processBodyErrore)で以下の手順:

          1. fetchParamsキャンセル済みなら中止。

          2. eが"AbortError"DOMExceptionならfetchParamscontrollerabortする。

          3. それ以外の場合、fetchParamscontrollerterminateする。

        4. incrementally readrequestbodyprocessBodyChunkprocessEndOfBodyprocessBodyErrorfetchParamstask destination)で実行。

  8. もし中断された場合

    1. connectionがHTTP/2ならRST_STREAMフレームを送信。

    2. fetchParamsに対する適切なネットワークエラーを返す。

  9. bufferに空のバイト列を設定する。

    これはユーザーエージェントのネットワーク層内部バッファを表します。

  10. streamに新しい新規ReadableStreamを設定する。

  11. pullAlgorithmに以下の手順を設定する:

    1. promise新しいpromiseを設定する。

    2. 並列で以下を実行:

      1. bufferのサイズがユーザーエージェント選択の下限より小さく、かつ進行中のフェッチが一時停止中なら再開する。

      2. bufferが空でなくなるまで待つ。

      3. fetchタスクをキューし、以下の手順をfetchParamstask destinationで実行:

        1. Pull from bytesbufferstreamに転送。

        2. streamエラーならfetchParamscontrollerterminateする。

        3. resolvepromiseをundefinedで解決。

    3. promiseを返す。

  12. cancelAlgorithmreasonを受け取ったときfetchParamscontrollerabortするアルゴリズムを設定する。

  13. byte読み取り対応でstreamセットアップを行い、pullAlgorithmcancelAlgorithmを設定する。

  14. responsebodyに新しいbodystreamstream)を設定する。

  15. (This is a tracking vector.) includeCredentialsがtrueなら、ユーザーエージェントはrequestresponseSet-Cookieヘッダー解析・保存を行うべきです。

  16. 並列で以下を実行:

    1. abort when fetchParamsキャンセル済みの場合は中止しつつ以下を実行:

      1. 以下を繰り返す:

        1. responseのメッセージボディから1バイト以上送信された場合:

          1. bytesに送信済みバイトを設定。

          2. codingsheader list値抽出Content-Encodingresponseheader list)の結果を設定。

          3. filteredCodingに"@unknown"を設定。

          4. codingsがnullまたは失敗ならfilteredCodingを空文字列に設定。

          5. それ以外でcodingssizeが1を超える場合filteredCodingを"multiple"に設定。

          6. それ以外でcodings[0]が空文字列か、ユーザーエージェントがサポートし、HTTP Content Coding Registryのエントリとバイト大文字小文字無視で一致する場合、filteredCodingバイト小文字化codings[0])の結果を設定。 [IANA-HTTP-PARAMS]

          7. responsebody infocontent encodingfilteredCodingを設定。

          8. responsebody infoencoded sizebyteslengthを加算。

          9. bytescontent codings処理codingsbytes)の結果を設定。

            これによりContent-Lengthヘッダーは信頼性が下がります。

          10. responsebody infodecoded sizebyteslengthを加算。

          11. bytesが失敗ならfetchParamscontrollerterminateする。

          12. bytesbufferに追加。

          13. bufferのサイズがユーザーエージェント選択の上限を超えた場合、進行中のフェッチを一時停止要求。

        2. それ以外で、responseのメッセージボディ送信が正常終了しstreamreadableなら、closeし、この並列手順を中止。

    2. もし中断された場合

      1. fetchParamsabortedなら:

        1. responseaborted flagを設定。

        2. streamreadableなら、errorstreamfetchParamscontrollerserialized abort reasonabort理由デシリアライズ(実装定義realm)でエラーに。

      2. それ以外でstreamreadableなら、errorTypeErrorのエラーに。

      3. connectionがHTTP/2ならRST_STREAMフレーム送信。

      4. それ以外の場合、パフォーマンス上悪くなければユーザーエージェントはconnectionをクローズすべき。

        例えば、再利用可能な接続で残り転送がごく少量の場合はクローズせず次のフェッチで再利用した方が良い場合もある。

    この一連は並列で実行され、現時点ではresponsebodyが有効か(リダイレクト等)不明なためです。

  17. responseを返す。通常はresponsebodystreamへのenqueueは返却後も継続しています。

4.7. CORSプリフライトフェッチ

これは、CORSプロトコルが理解されているかのチェックのユーザーエージェント実装に相当します。いわゆるCORSプリフライトリクエストです。成功した場合、CORSプリフライトキャッシュが更新され、これらのフェッチの回数を最小限にします。

CORSプリフライトフェッチは、リクエストrequestを指定して以下を実行します:

  1. preflightを新しいリクエストとして生成し、methodは`OPTIONS`、URLリストrequestURLリスト複製initiatorrequestinitiatordestinationrequestdestinationoriginrequestoriginreferrerrequestreferrerreferrer policyrequestreferrer policymodeは"cors"、response taintingは"cors"で設定する。

    preflightservice-workers modeは重要ではありません。このアルゴリズムはHTTPネットワークまたはキャッシュフェッチを用い、HTTPフェッチは使いません。

  2. Accept(`*/*`)をpreflightheader listに追加する。

  3. Access-Control-Request-Methodrequestmethod)をpreflightheader listに追加する。

  4. headersrequestheader listでのCORS安全でないリクエストヘッダー名を設定する。

  5. headers空でなければ

    1. valueheaders内の各要素を`,`で区切った文字列を設定する。

    2. Access-Control-Request-Headersvalue)をpreflightheader listに追加する。

    これは意図的にcombineを使いません。0x2C後の0x20は実装通りではないためです。

  6. responseに新しいfetch params(request: preflight)を使ってHTTPネットワークまたはキャッシュフェッチの結果を設定する。

  7. CORSチェックrequest, response)が成功し、responsestatusok statusなら:

    CORSチェックはpreflightでなくrequestで行い、正しいcredentials modeを使うようにします。

    1. methodsheader list値抽出Access-Control-Allow-Methodsresponseheader list)の結果を設定する。

    2. headerNamesheader list値抽出Access-Control-Allow-Headersresponseheader list)の結果を設定する。

    3. methodsまたはheaderNamesが失敗ならネットワークエラーを返す。

    4. methodsがnullかつrequestuse-CORS-preflight flagがセットされていれば、methodsに新しいリスト(requestmethod)を設定する。

      これはrequestuse-CORS-preflight flagにより行われたCORSプリフライトフェッチがキャッシュされるようにします。

    5. requestmethodmethodsに含まれず、requestmethodCORS安全リストメソッドでなく、かつrequestcredentials modeが"include"、またはmethodsに`*`が含まれていなければネットワークエラーを返す。

    6. requestheader listのいずれかのCORS非ワイルドカードリクエストヘッダー名で、かつheaderNamesのいずれのitemともバイト大文字小文字無視で一致しないならネットワークエラーを返す。

    7. unsafeNamerequestheader listでのCORS安全でないリクエストヘッダー名)について、unsafeNameheaderNames内のいずれのitemともバイト大文字小文字無視で一致せず、かつrequestcredentials modeが"include"、またはheaderNamesに`*`が含まれていなければネットワークエラーを返す。

    8. max-ageheader list値抽出Access-Control-Max-Ageresponseheader list)の結果を設定する。

    9. max-ageが失敗またはnullならmax-ageを5に設定する。

    10. max-age最大有効期間の上限を超えていればmax-ageを上限に設定する。

    11. ユーザーエージェントがキャッシュを提供しない場合、responseを返す。

    12. methods内でrequestを使ったメソッドキャッシュエントリ一致がある各methodについて、対応するエントリのmax-agemax-ageに設定する。

    13. methods内でrequestを使ったメソッドキャッシュエントリ一致がない各methodについて、新規キャッシュエントリ作成requestmax-agemethod、null)を実行する。

    14. headerNames内でrequestを使ったヘッダー名キャッシュエントリ一致がある各headerNameについて、対応するエントリのmax-agemax-ageに設定する。

    15. headerNames内でrequestを使ったヘッダー名キャッシュエントリ一致がない各headerNameについて、新規キャッシュエントリ作成requestmax-age、null、headerName)を実行する。

    16. responseを返す。

  8. それ以外の場合、ネットワークエラーを返す。

4.8. CORSプリフライトキャッシュ

ユーザーエージェントは関連付けられたCORSプリフライトキャッシュを持ちます。 CORSプリフライトキャッシュは、リストであり、キャッシュエントリのリストです。

キャッシュエントリは以下から構成されます:

キャッシュエントリは、 max-ageフィールドで指定された秒数が保存から経過した後に削除されなければなりません。 キャッシュエントリは、その時刻より前に削除される場合もあります。

新しいキャッシュエントリの作成は、requestmax-agemethodheaderNameを受け取り、以下を実行します:

  1. entryキャッシュエントリとして、以下のように初期化する:

    キー

    ネットワークパーティションキー決定request)の結果

    バイト列化オリジン

    リクエストオリジンのバイト列化request)の結果

    URL

    requestcurrent URL

    max-age

    max-age

    credentials

    requestcredentials modeが"include"のときtrue、そうでなければfalse

    method

    method

    header name

    headerName

  2. entryを追加をユーザーエージェントのCORSプリフライトキャッシュに実行する。

キャッシュエントリのクリアは、requestを受け取り、 削除をユーザーエージェントのCORSプリフライトキャッシュ内の 以下の条件を満たすキャッシュエントリに対して実行する: キーネットワークパーティションキー決定request)の結果と一致し、 バイト列化オリジンリクエストオリジンのバイト列化request)の結果と一致し、 URLrequestcurrent URLと一致する。

キャッシュエントリ一致は、キャッシュエントリentryrequestについて、以下が成立する場合に一致する: entryキーネットワークパーティションキー決定request)の結果と一致し、 entryバイト列化オリジンリクエストオリジンのバイト列化request)の結果と一致し、 entryURLrequestcurrent URLと一致し、かつ以下のいずれかが成立する場合:

が成立する。

メソッドキャッシュエントリ一致は、 methodrequestについて、ユーザーエージェントのCORSプリフライトキャッシュ内に キャッシュエントリ一致を満たし、methodmethodまたは`*`であるキャッシュエントリが存在する場合。

ヘッダー名キャッシュエントリ一致は、 headerNamerequestについて、ユーザーエージェントのCORSプリフライトキャッシュ内に キャッシュエントリ一致を満たし、かつ以下のいずれかが成立するキャッシュエントリが存在する場合:

が成立する。

4.9. CORSチェック

CORSチェックは、requestresponseについて以下を実行します:

  1. origin取得(`Access-Control-Allow-Origin`、responseheader list)の結果を設定する。

  2. originがnullならfailureを返す。

    nullは`null`文字列ではありません。

  3. requestcredentials modeが"include"でなく、originが`*`ならsuccessを返す。

  4. リクエストオリジンのバイト列化request)の結果がoriginと一致しなければfailureを返す。

  5. requestcredentials modeが"include"でなければsuccessを返す。

  6. credentials取得(`Access-Control-Allow-Credentials`、responseheader list)の結果を設定する。

  7. credentialsが`true`ならsuccessを返す。

  8. failureを返す。

4.10. TAOチェック

TAOチェックは、requestresponseについて以下を実行します:

  1. アサートrequestoriginが"client"でないこと。

  2. requesttiming allow failed flagがセットされていればfailureを返す。

  3. values取得・デコード・分割(`Timing-Allow-Origin`、responseheader list)の結果を設定する。

  4. valuesが`*`を含むならsuccessを返す。

  5. valuesリクエストオリジンのシリアライズrequest)の結果を含むならsuccessを返す。

  6. requestmodeが"navigate"で、requestcurrent URLoriginrequestorigin同一オリジンでなければfailureを返す。

    これは入れ子ナビゲーションのために必要です。この場合、requestoriginはコンテナドキュメントのoriginとなり、TAOチェックは失敗します。ナビゲーションタイミングはTAOチェックの結果を検証しないため、入れ子ドキュメントは完全なタイミング情報にアクセスできますが、コンテナドキュメントはできません。

  7. requestresponse taintingが"basic"ならsuccessを返す。

  8. failureを返す。

4.11. 遅延フェッチ

遅延フェッチは、呼び出し元がフェッチの実行時点をできるだけ遅く、つまりフェッチグループ終了される時、またはタイムアウト後などに呼び出すことを可能にします。

遅延フェッチタスクソースは、遅延フェッチの結果を更新するために使用されるタスクソースです。ユーザーエージェントは、このタスクソースのタスクを、他のタスクソース、特にスクリプト実行につながるDOM操作タスクソース等よりも優先して実行し、fetchLater()呼び出しの最新状態がそれに依存するスクリプトの実行前に反映されるようにしなければなりません。

遅延フェッチをキューするには、リクエストrequest、nullまたはDOMHighResTimeStampactivateAfter、そして引数なしのアルゴリズムonActivatedWithoutTerminationを指定して以下の手順を実行します:

  1. クライアントからリクエストを設定request)を実行する。

  2. requestservice-workers modeを"none"に設定する。

  3. requestkeepaliveをtrueに設定する。

  4. deferredRecordに新しい遅延フェッチレコードrequestrequestnotify invokedonActivatedWithoutTermination)を設定する。

  5. deferredRecordを追加requestclientfetch groupdeferred fetch recordsに実行する。

  6. activateAfterがnullでなければ、以下の手順を並列で実行する:

    1. ユーザーエージェントは以下いずれかの条件を満たすまで待つべきである:

    2. deferredRecordの処理を実行する。

  7. deferredRecordを返す。

総リクエスト長計算は、リクエストrequestに対して以下を実行する:

  1. totalRequestLengthrequestURL直列化exclude fragmentはtrue)した文字列の長さを設定する。

  2. totalRequestLengthrequestreferrer直列化した文字列の長さを加算する。

  3. (name, value)(requestheader listの要素)について、totalRequestLengthname長さvalue長さを加算する。

  4. totalRequestLengthrequestbodylengthを加算する。

  5. totalRequestLengthを返す。

遅延フェッチ群の処理は、フェッチグループfetchGroupに対して以下を実行する:

  1. deferred fetch recorddeferredRecordfetchGroupdeferred fetch recordsの要素)について、遅延フェッチの処理deferredRecord)を実行する。

遅延フェッチの処理deferredRecordに対して以下を実行します:

  1. deferredRecordinvoke stateが"pending"でなければreturnする。

  2. deferredRecordinvoke stateを"sent"に設定する。

  3. フェッチdeferredRecordrequest)を実行する。

  4. グローバルタスクをキューし、遅延フェッチタスクソース上で、deferredRecordrequestclientglobal object上でdeferredRecordnotify invokedを実行する。

4.11.1. 遅延フェッチのクォータ

この節は非規範的です。

遅延フェッチのクォータはトップレベル遷移可能(タブ)に割り当てられ、合計で640キビバイトです。トップレベル文書とその同一オリジンの直接ネスト文書は、このクォータを使って遅延フェッチをキューできます。また、パーミッションポリシーを使って一部をクロスオリジンのネスト文書へ委譲できます。

デフォルトでは、この640キビバイトのうち128キビバイトがクロスオリジンネスト文書への委譲用に割り当てられ、各文書は8キビバイトを予約します。

トップレベルの文書は、その後のネスト文書とともに、パーミッションポリシーを通じてクロスオリジン子文書へのクォータ委譲量を制御できます。デフォルトでは、"deferred-fetch-minimal"ポリシーは任意のオリジンで有効であり、"deferred-fetch"はトップレベル文書のオリジンだけで有効です。特定のオリジンやネスト文書に対して"deferred-fetch"ポリシーを緩和すれば、そのネスト文書へ最大64キビバイトを割り当てることが可能です。また、"deferred-fetch-minimal"ポリシーを特定のオリジンやネスト文書に対して制限することで、その文書がデフォルトで受け取る8キビバイトの予約を防ぐこともできます。トップレベル文書自身に対して"deferred-fetch-minimal"ポリシーを無効にすると、委譲された128キビバイトが元の640キビバイトプールに戻ります。

ある文書に割り当てられたクォータのうち、同じレポートオリジン(requestURLorigin)に同時利用できるのは64キビバイトまでです。これにより、特定のサードパーティライブラリがデータ送信前にクォータを機会主義的に予約するのを防ぎます。

以下のいずれかのfetchLater()呼び出しは、リクエスト自体がレポートオリジンに割り当てられた64キビバイトクォータを超えるためthrowされます。リクエストのサイズはURL自体、bodyheader listreferrerを含みます。

fetchLater(a_72_kb_url);
fetchLater("https://origin.example.com", {headers: headers_exceeding_64kb});
fetchLater(a_32_kb_url, {headers: headers_exceeding_32kb});
fetchLater("https://origin.example.com", {method: "POST", body: body_exceeding_64_kb});
fetchLater(a_62_kb_url /* with a 3kb referrer */);

次のシーケンスでは、最初の2つのリクエストは成功しますが、3つ目はthrowされます。最初の2回の呼び出しでは全体の640キビバイトクォータは超えていませんが、3つ目のリクエストはhttps://a.example.comのレポートオリジンクォータを超えるためthrowされます。

fetchLater("https://a.example.com", {method: "POST", body: a_64kb_body});
fetchLater("https://b.example.com", {method: "POST", body: a_64kb_body});
fetchLater("https://a.example.com");

同一オリジンのネスト文書は親のクォータを共有します。しかし、クロスオリジンやクロスエージェントiframeはデフォルトで8キビバイトしか割り当てられません。従って、以下の例では最初の3回の呼び出しは成功し、最後はthrowされます。

// メインページ内
fetchLater("https://a.example.com", {method: "POST", body: a_64kb_body});

// 同一オリジンのネスト文書内
fetchLater("https://b.example.com", {method: "POST", body: a_64kb_body});

// https://fratop.example.com のクロスオリジンネスト文書内
fetchLater("https://a.example.com", {body: a_5kb_body});
fetchLater("https://a.example.com", {body: a_12kb_body});

前述の例でthrowされないようにするには、トップレベル文書が例えば以下のヘッダーを送信してhttps://fratop.example.comへクォータを委譲します:

Permissions-Policy: deferred-fetch=(self "https://fratop.example.com")

各ネスト文書は自身のクォータを予約します。したがって、下記のように各フレームが8キビバイトずつ予約するため動作します:

// https://fratop.example.com/frame-1 のクロスオリジンネスト文書内
fetchLater("https://a.example.com", {body: a_6kb_body});

// https://fratop.example.com/frame-2 のクロスオリジンネスト文書内
fetchLater("https://a.example.com", {body: a_6kb_body});

以下のツリーは異なるネスト文書にクォータがどのように分配されるかを示します:

上記の例では、トップレベル遷移可能とその同一オリジンの子孫は384キビバイトのクォータを共有します。その値は以下のように計算されます:

この仕様は、文字列"deferred-fetch"で識別されるポリシー制御機能を定義します。そのデフォルト許可リストは"self"です。

この仕様は、文字列"deferred-fetch-minimal"で識別されるポリシー制御機能を定義します。そのデフォルト許可リストは"*"です。

deferred-fetch-minimal用に予約されたクォータは128キビバイトです。

ナビゲーション可能コンテナは関連付けられた数値遅延フェッチ用予約クォータを持ちます。その値はミニマルクォータ(8キビバイト)、ノーマルクォータ(0または64キビバイト)。特に記載がない場合は0です。

利用可能な遅延フェッチクォータ を、document document と、origin-または-null の origin を指定して取得するには:

  1. controlDocumentdocument遅延フェッチ制御文書を設定する。

  2. navigablecontrolDocumentノード遷移可能を設定する。

  3. isTopLevelcontrolDocumentノード遷移可能トップレベル遷移可能ならtrue、そうでなければfalseを設定する。

  4. deferredFetchAllowedcontrolDocumentが"deferred-fetch"ポリシー制御機能の利用を許可されていればtrue、そうでなければfalseを設定する。

  5. deferredFetchMinimalAllowedcontrolDocumentが"deferred-fetch-minimal"ポリシー制御機能の利用を許可されていればtrue、そうでなければfalseを設定する。

  6. quotaに最初に一致する条件の結果を設定する:

    isTopLevelがtrueかつdeferredFetchAllowedがfalse
    0
    isTopLevelがtrueかつdeferredFetchMinimalAllowedがfalse

    640キビバイト

    640kbはみんなに十分なはずです。

    isTopLevelがtrue

    512キビバイト

    デフォルト640キビバイトからdeferred-fetch-minimal用予約クォータ分を減算した値

    deferredFetchAllowedがtrueかつnavigableナビゲーション可能コンテナ遅延フェッチ用予約クォータノーマルクォータ
    ノーマルクォータ
    deferredFetchMinimalAllowedがtrueかつnavigableナビゲーション可能コンテナ遅延フェッチ用予約クォータミニマルクォータ
    ミニマルクォータ
    それ以外
    0
  7. quotaForRequestOriginに64キビバイトを設定する。

  8. navigablecontrolDocumentノード遷移可能包括的子孫遷移可能で、アクティブ文書遅延フェッチ制御文書controlDocumentであるもの)について:

    1. containernavigableアクティブ文書shadow-including包括的子孫のうちナビゲーション可能コンテナ)について、quotaからcontainer遅延フェッチ用予約クォータを減算する。

    2. deferred fetch recorddeferredRecordnavigableアクティブ文書関連設定オブジェクトfetch groupdeferred fetch records)について:

      1. requestLengthdeferredRecordrequest総リクエスト長を設定する。

      2. quotaからrequestLengthを減算する。

      3. deferredRecordrequestURLoriginorigin同一オリジンであれば、quotaForRequestOriginからrequestLengthを減算する。

  9. quotaが0以下なら0を返す。

  10. quotaquotaForRequestOrigin未満ならquotaを返す。

  11. quotaForRequestOriginを返す。

遅延フェッチクォータの予約は、ナビゲーション可能コンテナcontaineroriginoriginToNavigateToを指定して以下を実行します:

これはナビゲーション時、ナビゲーション元文書がnavigableの親文書である場合に呼ばれます。パーミッションポリシーで許可されていれば、コンテナおよびそのナビゲーション可能要素に最大64kbまたは8kbのクォータを予約します。予約されたクォータが実際に使われたかどうかはコンテナ文書から観測できません。このアルゴリズムは、コンテナの文書がナビゲート先コンテナにクォータを委譲する可能性があると仮定し、予約されたクォータはその場合のみ適用され、共有されることになった場合は無視されます。クォータが予約され、その文書が親と同一オリジンとなった場合、クォータは解放されます。

  1. container遅延フェッチ用予約クォータを0に設定する。

  2. controlDocumentcontainerノード文書遅延フェッチ制御文書を設定する。

  3. "deferred-fetch" の継承ポリシーcontainer, originToNavigateTo)が"Enabled"であり、controlDocument利用可能な遅延フェッチクォータノーマルクォータ以上であれば、container遅延フェッチ用予約クォータノーマルクォータに設定してreturnする。

  4. 以下すべてが真の場合:

    この場合、container遅延フェッチ用予約クォータミニマルクォータに設定する。

遅延フェッチクォータの解放(可能性あり)は、文書documentに対して、documentノード遷移可能コンテナ文書がnullでなく、かつそのorigindocument同一オリジンであれば、documentノード遷移可能navigable container遅延フェッチ用予約クォータを0に設定する。

これは文書が生成されたときに呼ばれます。同一オリジンのネスト文書は親クォータを共有するため予約しません。これは文書生成時のみ呼ばれ、originはリダイレクト処理後にのみ判明するためです。

遅延フェッチ制御文書の取得は、文書documentについて以下を実行する:

  1. documentノード遷移可能コンテナ文書がnullまたは、文書で、そのorigindocument同一オリジンでなければ、documentを返し、それ以外の場合はdocumentノード遷移可能コンテナ文書について再帰的に遅延フェッチ制御文書の取得を実行する。

5. Fetch API(フェッチAPI)

fetch()メソッドは、リソースの取得のための比較的低レベルなAPIです。現行標準ではXMLHttpRequestよりも少し広い範囲をカバーしますが、リクエスト進行状況(レスポンス進行状況ではなく)の点ではまだ不十分です。

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("全データをメモリに保持せずにボディ全体を消費しました!"))
  .catch(e => log("何か問題が発生しました: " + e))

5.1. Headersクラス

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>;
};

Headersオブジェクトは、関連付けられたヘッダーリストheader list)を持ち、初期状態は空です。これは、他のオブジェクト(例:request)のheader listへのポインタとなることもあります。

Headersオブジェクトには、さらに関連付けられたガードheaders guard)があります。headers guardは、"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);

// 上記と同等
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)

最初に一致したnameのヘッダー値をvalueに置換し、残りの同名ヘッダーは削除します。

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. バリデートname, value)がheadersでfalseなら、returnする。

  3. headersガードが"request-no-cors"なら:

    1. temporaryValueheadersheader listからname取得した結果を設定する。

    2. temporaryValueがnullなら、temporaryValuevalueに設定する。

    3. それ以外の場合、temporaryValuetemporaryValue+「, 」+valueに設定する。

    4. name, temporaryValue)がno-CORS安全リストリクエストヘッダーでない場合、returnする。

  4. 追加name, value)をheadersheader listに対して実行する。

  5. headersガードが"request-no-cors"なら、特権no-CORSリクエストヘッダーの削除headersに対して実行する。

fillHeadersオブジェクトheaders、与えられたオブジェクトobject)は以下を実行する:

  1. objectsequenceなら、headerobjectの要素)について:

    1. headersizeが2でなければ、TypeError例外を投げる。

    2. 追加header[0], header[1])をheadersに対して実行する。

  2. それ以外の場合、objectrecordなら、keyvalueobjectの要素)について、追加key, value)をheadersに対して実行する。

特権no-CORSリクエストヘッダーの削除Headersオブジェクト(headers))は以下を実行する:

  1. headerName特権no-CORSリクエストヘッダー名)について:

    1. 削除headerName)をheadersheader listに対して実行する。

これは、特権のないコードによってヘッダーが変更された時に呼ばれます。

new Headers(init) コンストラクタの手順は次の通りです:

  1. thisガードを"none"に設定する。

  2. initが与えられていれば、fillthisinit)を実行する。

append(name, value) メソッドの手順は、追加name, value)をthisに対して行うこと。

delete(name)メソッドの手順は以下の通りです:

  1. バリデートname, ``)がthisでfalseなら、returnする。

    ダミーのヘッダー値を渡しても悪影響はありません。

  2. thisガードが"request-no-cors"、かつnameno-CORS安全リストリクエストヘッダー名でも特権no-CORSリクエストヘッダー名でもない場合、returnする。

  3. thisheader listname含まない場合、returnする。

  4. 削除name)をthisheader listに対して実行する。

  5. thisガードが"request-no-cors"なら、特権no-CORSリクエストヘッダーの削除thisに対して実行する。

get(name)メソッドの手順は以下の通りです:

  1. nameヘッダー名でない場合、TypeError例外を投げる。

  2. name取得thisheader listから)し、その結果を返す。

getSetCookie()メソッドの手順は以下の通りです:

  1. thisheader listが`Set-Cookie`を含まない場合、« »を返す。

  2. thisheader listのうち、nameが`Set-Cookie`とバイト大文字小文字無視で一致するヘッダー)の値を順序通り返す。

has(name)メソッドの手順は以下の通りです:

  1. nameヘッダー名でない場合、TypeError例外を投げる。

  2. thisheader listname含むならtrue、そうでなければfalseを返す。

set(name, value) メソッドの手順は以下の通りです:

  1. value正規化する。

  2. バリデートname, value)がthisでfalseなら、returnする。

  3. thisガードが"request-no-cors"かつ(name, value)がno-CORS安全リストリクエストヘッダーでない場合、returnする。

  4. セットname, value)をthisheader listに対して実行する。

  5. thisガードが"request-no-cors"なら、特権no-CORSリクエストヘッダーの削除thisに対して実行する。

反復対象の値ペアは、ソートおよび結合thisheader list)の実行結果です。

5.2. BodyInit ユニオン型

typedef (Blob or BufferSource or FormData or URLSearchParams or USVString) XMLHttpRequestBodyInit;

typedef (ReadableStream or XMLHttpRequestBodyInit) BodyInit;

安全抽出は、型付きbodyバイト列またはBodyInitオブジェクトobjectから抽出するための手順です:

  1. objectReadableStream オブジェクトなら:

    1. アサートobjectdisturbedでもlockedでもないこと。

  2. extractobject)の結果を返す。

安全抽出操作は、例外を投げないことが保証されるextract操作のサブセットです。

extractは、 型付きbodyバイト列またはBodyInitオブジェクトobjectから抽出するための手順です。オプションのブール値 keepalive(デフォルトfalse)を受け取ります:

  1. streamをnullに設定する。

  2. objectReadableStream オブジェクトなら、streamobjectを設定する。

  3. それ以外でobjectBlob オブジェクトなら、streamobjectget streamの結果を設定する。

  4. それ以外の場合、streamに新しいReadableStreamオブジェクトを設定し、 バイト読み取り対応でセットアップする。

  5. アサートstreamReadableStreamオブジェクトであること。

  6. actionをnullに設定する。

  7. sourceをnullに設定する。

  8. lengthをnullに設定する。

  9. typeをnullに設定する。

  10. objectの型によって分岐:

    Blob

    sourceobjectを設定する。

    lengthobjectsize属性値を設定する。

    objecttype属性値が空でなければ、typeにその値を設定する。

    バイト列

    sourceobjectを設定する。

    BufferSource

    sourceobjectが保持するバイトのコピーを設定する。

    FormData

    actionに次の手順:multipart/form-dataエンコーディングアルゴリズムobjectentry listUTF-8で実行する、を設定する。

    sourceobjectを設定する。

    length未確定、詳細は html/6424参照を設定する。

    typeに`multipart/form-data; boundary=`+multipart/form-data境界文字列multipart/form-dataエンコーディングアルゴリズムで生成)を設定する。

    URLSearchParams

    sourceapplication/x-www-form-urlencodedシリアライザobjectlistを使う)を実行した結果を設定する。

    typeに`application/x-www-form-urlencoded;charset=UTF-8`を設定する。

    スカラー値文字列

    sourceUTF-8エンコードobject)の結果を設定する。

    typeに`text/plain;charset=UTF-8`を設定する。

    ReadableStream

    keepaliveがtrueなら、TypeError例外を投げる。

    objectdisturbedまたはlockedなら、TypeError例外を投げる。

  11. sourceバイト列なら、actionに「sourceを返す」手順を設定し、lengthsourcelengthを設定する。

  12. actionがnullでなければ、以下の手順を並列で実行する:

    1. actionを実行する。

      バイトが1つ以上利用可能になり、かつstreamerroredでなければ、enqueue(利用可能なバイトからUint8Arrayを生成した結果、stream)を行う。

      actionが終了したら、closestream)を行う。

  13. bodybodystream: stream, source: source, length: length)を設定する。

  14. (body, type) を返す。

5.3. Bodyミックスイン

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();
};

ネットワーク層が依存してほしくない形式、例えばHTMLなどはここで公開されることはありません。そうした形式は、将来的にHTMLパーサAPIがストリームを受け入れるようになる可能性があります。

Bodyインターフェースミックスインを含むオブジェクトは、関連付けられたbody(nullまたはbody)を持ちます。

Body インターフェースミックスインを含むオブジェクトは、 その body が null でなく、 かつその bodystream乱された または ロック済み の場合、 使用不可 であると言う。


requestOrResponse . body

requestOrResponseのbodyをReadableStreamとして返します。

requestOrResponse . bodyUsed

requestOrResponseのbodyが既に読み取られたかどうかを返します。

requestOrResponse . arrayBuffer()

requestOrResponseのbodyをArrayBufferとして返すPromiseを返します。

requestOrResponse . blob()

requestOrResponseのbodyをBlobとして返すPromiseを返します。

requestOrResponse . bytes()

requestOrResponseのbodyをUint8Arrayとして返すPromiseを返します。

requestOrResponse . formData()

requestOrResponseのbodyをFormDataとして返すPromiseを返します。

requestOrResponse . json()

requestOrResponseのbodyをJSONとしてパースした結果を返すPromiseを返します。

requestOrResponse . text()

requestOrResponseのbodyを文字列として返すPromiseを返します。


MIMEタイプ取得は、RequestまたはResponseオブジェクトrequestOrResponseに対して以下を実行します:

  1. headersをnullに設定する。

  2. requestOrResponseRequestオブジェクトなら、headersrequestOrResponserequestheader listを設定する。

  3. それ以外の場合、headersrequestOrResponseresponseheader listを設定する。

  4. mimeTypeMIMEタイプ抽出headers)の結果を設定する。

  5. mimeTypeが失敗ならnullを返す。

  6. mimeTypeを返す。

bodygetterの手順は、thisbodyがnullならnullを返し、そうでなければthisbodystreamを返すこと。

bodyUsedgetterの手順は、thisbodyがnullでなく、かつthisbodystreamdisturbedならtrue、そうでなければfalseを返すこと。

consume body アルゴリズムは、Bodyを含むオブジェクトobjectと、バイト列を受け取りJavaScript値を返す(または例外を投げる)アルゴリズムconvertBytesToJSValueを受け取り、以下を実行します:

  1. object使用不可なら、TypeErrorでrejectされたpromiseを返す。

  2. promise新しいpromiseを設定する。

  3. errorStepserror)にpromiseerrorrejectする手順を設定する。
  4. successStepsバイト列data)にpromiseconvertBytesToJSValuedata)の結果でresolveする手順(例外ならerrorStepsを実行)を設定する。
  5. objectbodyがnullなら、空のバイト列successStepsを実行する。

  6. それ以外なら、完全に読み取るobjectbodysuccessStepserrorStepsobject関連グローバルオブジェクト)を実行する。

  7. promiseを返す。

arrayBuffer()メソッドの手順は、consume bodythis、バイト列bytesの場合はArrayBuffer作成bytesthis関連realm))を返すこと。

このメソッドはRangeErrorでrejectされる場合があります。

blob()メソッドの手順は、consume bodythis、バイト列bytesの場合はBlob(内容:bytes、type属性:MIMEタイプ取得this)))を返すこと。

bytes()メソッドの手順は、consume bodythis、バイト列bytesの場合はUint8Array作成bytesthis関連realm))を返すこと。

このメソッドはRangeErrorでrejectされる場合があります。

formData()メソッドの手順は、consume bodythis、バイト列bytesの場合は以下の手順)を返すこと:

  1. mimeTypeMIMEタイプ取得this)の結果を設定する。

  2. mimeTypeがnullでなければ、mimeTypeessenceごとに分岐する:

    "multipart/form-data"
    1. bytesmimeTypeの`boundary`パラメータ値を使ってRFC7578の規則に従いパースする。

      `Content-Disposition`ヘッダーに`filename`パラメータを持つ各部品は、その内容からFileオブジェクトとしてパースされる。そのname属性はその`filename`パラメータ値、type属性は部品の`Content-Type`ヘッダー値(なければ`text/plain`)となる。

      `filename`を持たない部品は、UTF-8デコード(BOMなし)した内容としてパースされる(`Content-Type`や`charset`の有無・値は無視)。

      `Content-Disposition`ヘッダーに`name`パラメータが`_charset_`の場合でもエンコーディングは変わりません。

    2. 何らかの理由で失敗した場合はTypeError例外を投げる。

    3. パース結果の各エントリをFormDataオブジェクトのentry listに追加し新たなFormDataを返す。

    上記は`multipart/form-data`に必要な処理の概略です。より詳細な仕様策定が必要です。協力者歓迎。

    "application/x-www-form-urlencoded"
    1. bytesパースentriesを得る。

    2. entriesをentry listに持つ新しいFormDataオブジェクトを返す。

  3. TypeError例外を投げる。

json()メソッドの手順は、consume bodythisJSONパース)を返すこと。

このメソッドはSyntaxErrorでrejectされる場合があります。

text()メソッドの手順は、consume bodythisUTF-8デコード)を返すこと。

5.4. Requestクラス

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" };

"serviceworker"はRequestDestinationから省略されていますが、JavaScriptからは観測できません。実装はdestinationとしてサポートする必要があります。"websocket"はRequestModeから省略されていますが、JavaScriptから利用・観測できません。

Requestオブジェクトには関連付けられたrequestrequest)があります。

Requestオブジェクトには、関連付けられたheaders(nullまたはHeadersオブジェクト、初期値はnull)があります。

Requestオブジェクトには、関連付けられたsignal(nullまたはAbortSignalオブジェクト、初期値はnull)があります。

Requestオブジェクトのbodyは、そのrequestbodyです。


request = new Request(input [, init])

requesturlプロパティは、inputが文字列の場合はその値、inputRequestオブジェクトの場合はそのurlになります。

init引数は以下のようにプロパティを設定できるオブジェクトです:

method
文字列でrequestmethodを設定します。
headers
Headersオブジェクト、リテラルオブジェクト、または2要素配列の配列でrequestheadersを設定します。
body
BodyInitオブジェクトまたはnullでrequestbodyを設定します。
referrer
同一オリジンのURL、"about:client"、または空文字列でrequestreferrerを設定します。
referrerPolicy
referrer policyrequestreferrerPolicyを設定します。
mode
リクエストがCORSを使うか、同一オリジンに制限されるかを示す文字列。requestmodeを設定します。inputが文字列の場合、デフォルトは"cors"です。
credentials
リクエストに認証情報を常に送るか、送らないか、同一オリジンのURLのみ送るか、またレスポンスの認証情報を常に使うか、使わないか、同一オリジンのレスポンスのみ使うかを示す文字列。requestcredentialsを設定します。inputが文字列の場合、デフォルトは"same-origin"です。
cache
リクエストがブラウザのキャッシュとどうやり取りするかを示す文字列。requestcacheを設定します。
redirect
リダイレクトに従うか、エラーにするか、リダイレクト(不透明な形)を返すかを示す文字列。requestredirectを設定します。
integrity
取得するリソースの暗号学的ハッシュ。requestintegrityを設定します。
keepalive
グローバルが破棄されてもrequestが生き残れるかどうかを示す真偽値。requestkeepaliveを設定します。
signal
AbortSignalrequestsignalを設定します。
window
nullのみ可。requestWindowから切り離すのに使われます。
duplex
"half"のみ有効。ハーフデュプレックスフェッチ(リクエスト送信後にレスポンス処理)用。"full"は将来用で、フルデュプレックス(リクエスト送信中にレスポンス処理)用に予約されています。bodyがReadableStreamの場合は必須。"full"の仕様化はissue #1254参照。
priority
文字列でrequestpriorityを設定します。
request . method
requestのHTTPメソッドを返します(デフォルトは"GET")。
request . url
requestのURLを文字列として返します。
request . headers
requestに関連付けられたHeadersオブジェクトを返します。ネットワーク層でユーザーエージェントが追加するヘッダー(例:"Host")はこのオブジェクトに含まれません。
request . destination
requestで要求されたリソース種別(例:"document"や"script")を返します。
request . referrer
requestのreferrerを返します。initで明示的に設定された場合は同一オリジンURL、空文字列はreferrerなし、"about:client"はグローバルのデフォルトを表します。フェッチ時にRefererヘッダー値の決定に使われます。
request . referrerPolicy
requestに関連付けられたreferrer policyを返します。フェッチ時にreferrer値の計算に使われます。
request . mode
requestに関連付けられたmode(CORS利用か同一オリジン限定かを示す文字列)を返します。
request . credentials
requestに関連付けられたcredentials mode(認証情報を常に送るか、送らないか、同一オリジンのみ送るか、を示す文字列)を返します。
request . cache
requestに関連付けられたcache mode(フェッチ時にブラウザキャッシュとどう連携するかを示す文字列)を返します。
request . redirect
requestに関連付けられたredirect mode(リダイレクトの扱い方を示す文字列)を返します。デフォルトではリダイレクトに従います。
request . integrity
requestのサブリソース整合性メタデータ(取得リソースの暗号学的ハッシュ。複数ハッシュは空白区切り)を返します。[SRI]
request . keepalive
requestが作成元グローバルより長生きできるかどうかを表す真偽値を返します。
request . isReloadNavigation
requestがリロードナビゲーションかどうかを表す真偽値を返します。
request . isHistoryNavigation
requestが履歴ナビゲーション(戻る・進む)かどうかを表す真偽値を返します。
request . signal
requestに関連付けられたsignal(AbortSignalオブジェクト。abort状態やabortイベントハンドラを示す)を返します。
request . duplex
"half"を返します(ハーフデュプレックス:リクエスト送信後にレスポンス処理)。将来的には"full"(フルデュプレックス:リクエスト送信中にレスポンス処理)も返す可能性があります。"full"の仕様化はissue #1254参照。
request . clone()

requestのクローンを返します。


Requestオブジェクトの作成は、Request オブジェクトを、request requestheaders guard guardAbortSignal オブジェクトsignalrealm realmを指定して次の手順で作成します:

  1. requestObjectrealm新しいRequestオブジェクトを生成する。

  2. requestObjectrequestrequestに設定する。

  3. requestObjectheadersを、realm新しいHeadersオブジェクト(headers listrequestheaders listguardguard)に設定する。

  4. requestObjectsignalsignalに設定する。

  5. requestObjectを返す。


new Request(input, init) コンストラクタの手順は次の通りです:

  1. requestをnullに設定する。

  2. fallbackModeをnullに設定する。

  3. baseURLthisrelevant settings objectAPI base URLを設定する。

  4. signalをnullに設定する。

  5. inputが文字列なら:

    1. parsedURLinputbaseURLパースした結果を設定する。

    2. parsedURLが失敗ならTypeError例外を投げる。

    3. parsedURL認証情報を含むならTypeError例外を投げる。

    4. requestrequestURLparsedURL)を新規作成して設定する。

    5. fallbackModeを"cors"に設定する。

  6. それ以外の場合:

    1. アサートinputRequestオブジェクトであること。

    2. requestinputrequestを設定する。

    3. signalinputsignalを設定する。

  7. originthisrelevant settings objectoriginを設定する。

  8. traversableForUserPromptsを"client"に設定する。

  9. requesttraversable for user promptsenvironment settings objectであり、そのoriginorigin同一オリジンなら、traversableForUserPromptsrequesttraversable for user promptsに設定する。

  10. init["window"]が存在し、nullでなければTypeError例外を投げる。

  11. init["window"]が存在すれば、traversableForUserPromptsを"no-traversable"に設定する。

  12. requestに次のプロパティでrequestを新規作成して設定する:

    URL
    requestURL
    method
    requestmethod
    header list
    requestheader listのコピー
    unsafe-request flag
    セットする
    client
    thisrelevant settings object
    traversable for user prompts
    traversableForUserPrompts
    internal priority
    requestinternal priority
    origin
    requestoriginオリジンの伝播はサービスワーカーによるナビゲーションリクエスト処理時のみ重要です。この場合リクエストのオリジンが現在のクライアントと異なることがあります。
    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. requestURLrequestcurrent URLに設定する。

    8. requestURL listを« requestURL »に設定する。

    サービスワーカーがクロスオリジンスタイルシート中の画像等からリダイレクトしてリクエストを書き換える場合、もはや元のソース(クロスオリジンスタイルシート)から来たようには見えず、リダイレクトしたサービスワーカーから来たと扱われる。元ソースが同種リクエストを生成できない場合があるため、これが重要。元ソースを信頼するサービスが攻撃される恐れもある(稀だが)。

  14. init["referrer"]が存在する場合:

    1. referrerinit["referrer"]を設定する。

    2. referrerが空文字列なら、requestreferrerを"no-referrer"に設定する。

    3. それ以外の場合:

      1. parsedReferrerreferrerbaseURLパースした結果を設定する。

      2. parsedReferrerが失敗ならTypeError例外を投げる。

      3. 次のいずれかが成立する場合

        なら、requestreferrerを"client"に設定する。

      4. それ以外の場合、requestreferrerparsedReferrerに設定する。

  15. init["referrerPolicy"]が存在すれば、requestreferrer policyをその値に設定する。

  16. modeinit["mode"]が存在するならその値、しなければfallbackModeを設定する。

  17. modeが"navigate"ならTypeError例外を投げる。

  18. modeがnullでなければ、requestmodemodeに設定する。

  19. init["credentials"]が存在すれば、requestcredentials modeをその値に設定する。

  20. init["cache"]が存在すれば、requestcache modeをその値に設定する。

  21. requestcache modeが"only-if-cached"かつmodeが"same-origin"でなければTypeError例外を投げる。

  22. init["redirect"]が存在すれば、requestredirect modeをその値に設定する。

  23. init["integrity"]が存在すれば、requestintegrity metadataをその値に設定する。

  24. init["keepalive"]が存在すれば、requestkeepaliveをその値に設定する。

  25. init["method"]が存在すれば:

    1. methodinit["method"]を設定する。

    2. methodmethodでない、またはmethod禁止メソッドならTypeError例外を投げる。

    3. method正規化する。

    4. requestmethodmethodに設定する。

  26. init["signal"]が存在すれば、signalをその値に設定する。

  27. init["priority"]が存在すれば:

    1. requestinternal priorityがnullでなければ、実装定義の方法でinternal priorityを更新する。

    2. それ以外の場合、requestpriorityinit["priority"]に設定する。

  28. thisrequestrequestに設定する。

  29. signalssignalがnullでなければ« signal »、そうでなければ« »を設定する。

  30. thissignaldependent abort signalの作成signalsAbortSignalthisrelevant realm)の結果に設定する。

  31. thisheaders新しいHeadersオブジェクト(thisrelevant realm、header listはrequestheader list、guardは"request")に設定する。

  32. thisrequestmodeが"no-cors"なら:

    1. thisrequestmethodCORS安全リストメソッドでなければTypeError例外を投げる。

    2. thisheadersguardを"request-no-cors"に設定する。

  33. init空でない場合:

    このモードで許可されないヘッダーが含まれる可能性があるためヘッダーをサニタイズする。そうでなければ、以前にサニタイズ済みか特権APIで設定され変更されていない。

    1. headersthisheadersと関連header listのコピーを設定する。

    2. init["headers"]が存在すれば、headersinit["headers"]に設定する。

    3. thisheadersheader listを空にする。

    4. headersHeadersオブジェクトなら、header(header listの要素)について、append(header)をthisheadersに実行する。

    5. それ以外の場合、fillthisheadersheaders)を実行する。

  34. inputBodyinputRequestオブジェクトならinputrequestbody、それ以外ならnullを設定する。

  35. init["body"]が存在しかつnullでない、またはinputBodyがnullでない場合で、requestmethodが`GET`または`HEAD`ならTypeError例外を投げる。

  36. initBodyをnullに設定する。

  37. init["body"]が存在しかつnullでない場合:

    1. bodyWithTypeextractinit["body"]、keepaliverequestkeepalive)の結果を設定する。

    2. initBodybodyWithTypebodyを設定する。

    3. typebodyWithTypetypeを設定する。

    4. typeがnullでなく、thisheadersheader listが`Content-Type`を含まない場合、append(`Content-Type`、type)をthisheadersに実行する。

  38. inputOrInitBodyinitBodyがnullでなければそれを、そうでなければinputBodyを設定する。

  39. inputOrInitBodyがnullでなく、そのsourceが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使用不可 なら、throwTypeError を投げる。

    2. finalBodyproxyの生成 の結果(inputBody を対象)を設定する。

  42. thisrequestbodyfinalBodyに設定する。

methodゲッターの手順は、thisrequestmethodを返すこと。

urlゲッターの手順は、thisrequestURL直列化して返すこと。

headersゲッターの手順は、thisheadersを返すこと。

destinationゲッターの手順は、thisrequestdestinationを返すこと。

referrerゲッターの手順は次の通りです:

  1. thisrequestreferrerが"no-referrer"なら空文字列を返す。

  2. thisrequestreferrerが"client"なら"about:client"を返す。

  3. thisrequestreferrer直列化して返す。

referrerPolicyゲッターの手順は、thisrequestreferrer policyを返すこと。

modeゲッターの手順は、thisrequestmodeを返すこと。

credentialsゲッターの手順は、thisrequestcredentials modeを返すこと。

cacheゲッターの手順は、thisrequestcache modeを返すこと。

redirectゲッターの手順は、thisrequestredirect modeを返すこと。

integrityゲッターの手順は、thisrequestintegrity metadataを返すこと。

keepaliveゲッターの手順は、thisrequestkeepaliveを返すこと。

isReloadNavigationゲッターの手順は、thisrequestreload-navigation flagがセットされていればtrue、そうでなければfalseを返すこと。

isHistoryNavigationゲッターの手順は、thisrequesthistory-navigation flagがセットされていればtrue、そうでなければfalseを返すこと。

signalゲッターの手順は、thissignalを返すこと。

duplexゲッターの手順は"half"を返すこと。


clone()メソッドの手順は次の通りです:

  1. this使用不可ならTypeError例外を投げる。

  2. clonedRequestclonethisrequest)の結果を設定する。

  3. アサートthissignalはnullでない。

  4. clonedSignaldependent abort signalの作成(« thissignal »、AbortSignalthisrelevant realm)の結果を設定する。

  5. clonedRequestObjectRequestオブジェクトの作成clonedRequestthisheadersguardclonedSignalthisrelevant realm)の結果を設定する。

  6. clonedRequestObjectを返す。

5.5. Responseクラス

[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" };

Response オブジェクトには関連付けられたresponseresponse)があります。

Response オブジェクトには、関連付けられたheaders(nullまたはHeadersオブジェクト、初期値はnull)があります。

Response オブジェクトのbodyは、そのresponsebodyです。


response = new Response(body = null [, init])

Responseオブジェクトを生成し、bodyはbody、status・status message・headersはinitで指定されます。

response = Response . error()

ネットワークエラーのResponseオブジェクトを生成します。

response = Response . redirect(url, status = 302)

urlstatusでリダイレクトするResponseを生成します。

response = Response . json(data [, init])

bodyがJSONエンコードされたdata、status・status message・headersはinitで指定されるResponseを生成します。

response . type

responseのtype(例:"cors")を返します。

response . url

responseにURLがあれば返し、なければ空文字列を返します。

response . redirected

responseがリダイレクトによって取得されたかどうかを返します。

response . status

responseのstatusを返します。

response . ok

responseのstatusがok statusならtrueを返します。

response . statusText

responseのstatus messageを返します。

response . headers

responseのheadersをHeadersとして返します。

response . clone()

responseのクローンを返します。


Responseオブジェクトの作成は、Responseオブジェクトを、responseresponseheaders guardguardrealmrealmを指定して次の手順で作成します:

  1. responseObjectrealm新しいResponseオブジェクトを生成する。

  2. responseObjectresponseresponseに設定する。

  3. responseObjectheadersを、realm新しいHeadersオブジェクト(headers listresponseheaders listguardguard)に設定する。

  4. responseObjectを返す。

レスポンスの初期化は、ResponseオブジェクトresponseResponseInitinit、nullまたはbody with typebodyを指定して次の手順で初期化します:

  1. init["status"]が200~599の範囲外ならRangeError例外を投げる。

  2. init["statusText"]が空文字列でなく、かつreason-phraseトークン生成規則に一致しない場合、TypeError例外を投げる。

  3. responseresponsestatusinit["status"]に設定する。

  4. responseresponsestatus messageinit["statusText"]に設定する。

  5. init["headers"]が存在すれば、fillresponseheadersinit["headers"])を実行する。

  6. bodyがnullでなければ:

    1. responsestatusnull body statusならTypeError例外を投げる。

      101/103はnull body statusに含まれるが、ここでは影響しません。

    2. responsebodybodybodyに設定する。

    3. bodytypeがnullでなく、responseheader listが`Content-Type`を含まない場合、append(`Content-Type`、bodytype)をresponseheader listに実行する。


new Response(body, init) コンストラクタの手順は次の通りです:

  1. thisresponseを新しいresponseに設定する。

  2. thisheaders新しいHeadersオブジェクト(thisrelevant realm、header listはresponseheader list、guardは"response")に設定する。

  3. bodyWithTypeをnullに設定する。

  4. bodyがnullでなければ、extractbody)の結果をbodyWithTypeに設定する。

  5. レスポンスの初期化thisinitbodyWithType)を実行する。

error()静的メソッドの手順は、新しいnetwork error、"immutable"、current realmを指定してResponseオブジェクトの作成の結果を返すこと。

redirect(url, status)静的メソッドの手順は次の通りです:

  1. parsedURLurlcurrent settings objectAPI base URLパースした結果を設定する。

  2. parsedURLが失敗ならTypeError例外を投げる。

  3. statusredirect statusでなければRangeError例外を投げる。

  4. responseObjectResponseオブジェクトの作成(新しいresponse、"immutable"、current realm)の結果を設定する。

  5. responseObjectresponsestatusstatusに設定する。

  6. valueparsedURL直列化してisomorphic encodeしたものを設定する。

  7. append(`Location`、value)をresponseObjectresponseheader listに実行する。

  8. responseObjectを返す。

json(data, init)静的メソッドの手順は次の通りです:

  1. bytesdataJSONバイト列へシリアライズした結果を設定する。

  2. bodyextractbytes)の結果を設定する。

  3. responseObjectResponseオブジェクトの作成(新しいresponse、"response"、current realm)の結果を設定する。

  4. レスポンスの初期化responseObjectinit、(body, "application/json"))を実行する。

  5. responseObjectを返す。

typeゲッターの手順は、thisresponsetypeを返すこと。

urlゲッターの手順は、thisresponseURLがnullなら空文字列を返し、そうでなければthisresponseURL直列化exclude fragmentをtrueに設定)して返すこと。

redirectedゲッターの手順は、thisresponseURL listsizeが1より大きければtrue、そうでなければfalseを返すこと。

リダイレクトの結果のresponseを除外したい場合は、API経由で直接制御できます(例:fetch(url, { redirect:"error" }))。この方法なら潜在的に危険なresponseが漏れることはありません。

statusゲッターの手順は、thisresponsestatusを返すこと。

okゲッターの手順は、thisresponsestatusok statusならtrue、そうでなければfalseを返すこと。

statusTextゲッターの手順は、thisresponsestatus messageを返すこと。

headersゲッターの手順は、thisheadersを返すこと。


clone()メソッドの手順は次の通りです:

  1. this使用不可ならTypeError例外を投げる。

  2. clonedResponseclonethisresponse)の結果を設定する。

  3. Responseオブジェクトの作成clonedResponsethisheadersguardthisrelevant realm)の結果を返す。

5.6. Fetchメソッド

partial interface mixin WindowOrWorkerGlobalScope {
  [NewObject] Promise<Response> fetch(RequestInfo input, optional RequestInit init = {});
};

dictionary DeferredRequestInit : RequestInit {
  DOMHighResTimeStamp activateAfter;
};

[Exposed=Window]
interface FetchLaterResult {
  readonly attribute boolean activated;
};

partial interface Window {
  [NewObject] FetchLaterResult fetchLater(RequestInfo input, optional DeferredRequestInit init = {});
};

fetch(input, init) メソッドの手順は次の通りです:

  1. p新しいpromiseを設定する。

  2. requestObjectRequestの初期値をコンストラクタとしてinputinitを引数に呼び出した結果を設定する。例外が投げられた場合、pをrejectしてpを返す。

  3. requestrequestObjectrequestを設定する。

  4. requestObjectsignalabort済みなら:

    1. fetch()呼び出しの中止prequest、null、requestObjectsignalabort理由)を実行する。

    2. pを返す。

  5. globalObjectrequestclientglobal objectを設定する。
  6. globalObjectServiceWorkerGlobalScopeオブジェクトなら、requestservice-workers modeを"none"に設定する。
  7. responseObjectをnullに設定する。

  8. relevantRealmthisrelevant realmを設定する。

  9. locallyAbortedをfalseに設定する。

    同一スレッドからabort要求が来た場合、予測可能なタイミングでpromiseをrejectできるようにする。

  10. controllerをnullに設定する。

  11. abort時の手順追加requestObjectsignalに対して次の通り追加する:

    1. locallyAbortedをtrueに設定する。

    2. アサートcontrollerはnullでない。

    3. controllerのabortcontrollerrequestObjectsignalabort理由)を実行する。

    4. fetch()呼び出しの中止prequestresponseObjectrequestObjectsignalabort理由)を実行する。

  12. controllerfetchrequestprocessResponseとして、responseが次の手順)を実行した結果を設定する:

    1. locallyAbortedがtrueならこの手順を中止する。

    2. responseaborted flagがセットされていれば:

      1. deserializedErrorabort理由のデシリアライズcontrollerserialized abort理由relevantRealm)の結果を設定する。

      2. fetch()呼び出しの中止prequestresponseObjectdeserializedError)を実行する。

      3. この手順を中止する。

    3. responsenetwork errorなら、pをTypeErrorでrejectし、この手順を中止する。

    4. responseObjectResponseオブジェクトの作成response、"immutable"、relevantRealm)の結果を設定する。

    5. pをresponseObjectでresolveする。

  13. pを返す。

fetch()呼び出しの中止promiserequestresponseObjecterror)は次の通り:

  1. promiseをerrorでrejectする。

    promiseが既にfulfilledなら何もしない。

  2. requestbodyがnullでなく、かつreadableなら、request.bodyをerrorでcancelする。

  3. responseObjectがnullならreturn。

  4. responseresponseObjectresponseを設定する。

  5. responsebodyがnullでなく、かつreadableなら、response.bodyをerrorでエラー化する。

FetchLaterResultには関連付けられたactivated getter steps(booleanを返すアルゴリズム)があります。

activatedゲッターの手順は、thisactivated getter stepsを実行した結果を返すこと。

fetchLater(input, init) メソッドの手順は次の通りです:

  1. requestObjectRequestの初期値をコンストラクタとしてinputinitを引数に呼び出した結果を設定する。

  2. requestObjectsignalabort済みなら、signalabort理由をthrowする。

  3. requestrequestObjectrequestを設定する。

  4. activateAfterをnullに設定する。

  5. initが与えられ、init["activateAfter"]が存在すれば、activateAfterにその値を設定する。

  6. activateAfterが0未満ならRangeError例外を投げる。

  7. thisrelevant global objectassociated documentfully activeでなければTypeError例外を投げる。

  8. requestURLschemeHTTP(S) schemeでなければTypeError例外を投げる。

  9. requestURLpotentially trustworthy URLでなければTypeError例外を投げる。

  10. requestbodyがnullでなく、かつそのlengthがnullならTypeError例外を投げる。

    bodyがReadableStreamオブジェクトの場合はdeferred不可。

  11. available deferred-fetch quotarequestclientrequestURLorigin)がrequesttotal request length未満ならQuotaExceededErrorDOMException例外を投げる。

  12. activatedをfalseに設定する。

  13. deferredRecorddeferred fetchのキュー追加requestactivateAfter、次の手順:activatedをtrueに設定)を実行した結果を設定する。

  14. abort時の手順追加requestObjectsignalに対して、「deferredRecordinvoke stateを"aborted"に設定」する手順を追加する。

  15. 新しいFetchLaterResultactivated getter stepsactivatedを返す)を返す。

次の呼び出しは、ドキュメントが終了したときにフェッチされるリクエストをキューします:

fetchLater("https://report.example.com", {
  method: "POST",
  body: JSON.stringify(myReport),
  headers: { "Content-Type": "application/json" }
})

次の呼び出しは5秒後にこのリクエストをキューし、返された値で本当にアクティベートされたかどうか確認できます。ユーザーエージェントがタイマーをスロットルしても、リクエストは必ず実行されます。

const result = fetchLater("https://report.example.com", {
  method: "POST",
  body: JSON.stringify(myReport),
  headers: { "Content-Type": "application/json" },
  activateAfter: 5000
});

function check_if_fetched() {
  return result.activated;
}

FetchLaterResultオブジェクトはAbortSignalと組み合わせて使うこともできます。例えば:

let accumulated_events = [];
let previous_result = null;
const abort_signal = new AbortSignal();
function accumulate_event(event) {
  if (previous_result) {
    if (previous_result.activated) {
      // リクエストは既にアクティベートされているので、新しく始められます。
      accumulated_events = [];
    } else {
      // このリクエストをabortして、すべてのイベントで新規リクエストを開始します。
      signal.abort();
    }
  }

  accumulated_events.push(event);
  result = fetchLater("https://report.example.com", {
    method: "POST",
    body: JSON.stringify(accumulated_events),
    headers: { "Content-Type": "application/json" },
    activateAfter: 5000,
    abort_signal
  });
}

以下のいずれかのfetchLater()呼び出しは例外が投げられます:

// potentially trustworthy URLのみサポート
fetchLater("http://untrusted.example.com");

// deferredリクエストの長さは事前に分かっている必要があります。
fetchLater("https://origin.example.com", {body: someDynamicStream});

// deferred fetchはactiveなwindowでのみ動作します。
const detachedWindow = iframe.contentWindow;
iframe.remove();
detachedWindow.fetchLater("https://origin.example.com");

deferred fetch quotaの例も参照。

5.7. ガベージコレクション

ユーザーエージェントは、スクリプトから観測できない場合、進行中のfetchを終了してもよい。

「スクリプトから観測できる」とは、fetch() の引数と戻り値で観測できることを意味します。それ以外の方法(サーバーとのサイドチャネル通信など)は含みません。

サーバーがガベージコレクションを観測できる例は既に存在します。例えば WebSocketXMLHttpRequest オブジェクトなどです。

ユーザーエージェントは、終了が観測できないためfetchを終了できる。

fetch("https://www.example.com/")

ユーザーエージェントは、promise経由で終了が観測できるためfetchを終了できない。

window.promise = fetch("https://www.example.com/")

関連するbodyが観測できないため、ユーザーエージェントはfetchを終了できる。

window.promise = fetch("https://www.example.com/").then(res => res.headers)

終了が観測できないため、ユーザーエージェントはfetchを終了できる。

fetch("https://www.example.com/").then(res => res.body.getReader().closed)

promiseオブジェクトにハンドラを登録することで、終了が観測できるためユーザーエージェントはfetchを終了できない。

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: URL

data: URLについての参考説明はRFC 2397を参照してください。本節は、現行のコンテンツと互換性を持たせるため、そのRFCの規範的な処理要件を置き換えます。[RFC2397]

data: URL構造体は、構造体で、MIMEタイプMIMEタイプ)と、 bodyバイト列)を持ちます。

data: URL処理器は、URL dataURLを受け取り、次の手順を実行します:

  1. アサートdataURLschemeは"data"であること。

  2. inputURL直列化dataURLexclude fragmentをtrue)した結果を設定する。

  3. inputの先頭の"data:"を削除する。

  4. positioninputの最初に設定する。

  5. mimeTypepositionからU+002C(,)以外のコードポイントを収集した結果を設定する。

  6. 先頭・末尾のASCII空白mimeTypeから除去する。

    これによりU+0020 SPACEコードポイントのみが削除されます(ある場合)。

  7. positioninputの終端を超えていれば失敗を返す。

  8. positionを1進める。

  9. encodedBodyinputの残り部分を設定する。

  10. bodyencodedBodyパーセントデコード結果を設定する。

  11. mimeTypeがU+003B(;)で終わり、その後ゼロ個以上のU+0020 SPACE、さらにASCII大文字小文字無視で"base64"が続く場合、次を実行:

    1. stringBodybodyisomorphic decode結果を設定する。

    2. bodystringBodyforgiving-base64 decode結果を設定する。

    3. bodyが失敗なら失敗を返す。

    4. mimeTypeから最後の6つのコードポイントを削除する。

    5. mimeTypeから末尾のU+0020 SPACEコードポイントを削除する(あれば)。

    6. mimeTypeから最後のU+003B(;)を削除する。

  12. mimeTypeが";"で始まるなら、"text/plain"を先頭に追加する。

  13. mimeTypeRecordMIMEタイプをパースmimeType)の結果を設定する。

  14. mimeTypeRecordが失敗ならtext/plain;charset=US-ASCIIに設定する。

  15. 新しいdata: URL構造体(MIMEタイプ:mimeTypeRecord、body:body)を返す。

参考文献

このセクションおよびその下位セクションは参考情報のみです。

HTTPヘッダー階層の区分

fetchにおいては、API層(HTMLのimg、CSSのbackground-image)、早期fetch層、Service Worker層、ネットワーク&キャッシュ層があります。`Accept`や`Accept-Language`は早期fetch層(通常はユーザーエージェントが設定)で扱われます。他のほとんどのユーザーエージェント制御ヘッダー(`Accept-Encoding`、`Host`、`Referer`など)はネットワーク&キャッシュ層で設定されます。開発者はAPI層またはService Worker層(通常はRequestオブジェクト経由)でヘッダーを設定できます。 禁止リクエストヘッダーはほぼ制御できませんが、`Accept`は制御でき、例えば`Referer`は省略・制限できます。

HTTPリダイレクトのアトミックな取り扱い

リダイレクト(responsestatusinternal response(あれば)のstatusリダイレクトステータスの場合)はAPIに公開されません。リダイレクトを公開すると、クロスサイトスクリプティング攻撃などで得られない情報が漏れる可能性があります。

例えばhttps://example.org/authに対するfetchで、HttpOnly付きのCookieが含まれている場合、https://other-origin.invalid/4af955781ea1c84a3b11にリダイレクトされる可能性があります。この新しいURLには秘密情報が含まれています。リダイレクトを公開すれば、その秘密がクロスサイトスクリプティング攻撃で取得されてしまいます。

CORSプロトコルの安全な基本設定

IP認証やファイアウォールによってデータが保護されているリソース(残念ながら現在も比較的多い)では、CORSプロトコルの使用は安全ではありません。(このためCORSプロトコルが考案されました。)

しかし、下記のようなヘッダーの使用は安全です:

Access-Control-Allow-Origin: *

リソースがCookieやHTTP認証で追加情報を公開している場合でも、上記のヘッダーを使ってもそれが漏れることはありません。API(XMLHttpRequestなど)にリソースを共有できます。 これはcurlwgetと同様です。

言い換えれば、リソースがWeb上の任意のデバイスからcurlwgetでアクセスできない場合、上記のヘッダーは含めるべきではありません。アクセスできる場合は問題ありません。

CORSプロトコルとHTTPキャッシュ

CORSプロトコルの要件が`Access-Control-Allow-Origin`を*や静的なoriginに設定するだけより複雑な場合は、`Vary`を使う必要があります。[HTML] [HTTP] [HTTP-CACHING]

Vary: Origin

特に、`Vary`が使われず、サーバーが特定のリソースに対しAccess-Control-Allow-Origin`をCORSリクエストにのみ返す場合を考えてください。ユーザーエージェントが非CORSリクエスト(例えばナビゲーションリクエスト)でそのリソースのレスポンスを受け取った場合、そのレスポンスには`Access-Control-Allow-Origin`が含まれず、ユーザーエージェントはそのレスポンスをキャッシュします。その後ユーザーエージェントが同じリソースに対してCORSリクエストを発行すると、以前の非CORSリクエストのキャッシュレスポンスが使われ、`Access-Control-Allow-Origin`がない状態になります。

しかし、同じ状況で`Vary: Origin`を使えば、ユーザーエージェントは`Access-Control-Allow-Origin`を含むレスポンスをfetchし、以前の非CORSリクエストのキャッシュレスポンスは使われません。

一方、特定のリソースについて`Access-Control-Allow-Origin`を*や静的なoriginに設定している場合は、サーバーは常にそのリソースのレスポンスで`Access-Control-Allow-Origin`を返し、非CORSリクエストでもCORSリクエストでも同様にし、`Vary`は使わないようにします。

WebSocket

コネクション確立の一環として、WebSocket オブジェクトは特殊な種類の fetchrequestmodeが"websocket")を開始し、多くのfetchポリシー決定(例えばHTTP Strict Transport Security (HSTS))を共有できます。最終的にはfetchがWebSocketへ専用コネクション取得のため呼び出します。[WEBSOCKETS] [HSTS]

以前fetchは WebSocketコネクションの取得および WebSocketコネクションの確立を直接定義していましたが、現在はWebSocketsで定義されています。[WEBSOCKETS]

他の標準でのfetch利用

本質的には、fetchrequestresponseの交換です。実際には、標準仕様が正しく採用・利用するには非常に複雑なメカニズムとなります。本節はそのためのアドバイスを示します。

必ずドメイン専門家にレビューを依頼してください。

この部分は作業中です。

リクエストのセットアップ

fetchの最初のステップは、requestを作成し、その各項目を設定することです。

まずrequestURLmethodをHTTPで定義された通りに設定します。もし`POST`や`PUT`のrequestにbodyが必要な場合、requestbodyバイト列または新規bodystreamは自作のReadableStream)に設定します。[HTTP]

requestdestinationdestination表の指針に従って選択してください。destinationContent Security Policyなどに影響し、`Sec-Fetch-Dest`ヘッダーなどにも関係するため、単なるメタデータ以上の意味があります。新しい機能に未掲載のdestinationが必要な場合はissueを提出してください。[CSP]

requestclientは、自分が動作しているenvironment settings objectに設定します。Web公開APIは一般にWeb IDLで定義され、インターフェースを実装するすべてのオブジェクトはrelevant settings objectを持っています。たとえば、requestelementに紐付く場合は、そのrequestclientは要素のnode documentrelevant settings objectにします。JavaScript、HTML、CSSその他DocumentサブリソースでWebに直接公開する機能はすべてclientを持たせるべきです。

fetchが直接Web公開されない場合(例えばWindowやWorkerを使わずバックグラウンドで送信する場合)はrequestclientをnullにし、requestoriginpolicy containerservice-workers modereferrerは適切な値に設定します(例えば事前にenvironment settings objectからコピー)。このような高度なケースでは、fetchがContent Security Policyreferrer policyをどう扱うか詳細に検討してください。また並行処理にも注意が必要です(コールバックはfetch実行とレスポンス処理参照、parallel queueで処理されます)。[REFERRER] [CSP]

クロスオリジンのリソースをどう扱うかも検討してください。ある機能が同一オリジンでのみ動作する場合はrequestmodeを"same-origin"に設定します。そうでなければWeb公開機能はほぼ常にmodeを"cors"にするべきです。Web公開でなければ、あるいはCORSなしにクロスオリジンfetchすべき理由がある場合はissueを提出してください。

クロスオリジンリクエストの場合、credentialsを送信するかも検討し、送信するならrequestcredentials modeを"include"に設定します。

fetchがResource Timingに報告すべきか、どのinitiator typeで報告するかも検討します。initiator typerequestに渡せば、fetch終了時にResource Timingへ自動報告されます(responseが完全にダウンロードされた後)。[RESOURCE-TIMING]

追加のHTTPヘッダーが必要な場合はheader listを必要なヘッダー入りのheader listに設定します(例:« (`My-Header-Name`, `My-Header-Value`) »)。カスタムヘッダー送信はCORSプリフライトfetchなど追加処理が必要になる場合もあるので注意してください。

デフォルトのキャッシュ機構を上書きしたい場合(例:キャッシュ無効化)はrequestcache modeを"default"以外に設定します。

リダイレクトを許可したくない場合はredirect modeを"error"に設定します。

他にもrequestのパラメータを確認し、必要なものがあれば設定してください。これらのパラメータは特殊用途が多く、詳細は§ 2.2.5 リクエストに記載されています。

fetchの呼び出しとレスポンス処理

request以外にも、fetch操作にはいくつかのオプション引数があります。アルゴリズムを受け取る引数の場合、そのアルゴリズムはタスク(またはparallel queueuseParallelQueueがtrueの場合)から呼び出されます。

requestがセットアップできたら、どのアルゴリズムをfetchに渡すか判断し、responseをどう処理したいか、コールバックをどの段階で受け取りたいかを決めます:

完了時

ほとんどの呼び出し元はこの方法でresponseを扱います。例えばscriptstyle resourceなど。 responsebody全体をバイト列に読み込み、呼び出し元で処理します。

完了時にresponseを処理するには、processResponseConsumeBody引数にアルゴリズムを渡してfetchを実行します。渡したアルゴリズムはresponseと、完全に読み込んだbodyresponseinternal response)を受け取ります。2番目の引数の意味は以下の通りです:

null
responsebodyがnull(ネットワークエラーやnull body statusの場合)。
failure
完全に読み取る 試みが、 responsebody の内容について失敗した(例:I/O エラーなどが原因)。
バイト列

完全に読み込むことが成功した場合(responseinternal responsebody)。

"no-cors"requestでも全文バイト列が渡されるので扱いに注意。たとえば画像内容をユーザーに表示するだけなら問題ないが、埋め込みドキュメントのスクリプトでは直接触れないようにしてください。

  1. requestrequestURLhttps://stuff.example.com/clientthisrelevant settings object)として用意する。

  2. fetchrequestprocessResponseConsumeBodyとして「response、null/failure/バイト列contents」を受け取り:

    1. contentsがnullまたはfailureならエラー表示。

    2. それ以外はresponseのメタデータを考慮しつつcontentsをパースし、必要な処理を行う。

ヘッダー受信後、チャンクごと

動画再生や画像の漸進ロードなど、チャンクごとにレスポンスを処理したい場合もあります。responseはヘッダー受信後にfetch呼び出し元へ渡され、以降は呼び出し元が処理します。

チャンクごとにresponseを処理するには、processResponse引数にアルゴリズムを渡してfetchを実行します。渡したアルゴリズムはヘッダー受信時にresponseを受け取り、以降はbodyのstreamを読んで残りをダウンロードします。便利なように、全データ取得後に呼ばれるprocessResponseEndOfBody引数も渡せます(完了時の追加処理)。processResponseConsumeBodyとは異なり、processResponseprocessResponseEndOfBodyは全データ取得を保証しないので、呼び出し元でbodyを読む必要があります。

processResponse引数は、responseheader liststatusだけ扱い、body処理しない用途にも便利です。これはok statusでないレスポンスの処理などに使います。

  1. requestrequestURLhttps://stream.example.com/clientthisrelevant settings object)として用意する。

  2. fetchrequestprocessResponseとして「response」を受け取り:

    1. network errorならエラー表示。

    2. statusがok statusでなければ代替値を表示。

    3. それ以外はreader取得responsebodystream)し、MIMEタイプ抽出responseheaders list)に応じて処理する。

レスポンス無視

場合によってはresponse自体不要なこともあります(例:navigator.sendBeacon())。 fetchにコールバックを渡さずに実行すれば、responseは期待されません。この場合、responsebodystreamは破棄されるので、内容のダウンロードを気にする必要はありません。

fetchrequestURLhttps://fire-and-forget.example.com/methodは`POST`、clientthisrelevant settings object)。

レスポンス処理用コールバック以外にも、fetchは高度な用途向けに追加コールバックを受け付けます。例えばprocessEarlyHintsResponseは103レスポンス用(主にナビゲーション時)、processRequestBodyChunkLengthprocessRequestEndOfBodyはリクエストbodyのアップロード進捗通知用です。

fetch操作は呼び出し元と同じスレッドで開始し、その後内部処理は並列で進行します。上記コールバックはデフォルトではclientevent loopにポストされます。自分でmain threadとの連携を扱いたい場合は、fetchuseParallelQueueをtrue)でレスポンスを並列処理できます。

進行中のfetch操作の操作

既に開始されたfetch操作を操作するには、fetch呼び出しで返されるfetchコントローラーを使用します。例えば、ユーザーやページのロジックによりabort(中止)したり、ブラウザ内部の事情によりterminate(終了)したりできます。

終了や中止以外にも、タイミング報告(initiator typeを渡して自動報告されていない場合)、完全なタイミング情報の抽出(ナビゲーションのみ)なども呼び出し元が行えます。fetchコントローラーは、requestredirect modeが"manual"の場合の次の手動リダイレクト処理にも使われます。

謝辞

感謝を表します: Adam Barth、 Adam Lavin、 Alan Jeffrey、 Alexey Proskuryakov、 Andreas Kling、 Andrés Gutiérrez、 Andrew Sutherland、 Andrew Williams、 Á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、 Benjamin VanderSloot、 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、 Feng Yu、 François Marier、 Frank Ellerman、 Frederick Hirsch、 Frederik Braun、 Gary Blackwood、 Gavin Carothers、 Glenn Maynard、 Graham Klyne、 Gregory Terzian、 Guohui Deng(邓国辉)、 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、 Simon Wülker、 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)、 Zhenbin Xu 素晴らしい協力に感謝します。

本現行標準は Anne van Kesteren (Apple, annevk@annevk.nl) によって執筆されています。

知的財産権

Copyright © WHATWG (Apple, Google, Mozilla, Microsoft)。この成果物は Creative Commons Attribution 4.0 International License に基づきライセンスされています。ソースコードに組み込まれる部分については、BSD 3-Clause License に基づきライセンスされます。

これは現行標準です。 特許審査版に関心がある場合は 現行標準レビュー草案を参照してください。

索引

この仕様で定義されている用語

参照で定義される用語

参考文献

規範的参考文献

[ABNF]
D. Crocker, Ed.; P. Overell. 構文仕様のための拡張BNF:ABNF。2008年1月。Internet Standard。URL: https://www.rfc-editor.org/rfc/rfc5234
[BEACON]
Ilya Grigorik; Alois Reitbauer. Beacon。URL: https://w3c.github.io/beacon/
[COOKIES]
Johann Hofmann; Anne van Kesteren. Cookies: HTTP 状態管理メカニズム。URL: https://httpwg.org/http-extensions/draft-ietf-httpbis-layered-cookies.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標準。現行標準。URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript言語仕様。URL: https://tc39.es/ecma262/multipage/
[ENCODING]
Anne van Kesteren. Encoding標準。現行標準。URL: https://encoding.spec.whatwg.org/
[FETCH-METADATA]
Mike West. Fetch Metadataリクエストヘッダー。URL: https://w3c.github.io/webappsec-fetch-metadata/
[FILEAPI]
Marijn Kruisselbrink. File API。URL: https://w3c.github.io/FileAPI/
[HR-TIME-3]
Yoav Weiss. 高分解能時間。URL: https://w3c.github.io/hr-time/
[HSTS]
J. Hodges; C. Jackson; A. Barth. HTTP Strict Transport Security (HSTS)。2012年11月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc6797
[HTML]
Anne van Kesteren; et al. HTML標準。現行標準。URL: https://html.spec.whatwg.org/multipage/
[HTTP]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTPセマンティクス。2022年6月。Internet Standard。URL: https://httpwg.org/specs/rfc9110.html
[HTTP-CACHING]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTPキャッシュ。2022年6月。Internet Standard。URL: https://httpwg.org/specs/rfc9111.html
[HTTP1]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTP/1.1。2022年6月。Internet Standard。URL: https://httpwg.org/specs/rfc9112.html
[HTTP3]
M. Bishop, Ed.. HTTP/3。2022年6月。提案標準。URL: https://httpwg.org/specs/rfc9114.html
[HTTP3-DATAGRAM]
D. Schinazi; L. Pardue. HTTP DatagramとCapsuleプロトコル。2022年8月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc9297
[IANA-HTTP-PARAMS]
ハイパーテキスト転送プロトコル (HTTP) パラメータ。URL: https://www.iana.org/assignments/http-parameters/http-parameters.xhtml
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 標準。現行標準。URL: https://infra.spec.whatwg.org/
[MIMESNIFF]
Gordon P. Hemsley. MIME Sniffing標準。現行標準。URL: https://mimesniff.spec.whatwg.org/
[MIX]
Emily Stark; Mike West; Carlos IbarraLopez. Mixed Content。URL: https://w3c.github.io/webappsec-mixed-content/
[PERMISSIONS-POLICY-1]
Ian Clelland. Permissions Policy。URL: https://w3c.github.io/webappsec-permissions-policy/
[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. ABNFにおける大文字小文字区別文字列サポート。2014年12月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc7405
[RFC7578]
L. Masinter. フォームからの値返却:multipart/form-data。2015年7月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc7578
[RFC9218]
K. Oku; L. Pardue. HTTPの拡張優先順位付け方式。2022年6月。提案標準。URL: https://httpwg.org/specs/rfc9218.html
[RFC9651]
M. Nottingham; P-H. Kamp. HTTPの構造化フィールド値。2024年9月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc9651
[SECURE-CONTEXTS]
Mike West. Secure Contexts。URL: https://w3c.github.io/webappsec-secure-contexts/
[SRI]
Devdatta Akhawe; et al. Subresource Integrity。URL: https://w3c.github.io/webappsec-subresource-integrity/
[SRI-2]
Frederik Braun. Subresource Integrity。URL: https://w3c.github.io/webappsec-subresource-integrity/
[STALE-WHILE-REVALIDATE]
M. Nottingham. HTTPのキャッシュ制御拡張:Stale Content。2010年5月。Informational。URL: https://httpwg.org/specs/rfc5861.html
[STREAMS]
Adam Rice; et al. Streams標準。現行標準。URL: https://streams.spec.whatwg.org/
[SVCB]
B. Schwartz; M. Bishop; E. Nygren. DNSによるService Bindingとパラメータ指定 (SVCBとHTTPS Resource Record)。2023年11月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc9460
[SW]
Yoshisato Yanagisawa; Monica CHINTALA. Service Workers。URL: https://w3c.github.io/ServiceWorker/
[TLS]
E. Rescorla. Transport Layer Security (TLS) プロトコル バージョン1.3。2018年8月。提案標準。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標準。現行標準。URL: https://url.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL標準。現行標準。URL: https://webidl.spec.whatwg.org/
[WEBSOCKETS]
Adam Rice. WebSockets標準。現行標準。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標準。現行標準。URL: https://xhr.spec.whatwg.org/

参考情報文献

[HTTPVERBSEC1]
複数ベンダーのWebサーバーではHTTP TRACEメソッドがデフォルトで有効化されています。。URL: https://www.kb.cert.org/vuls/id/867593
[HTTPVERBSEC2]
Microsoft Internet Information Server (IIS)はHTTP TRACKメソッド経由でクロスサイトスクリプティングの脆弱性があります。。URL: https://www.kb.cert.org/vuls/id/288308
[HTTPVERBSEC3]
HTTPプロキシのデフォルト設定により任意のTCP接続が許可されます。。URL: https://www.kb.cert.org/vuls/id/150227
[NAVIGATION-TIMING]
Zhiheng Wang. ナビゲーションタイミング。2012年12月17日。REC。URL: https://www.w3.org/TR/navigation-timing/
[ORIGIN]
A. Barth. WebのOrigin概念。2011年12月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc6454
[RFC1035]
P. Mockapetris. ドメイン名 - 実装と仕様。1987年11月。Internet Standard。URL: https://www.rfc-editor.org/rfc/rfc1035
[RFC2397]
L. Masinter. "data" URLスキーム。1998年8月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc2397
[RFC6960]
S. Santesson; 他. X.509インターネット公開鍵基盤オンライン証明書ステータスプロトコル - OCSP。2013年6月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc6960
[RFC7301]
S. Friedl; 他. Transport Layer Security (TLS) アプリケーション層プロトコルネゴシエーション拡張。2014年7月。提案標準。URL: https://www.rfc-editor.org/rfc/rfc7301
[RFC7918]
A. Langley; N. Modadugu; B. Moeller. Transport Layer Security (TLS) False Start。2016年8月。Informational。URL: https://www.rfc-editor.org/rfc/rfc7918
[RFC8470]
M. Thomson; M. Nottingham; W. Tarreau. HTTPにおけるEarly Dataの利用。2018年9月。提案標準。URL: https://httpwg.org/specs/rfc8470.html
[RFC9163]
E. Stark. HTTP用Expect-CT拡張。2022年6月。実験的。URL: https://www.rfc-editor.org/rfc/rfc9163

IDL索引

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 = {});
};

dictionary DeferredRequestInit : RequestInit {
  DOMHighResTimeStamp activateAfter;
};

[Exposed=Window]
interface FetchLaterResult {
  readonly attribute boolean activated;
};

partial interface Window {
  [NewObject] FetchLaterResult fetchLater(RequestInfo input, optional DeferredRequestInit 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