目標
この標準の目標は、ウェブプラットフォーム全体でフェッチ処理を統一し、関連する全ての事項について一貫した取り扱いを提供することです。具体的には以下を含みます。
- URLスキーム
- リダイレクト
- クロスオリジンのセマンティクス
- CSP [CSP]
- Fetch Metadata [FETCH-METADATA]
- Service Workers [SW]
- 混在コンテンツ [MIX]
- 安全でないリクエストのアップグレード [UPGRADE-INSECURE-REQUESTS]
- `
Referer
` [REFERRER]
そのため、この標準はThe Web Origin Conceptで最初に定義されたHTTP
`Origin
`ヘッダーのセマンティクスも置き換えます。[ORIGIN]
1. 序文
大まかに言えば、リソースのフェッチは非常に単純な操作です。リクエストが入力され、レスポンスが出力されます。しかしその詳細は複雑であり、かつては十分に文書化されていなかったり、APIごとに異なっていました。
多くのAPIがリソースをフェッチする機能を提供しています。例えばHTMLのimg
やscript
要素、CSSのcursor
やlist-style-image
、JavaScript
APIであるnavigator.sendBeacon()
やself.importScripts()
などです。Fetch標準は、これらの機能について統一的なアーキテクチャを提供し、リダイレクトやCORSプロトコルなどフェッチに関する様々な側面で一貫性を持たせます。
Fetch標準はまた、ほとんどのネットワーク機能を比較的低レベルの抽象化で公開するfetch()
JavaScript APIも定義します。
2. インフラストラクチャー
本仕様はInfra標準に依存します。[INFRA]
本仕様では、ABNF、Encoding、HTML、HTTP、MIME Sniffing、Streams、URL、Web IDL、WebSocketsの用語を使用します。 [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。
- リクエストボディチャンク長の処理
(デフォルト: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)
- process request end-of-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またはRecord(StructuredSerializeの結果)。
- next manual redirect steps(初期値 null)
- nullまたは何も受け取らないアルゴリズム。
fetch controller controllerに対して、global object globalを与えて、report timingするには:
-
Assert: controllerの report timing stepsがnullでないことを確認する。
-
controllerのreport timing stepsを globalで呼び出す。
fetch controller controllerに対してprocess the next manual redirectするには:
-
Assert: controllerの next manual redirect stepsが nullでないことを確認する。
-
controllerのnext manual redirect stepsを呼び出す。
fetch controller controllerに対してextract full timing infoするには:
-
Assert: controllerのfull timing info がnullでないことを確認する。
-
controllerのfull timing infoを返す。
fetch controller controllerに対して、オプションのerrorでabortするには:
-
controllerのstateを"
aborted
"に設定する。 -
fallbackErrorを"
AbortError
"DOMException
とする。 -
errorが与えられなければ、fallbackErrorを設定する。
-
serializedErrorをStructuredSerialize(error)とする。 例外が発生したら、それをキャッチしてserializedErrorを StructuredSerialize(fallbackError)とする。
-
controllerのserialized abort reasonに serializedErrorを設定する。
nullまたはRecord abortReasonとrealm realmを与えて、serialized abort reasonをデシリアライズするには:
-
fallbackErrorを"
AbortError
"DOMException
とする。 -
deserializedErrorをfallbackErrorとする。
-
abortReasonがnullでなければ、 deserializedErrorに StructuredDeserialize(abortReason, realm)を設定する。 例外が発生したりundefinedを返したら、deserializedErrorをfallbackErrorに設定する。
-
deserializedErrorを返す。
fetch controller
controllerに対してterminateするには、controllerのstateを
"terminated
"に設定する。
fetch params
fetchParamsは、そのcontrollerのstateが
"aborted
"であれば、abortedである。
fetch params
fetchParamsは、そのcontrollerのstateが
"aborted
"または"terminated
"であれば、canceledである。
fetch timing infoは、 構造体であり、 Resource TimingやNavigation 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)
- redirect start time(初期値 0)
DOMHighResTimeStamp
。- final connection timing info(初期値 null)
- nullまたはconnection timing info。
- server-timing headers(初期値 « »)
- 文字列のリスト。
- render-blocking(初期値 false)
- 真偽値。
response body info は、構造体であり、 Resource TimingやNavigation Timingで必要な情報を保持します。次の項目を持ちます: [RESOURCE-TIMING] [NAVIGATION-TIMING]
- encoded size
(初期値 0)
- decoded size (初期値 0)
- 数値。
- content type(初期値 空文字列)
- ASCII文字列。
- content encoding(初期値 空文字列)
- ASCII文字列。
fetch timing info timingInfoを与えてopaque timing infoを作成するには、 timingInfoのstart timeおよび post-redirect start timeが timingInfoのstart timeとなる 新しいfetch timing infoを返す。
アルゴリズムalgorithm、グローバルオブジェクトまたは並列キュー taskDestinationを与えてfetchタスクをキューするには、次の手順を実行する:
-
taskDestinationが並列キューであれば、 enqueue algorithmを taskDestinationへ。
-
それ以外の場合、グローバルタスクをキューする。networking task sourceで taskDestinationおよびalgorithmとともに。
環境設定オブジェクト environment オフラインかどうかを確認するには:
-
ユーザーエージェントがインターネット接続がないと仮定する場合、trueを返す。
-
environmentのWebDriver BiDi ネットワークがオフラインを返す。
整数を直列化するには、最も短い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引用文字列を収集するには、次の手順を実行する:
-
positionStartをpositionとする。
-
valueを空文字列とする。
-
positionを1進める。
-
無限ループ:
-
extract-valueがtrueなら、valueを返す。
-
inputのpositionStartからpositionまでの符号位置を返す。
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または構造化フィールド値です。
-
Assert: typeは"
dictionary
"、"list
"、"item
"のいずれかであること。 -
valueにlistからnameを取得した結果を格納する。
-
valueがnullなら、nullを返す。
-
resultにinput_stringをvalue、header_typeをtypeとしてstructured fieldsをパースした結果を格納する。
-
パースに失敗した場合、nullを返す。
-
resultを返す。
構造化フィールド値の取得は、ヘッダーが存在しない場合と、その値のパースが 構造化フィールド値として失敗した場合を区別しません。これによりウェブプラットフォーム全体で一貫した処理が保証されます。
タプル (ヘッダー名 name、 構造化フィールド値 structuredValue)と ヘッダーリスト listを与えて 構造化フィールド値を設定するには:
-
serializedValueに structured fieldsのシリアライズアルゴリズムをstructuredValueに対して実行した結果を格納する。
-
設定(name, serializedValue)を listに行う。
構造化フィールド値はHTTPが(将来的に)興味深く効率的な方法でシリアライズできるオブジェクトとして定義されています。現時点では、Fetchはヘッダー値をバイト列としてのみサポートしているため、これらのオブジェクトはシリアライズを通じてのみ ヘッダーリストに設定でき、 パースによってのみヘッダーリストから取得できます。将来的にはこれらがエンドツーエンドでオブジェクトとして保持される可能性があります。[RFC9651]
ヘッダー名 nameをヘッダーリスト listから 取得・デコード・分割するには、次の手順を実行する。返り値はnullまたは文字列のリスト。
-
valueに、listからnameを取得した結果を格納する。
-
valueがnullなら、nullを返す。
-
valueを取得・デコード・分割した結果を返す。
取得・デコード・分割が、`A
`をname引数として実際にどのように動作するかを示します:
ヘッダー(ネットワーク上) | 出力 |
---|---|
| « "nosniff ", "" »
|
| |
| « "" » |
| null |
| « "text/html;", x/x " »
|
| |
| « "x/x;test="hi" ", "y/y " »
|
| |
| « "x / x ", "", "", "1 " »
|
| |
| « ""1,2" ", "3 " »
|
|
ヘッダー値 valueを取得・デコード・分割するには、次の手順を実行します。返り値は文字列のリストです。
-
inputにvalueをisomorphic decodeした結果を格納する。
-
positionをinputの位置変数として、先頭位置に設定する。
-
valuesを文字列のリストとして初期化する(初期値 « »)。
-
temporaryValueを空文字列とする。
-
無限ループ:
-
positionからU+0022 (") または U+002C (,) でない符号位置の列を収集し、その結果をtemporaryValueに追加する。
この結果は空文字列でもよい。
-
positionがinputの末尾を過ぎておらず、かつinputのpositionの符号位置がU+0022 (")なら:
-
input、positionでHTTP引用文字列を収集し、その結果をtemporaryValueに追加する。
- positionがまだ末尾を過ぎていなければcontinue。
-
-
temporaryValueの先頭および末尾からすべてのHTTPタブまたはスペースを除去する。
-
追加 temporaryValueをvaluesに。
-
temporaryValueを空文字列に戻す。
-
positionがinputの末尾を過ぎていれば、valuesを返す。
-
positionを1だけ進める。
-
祝福された呼び出し箇所以外では、このアルゴリズムは直接呼び出してはいけません。代わりに取得・デコード・分割を使ってください。
ヘッダー (name, value) をヘッダーリスト listで結合するには:
結合はXMLHttpRequest
および
WebSocketプロトコルハンドシェイクで使われます。
ヘッダーリスト listをソートおよび結合するには、次の手順を実行する。返り値はヘッダーリスト。
-
headersをヘッダーリストとして初期化する。
-
namesに、list内の全名前をソート済み小文字集合へ変換した結果を格納する。
-
各namesのnameについて:
-
headersを返す。
ヘッダーは、タプルであり、 名前(ヘッダー名)と 値(ヘッダー値)から構成されます。
ヘッダー名は、バイト列であり、 field-nameトークン生成規則に一致するものです。
ヘッダー値は、バイト列であり、次の条件を満たすものです。
-
先頭および末尾にHTTPタブまたはスペースバイトがないこと。
-
0x00 (NUL) やHTTP改行バイトを含まないこと。
ヘッダー値の定義は、field-valueトークン生成規則に基づいていません。これは既存のコンテンツとの非互換性があるためです。
ヘッダー(name, value)がCORSセーフリストリクエストヘッダーかどうかを判定するには、次の手順を実行する:
-
valueの長さが128より大きい場合、falseを返す。
-
バイト小文字化したnameで次の分岐を行う:
- `
accept
` -
valueにCORS-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
` -
-
valueにCORS-unsafeリクエストヘッダーバイトが含まれていれば、falseを返す。
-
mimeTypeにMIMEタイプのパースをisomorphic decodeしたvalueに対して行った結果を格納する。
-
mimeTypeがfailureならfalseを返す。
-
mimeTypeのessenceが "
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
` -
-
rangeValueに単一レンジヘッダー値のパースをvalueとfalseで行った結果を格納する。
-
rangeValueがfailureならfalseを返す。
-
rangeValue[0]がnullならfalseを返す。
ウェブブラウザは歴史的に `
bytes=-500
` のようなレンジは出さないため、このアルゴリズムはそれらをセーフリスト化しません。
-
- その他
-
falseを返す。
- `
-
trueを返す。
`Content-Type
`ヘッダーのセーフリストには限定的な例外があり、CORSプロトコルの例外に記載されています。
CORS-unsafeリクエストヘッダーバイトとは、バイトbyteが次のいずれかに該当する場合です:
-
byteが0x20未満かつ0x09 HTでない場合
-
byteが0x22(")、0x28(左括弧)、0x29(右括弧)、0x3A(:)、0x3C(<)、0x3E(> )、0x3F(?)、0x40(@)、0x5B([)、0x5C(\)、0x5D(])、0x7B({)、0x7D(})、または0x7F DELの場合。
CORS-unsafeリクエストヘッダー名は、ヘッダーリスト headersに対して次の手順で決定します:
CORSノンワイルドカードリクエストヘッダー名は、ヘッダー名であり、バイト大小区別なしで`Authorization
`と一致するものです。
特権no-CORSリクエストヘッダー名は、ヘッダー名であり、 バイト大小区別なしで以下のいずれかと一致するものです。
- `
Range
`。
これらは特権APIによって設定できるヘッダーであり、関連するリクエストオブジェクトがコピーされた場合は保持されますが、非特権APIによってリクエストが変更された場合には削除されます。
`Range
`ヘッダーは、ダウンロードやメディアの取得によく使われます。
特定のリクエストにRangeヘッダーを追加するためのヘルパーも用意されています。
CORSセーフリストレスポンスヘッダー名は、リスト ヘッダー名 list を与えて、以下のいずれかにバイト大小区別なしで一致するヘッダー名です。
- `
Cache-Control
` - `
Content-Language
` - `
Content-Length
` - `
Content-Type
` - `
Expires
` - `
Last-Modified
` - `
Pragma
` - list内の項目で、禁止レスポンスヘッダー名でないもの
no-CORSセーフリストリクエストヘッダー名は、ヘッダー名であり、 バイト大小区別なしで以下のいずれかと一致するものです。
- `
Accept
` - `
Accept-Language
` - `
Content-Language
` - `
Content-Type
`
ヘッダー(name, value)がno-CORSセーフリストリクエストヘッダーかどうかを判定するには、次の手順を実行します:
-
nameがno-CORSセーフリストリクエストヘッダー名でなければfalseを返す。
-
(name, value)がCORSセーフリストリクエストヘッダーかどうかを返す。
ヘッダー(name, value)が禁止リクエストヘッダーかどうかは、次の手順でtrueなら該当します:
-
nameが、次のいずれかにバイト大小区別なしで一致すればtrueを返す:
- `
Accept-Charset
` - `
Accept-Encoding
` - `
Access-Control-Request-Headers
` - `
Access-Control-Request-Method
` - `
Connection
` - `
Content-Length
` - `
Cookie
` - `
Cookie2
` - `
Date
` - `
DNT
` - `
Expect
` - `
Host
` - `
Keep-Alive
` - `
Origin
` - `
Referer
` - `
Set-Cookie
` - `
TE
` - `
Trailer
` - `
Transfer-Encoding
` - `
Upgrade
` - `
Via
`
該当すればtrueを返す。
- `
-
nameが、次のいずれかにバイト大小区別なしで一致すれば:
- `
X-HTTP-Method
` - `
X-HTTP-Method-Override
` - `
X-Method-Override
`
その場合:
-
parsedValuesに取得・デコード・分割したvalueの結果を格納する。
-
各parsedValuesのmethodについて、 そのisomorphic encodeが禁止メソッドであればtrueを返す。
- `
-
falseを返す。
これらはユーザーエージェントが完全に制御できるようにするために禁止されています。
ヘッダー名が`Sec-
`で始まるものは、新しいヘッダーをAPIで開発者が制御できるfetch系API(例:XMLHttpRequest
)で安全に追加できるように予約されています。[XHR]
`Set-Cookie
`ヘッダーは意味的にはレスポンスヘッダーであり、リクエストには不要です。また、`Set-Cookie
`ヘッダーは結合できないため、Headers
オブジェクトではより複雑な処理が必要となります。ここで禁止することで、この複雑さがリクエストに漏れないようにしています。
禁止レスポンスヘッダー名は、ヘッダー名であり、バイト大小区別なしで以下のいずれかに一致するものです。
- `
Set-Cookie
` - `
Set-Cookie2
`
リクエストボディヘッダー名は、ヘッダー名であり、バイト大小区別なしで以下のいずれかに一致するものです。
- `
Content-Encoding
` - `
Content-Language
` - `
Content-Location
` - `
Content-Type
`
ヘッダー headerに対してヘッダー値を抽出するには次の手順を実行します:
整数rangeStart、整数rangeEnd、整数fullLengthを与えてコンテンツレンジを構築するには、次の手順を実行します:
-
contentRangeを`
bytes
`とする。 -
rangeStartを直列化し、isomorphic encodeしてcontentRangeに追加する。
-
0x2D (-) をcontentRangeに追加する。
-
rangeEndを直列化し、isomorphic encodeしてcontentRangeに追加する。
-
0x2F (/) をcontentRangeに追加する。
-
fullLengthを直列化し、isomorphic encodeしてcontentRangeに追加する。
-
contentRangeを返す。
バイト列 valueと真偽値allowWhitespaceを与えて単一レンジヘッダー値のパースを行うには、次の手順を実行します:
-
dataにvalueをisomorphic decodeした結果を格納する。
-
dataが"
bytes
"で始まらない場合、failureを返す。 -
allowWhitespaceがtrueなら、HTTPタブまたはスペースをdataのpositionから収集する。
-
positionのdataにおける符号位置がU+003D (=)でなければfailureを返す。
-
positionを1進める。
-
allowWhitespaceがtrueなら、HTTPタブまたはスペースをdataのpositionから収集する。
-
rangeStartにdataのpositionからASCII数字の列を収集した結果を格納する。
-
rangeStartValueにrangeStartが空でなければ10進数として解釈した値を、空ならnullを格納する。
-
allowWhitespaceがtrueなら、HTTPタブまたはスペースをdataのpositionから収集する。
-
positionのdataにおける符号位置がU+002D (-)でなければfailureを返す。
-
positionを1進める。
-
allowWhitespaceがtrueなら、HTTPタブまたはスペースをdataのpositionから収集する。
-
rangeEndにdataのpositionからASCII数字の列を収集した結果を格納する。
-
rangeEndValueにrangeEndが空でなければ10進数として解釈した値を、空ならnullを格納する。
-
positionがdataの末尾を過ぎていなければfailureを返す。
-
rangeEndValueとrangeStartValueが両方nullならfailureを返す。
-
rangeStartValueとrangeEndValueが数値で、rangeStartValueがrangeEndValueより大きければfailureを返す。
-
(rangeStartValue, rangeEndValue)を返す。
rangeのendまたはstartは省略可能であり、`
bytes=0-
`や`bytes=-500
`も有効なレンジです。
単一レンジヘッダー値のパースは許可されるレンジヘッダー値の一部でしか成功しませんが、ユーザーエージェントがメディアやダウンロード再開時に使用する最も一般的な形式です。この形式のレンジヘッダー値はRangeヘッダーを追加で設定できます。
デフォルト`User-Agent
`値は、`User-Agent
`ヘッダーに対する実装依存のヘッダー値です。
不幸なウェブ互換性の理由から、ウェブブラウザーはこの値を `Mozilla/5.0 (
`
で始めること、そして他のウェブブラウザーを一般的に模倣することが強く推奨されています。
環境設定オブジェクト environmentの
環境のデフォルト `User-Agent
` 値
を取得するには、次の手順に従う:
-
userAgent を WebDriver BiDi エミュレートされた User-Agent(environment 用)として取得する。
-
userAgent が非 null であれば、userAgent を isomorphic encode されたものとして返す。
ドキュメント`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. ボディ
ボディは次の要素から成ります:
-
ストリーム(
ReadableStream
オブジェクト) -
長さ(nullまたは整数)、初期値はnull
ボディ bodyを複製するには、次の手順を実行します:
ボディ bodyを逐次的に読み込むには、アルゴリズムprocessBodyChunk、アルゴリズムprocessEndOfBody、アルゴリズムprocessBodyError、および省略可能なnull/並列キューまたはグローバルオブジェクト taskDestination(デフォルトnull)を与えて、次の手順を実行します。 processBodyChunkはバイト列を受け取るアルゴリズム、processEndOfBodyは引数なしアルゴリズム、processBodyErrorは例外を受け取るアルゴリズムでなければなりません。
-
taskDestinationがnullなら、新しい並列キューの開始の結果をtaskDestinationに設定する。
-
readerにbodyのストリームに対してリーダーの取得を実行した結果を格納する。
この操作で例外はスローされません。
-
逐次読み込みループをreader、taskDestination、processBodyChunk、processEndOfBody、processBodyErrorで実行する。
ReadableStreamDefaultReader
オブジェクトreader、並列キューまたはグローバルオブジェクト
taskDestination、アルゴリズムprocessBodyChunk、アルゴリズムprocessEndOfBody、アルゴリズムprocessBodyErrorを与えて逐次読み込みループを実行するには:
-
readRequestを次の読取リクエストとする:
- chunk steps(chunkを与えて)
-
-
continueAlgorithmをnullとする。
-
chunkが
Uint8Array
オブジェクトでなければ、continueAlgorithmを「processBodyErrorにTypeError
を与えて実行する」に設定する。 -
それ以外の場合:
-
fetchタスクをキューでcontinueAlgorithmとtaskDestinationを与えて実行する。
-
- close steps
-
-
fetchタスクをキューでprocessEndOfBodyとtaskDestinationを与えて実行する。
-
- error steps(eを与えて)
-
-
fetchタスクをキューでprocessBodyErrorにeを与え、taskDestinationで実行する。
-
-
チャンクの読み取りをreaderにreadRequestを与えて実行する。
ボディ bodyを完全に読み込むには、アルゴリズムprocessBody、アルゴリズムprocessBodyError、および省略可能なnull/並列キューまたはグローバルオブジェクト taskDestination(デフォルトnull)を与えて、次の手順を実行します。processBodyはバイト列を受け取るアルゴリズム、processBodyErrorはオプションで例外を受け取るアルゴリズムでなければなりません。
-
taskDestinationがnullなら、新しい並列キューの開始の結果をtaskDestinationに設定する。
-
successStepsをバイト列 bytesを受け取り、 fetchタスクをキューでprocessBodyにbytesを与えtaskDestinationで実行する手順とする。
-
errorStepsを(オプションの例外 exceptionを受け取り) fetchタスクをキューでprocessBodyErrorにexceptionを与えtaskDestinationで実行する手順とする。
-
readerにbodyのストリームに対してリーダーの取得を実行した結果を格納する。例外が発生した場合、errorStepsをその例外で実行し終了する。
-
全バイトの読み取りをreaderでsuccessStepsとerrorStepsを与えて実行する。
型付きボディは、タプルであり、 ボディ(ボディ)と 型(ヘッダー値またはnull)から構成されます。
codingsとbytesを与えてコンテンツ符号化の処理を行うには、次の手順を実行します:
-
codingsがサポートされていなければ、bytesを返す。
-
HTTPの説明通りにcodingsでbytesをデコードした結果(エラーでなければ)を返し、デコードに失敗したらfailureを返す。[HTTP]
2.2.5. リクエスト
この節ではリクエストの詳細な動作を記述します。導入は リクエストのセットアップを参照してください。
fetchの入力はリクエストです。
リクエストには、関連付けられたメソッド(メソッド)があります。特に記載がない限り、`GET
`です。
これはリダイレクト時にGET
へ更新される場合があります。詳細はHTTP fetchを参照。
リクエストには、関連付けられたURL (URL)があります。
実装はこれを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
"のいずれかです。
リクエストには、関連付けられたdestination(destination type)があります。特に記載がない限り空文字列です。
これらはRequestDestination
で反映されますが、"serviceworker
"と"webidentity
"は該当しません。これらのdestinationではサービスワーカーをスキップします。
リクエストのdestinationがscript-likeとなるのは、"audioworklet
"、"paintworklet
"、"script
"、"serviceworker
"、"sharedworker
"、または"worker
"の場合です。
script-likeを利用するアルゴリズムは、"xslt
"もスクリプト実行の原因となり得るため考慮すべきです。ただし、常に該当するとは限らず異なる動作が必要な場合があるためリストには含まれていません。
次の表は、リクエストの initiator、destination、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() 、XMLHttpRequest 、
WebSocket 、
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-src 、script-src 、worker-src
| navigator.serviceWorker.register()
| |
"sharedworker "
| child-src 、script-src 、worker-src
| SharedWorker
| |
"webidentity "
| connect-src
| Federated Credential Management requests
| |
"worker "
| child-src 、script-src 、worker-src
| Worker
| |
"json "
| connect-src
| import "..." with { type: "json" }
| |
"style "
| style-src
| HTMLの<link rel=stylesheet> 、CSSの@import 、
import "..." 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
`
のいずれかが含まれる場合、fetchは
cache
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]
リクエスト
requestのredirect-taintを計算するには、次の手順を実行します。返り値は"same-origin
"、"same-site
"、または"cross-site
"です。
-
lastURLをnullとする。
-
taintを"
same-origin
"とする。 -
taintを返す。
request requestに対してリクエストoriginの直列化を行うには、次の手順を実行します:
-
requestのredirect-taintが"
same-origin
"でなければ、"null
"を返す。
request requestに対してリクエストoriginのバイト直列化を行うには、リクエストoriginの直列化の結果をisomorphic encodeしたものを返す。
リクエスト requestを複製するには、次の手順を実行します:
リクエスト requestに整数first、オプションで整数lastを与えてRangeヘッダーを追加するには、次の手順を実行します:
-
Assert: lastが与えられていないか、firstがlast以下であること。
-
rangeValueを`
bytes=
`とする。 -
直列化し、isomorphic encodeしたfirstをrangeValueに追加する。
-
0x2D (-) をrangeValueに追加する。
-
lastが与えられていれば、それを直列化してisomorphic encodeした結果をrangeValueに追加する。
Rangeヘッダーはバイト範囲(両端を含む)を表します。たとえば、firstが0、lastが500の場合、501バイトの範囲になります。
複数のレスポンスを1つの論理リソースに結合する機能は、歴史的にセキュリティバグの原因となってきました。部分レスポンスを扱う機能を設計する場合は、必ずセキュリティレビューを受けてください。
response responseに対して報告用レスポンスURLの直列化を行うには、次の手順を実行します:
request requestに対してCross-Origin-Embedder-Policyが認証情報を許可するか確認するには、次の手順を実行します:
-
requestのmodeが"
no-cors
"でなければtrueを返す。 -
requestのclientがnullであればtrueを返す。
-
requestのclientのポリシーコンテナのembedder policyの値が"
credentialless
"でなければtrueを返す。 -
requestのoriginがrequestの現在のURLのoriginとsame originであり、かつrequestのredirect-taintが"
same-origin
"でなければtrueを返す。 -
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 WorkersやResource 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 info (response 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を与えて適切なネットワークエラーを作るには:
-
fetchParamsがabortedなら中断されたネットワークエラーを、それ以外ならネットワークエラーを返す。
フィルタ済みレスポンスとは、関連付けられたレスポンスへの限定的なビューを提供するレスポンスです。この関連するレスポンスは、フィルタ済みレスポンスの内部レスポンス(ネットワークエラーやフィルタ済みレスポンスでないレスポンス)としてアクセスできます。
特に記載がない限り、フィルタ済みレスポンスの各概念(例:ボディ)は、内部レスポンスの対応する概念を参照します(例外はこの後、フィルタ済みレスポンスの具体的な型の定義部分で記載)。
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を複製するには、次の手順を実行します:
-
responseがフィルタ済みレスポンスであれば、内部レスポンスがresponseの内部レスポンスの複製である、新しい同一のフィルタ済みレスポンスを返す。
-
newResponseをresponseのコピー(ただしボディを除く)とする。
-
responseのボディがnullでなければ、newResponseのボディに複製したresponseのボディを設定する。
-
newResponseを返す。
新鮮なレスポンスは、 レスポンスであって、 現在エージが、その 鮮度寿命以内であるものです。
stale-while-revalidateレスポンスは、 レスポンスであって、 新鮮なレスポンスでなく、 現在エージが stale-while-revalidate寿命以内であるものです。 [HTTP-CACHING] [STALE-WHILE-REVALIDATE]
古いレスポンスは、 レスポンスであって、 新鮮なレスポンスでも stale-while-revalidateレスポンスでもないものです。
レスポンス responseの location URLは、 nullまたはASCII文字列 requestFragmentを与えて、 次の手順で決定されます。返り値はnull・failure・またはURLです。
-
responseのstatusが リダイレクトステータスでなければnullを返す。
-
locationを ヘッダーリスト値を抽出(`
Location
`・responseのヘッダーリスト)の結果とする。 -
locationがヘッダー値なら、 locationをパース(location・responseのURL)の結果に置き換える。
responseが
Response
コンストラクターで生成された場合、 responseのURLはnullとなるため、 locationは絶対URL+フラグメント文字列でなければパースに成功しません。 -
locationがURLで、 そのfragmentがnullなら、 locationのfragmentにrequestFragmentを設定する。
これにより、合成レスポンス(実際には全てのレスポンス)がHTTPで定義されるリダイレクトの処理モデルに従うことが保証されます。[HTTP]
-
locationを返す。
location URLアルゴリズムは、この標準と、リダイレクトを手動で処理するHTMLのnavigateアルゴリズム専用です。[HTML]
2.2.7. その他
潜在的なdestinationは、"fetch
"または空文字列でないdestinationです。
潜在的なdestination potentialDestinationを変換するには、次の手順を実行します:
-
potentialDestinationが"
fetch
"なら空文字列を返す。 -
Assert: potentialDestinationはdestinationであること。
-
potentialDestinationを返す。
2.3. 認証エントリ
認証エントリおよびプロキシ認証エントリは、ユーザー名・パスワード・レルムからなるタプルであり、HTTP認証およびHTTPプロキシ認証に使われ、1つ以上のリクエストに関連付けられます。
ユーザーエージェントは、認証エントリとHTTPクッキーや同様のトラッキング機能を一括してクリアできるようにすべきです。
詳細はHTTPで定義されています。[HTTP] [HTTP-CACHING]
2.4. 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が 終了された場合:
-
各fetchレコード recordについて、 fetchGroupのfetchレコードのうち、 recordのcontrollerがnullでなく、 recordのrequestのdoneフラグが未設定で、 keepaliveがfalseの場合、 terminate recordの controller。
-
遅延fetchを処理する(fetchGroupに対して)。
2.5. ドメインの解決
ネットワークパーティションキー keyと
オリジン originを与えて
オリジンを解決するには、次の手順を実行します:
-
originのhostのパブリックスフィックスが"
localhost
"または"localhost.
"であれば、 «::1
,127.0.0.1
» を返す。 -
originを1つ以上のIPアドレスの 集合に変換する 実装依存の操作を行う。
他にも、IPアドレス以外の 接続情報を取得するために他の操作を行うかどうかも 実装依存です。例えば、 originのスキームが HTTP(S)スキームの場合、実装はHTTPS RRのためのDNSクエリを行うかもしれません。[SVCB]
-
failureを返す。
オリジンを解決するの結果はキャッシュしてもよい。キャッシュする場合はkeyをキャッシュキーの一部として用いるべきである。
2.6. コネクション
ユーザーエージェントは、関連付けられたコネクションプールを持ちます。 コネクションプールは、 0個以上の順序付き集合としてのコネクションです。各コネクションは、関連付けられたキー(ネットワークパーティションキー)、 オリジン(オリジン)、および認証情報 (boolean)で識別されます。
各コネクションは、関連付けられた タイミング情報( コネクションタイミング情報)を持ちます。
コネクションタイミング情報は、 コネクション取得処理に関するタイミング情報を保持するための 構造体です。以下の項目があります:
- ドメインルックアップ開始時刻(初期値0)
- ドメインルックアップ終了時刻(初期値0)
- コネクション開始時刻(初期値0)
- コネクション終了時刻(初期値0)
- セキュアコネクション開始時刻(初期値0)
- ドメインルックアップ終了時刻(初期値0)
DOMHighResTimeStamp
。- ALPNネゴシエートプロトコル(初期値:空のバイト列)
- バイト列。
コネクションタイミング情報のclampおよびcoarsenを行うには、
コネクションタイミング情報 timingInfo、
DOMHighResTimeStamp
defaultStartTime、boolean crossOriginIsolatedCapabilityを与えて次の手順を実行する:
-
timingInfoのコネクション開始時刻が defaultStartTimeより小さければ、新しいコネクションタイミング情報を返す(全ての時刻がdefaultStartTime、ALPNネゴシエートプロトコルはtimingInfoの値)。
-
新しいコネクションタイミング情報を返す(各時刻はcoarsen timeの結果、ALPNネゴシエートプロトコルはtimingInfoの値)。
新規コネクション設定は、"no
"、"yes
"、"yes-and-dedicated
"のいずれかです。
コネクションを取得するには、
ネットワークパーティションキー key、
URL url、
boolean credentials、
任意の新規コネクション設定 new(初期値"no
")、
任意のboolean requireUnreliable(初期値false)を与え、次の手順を実行する:
-
newが"
no
"なら: -
proxiesを実装依存の方法でurlのプロキシとして探索した結果とする。なければ« "
DIRECT
" »とする。ここで非標準技術(WPADやPAC)が使われる可能性があります。"
DIRECT
"は、このurlでプロキシを使わないことを意味します。 -
timingInfoを新しいコネクションタイミング情報とする。
-
各proxiesのproxyについて:
-
timingInfoのドメインルックアップ開始時刻 をunsafe shared current timeに設定する。
-
hostsがfailureなら、continue。
-
timingInfoのドメインルックアップ終了時刻を unsafe shared current timeに設定する。
-
connectionを、以下の手順で得られた結果とする:コネクション作成に、key、urlのオリジン、credentials、proxy、hostsから実装依存で選択したhost、timingInfo、requireUnreliableを与え、実装依存の回数だけ並列で実行し、少なくとも1つの値を待つ。実装依存で返す値を選び、それを返す。他の値(コネクション)は閉じてよい。
本質的には、オリジンを解決する(proxyが"
DIRECT
"の場合)から返された複数のIPアドレスを競わせたり、IPv6優先したり、タイムアウトで再試行したりできることを意味します。 -
connectionがfailureなら、continue。
-
newが"
yes-and-dedicated
"でなければ、 append connectionをユーザーエージェントのコネクションプールに追加する。 -
connectionを返す。
-
-
failureを返す。
コネクション管理には多くの微妙な点があるため、詳細は実装者の裁量に任せています。これを記述することで、<link rel=preconnect>
やコネクションが認証情報でキーされることを明確にできます。例えば、TLSセッションIDは認証情報がfalseのコネクションとtrueのコネクション間で再利用されません。
コネクション作成は、 ネットワークパーティションキー key、 オリジン origin、 boolean credentials、string proxy、 host host、 コネクションタイミング情報 timingInfo、 boolean requireUnreliableを与え、次の手順を実行する:
-
timingInfoのコネクション開始時刻を unsafe shared current timeに設定する。
-
connectionを新しいコネクションとし、 キーにkey、 オリジンにorigin、 認証情報にcredentials、 タイミング情報にtimingInfoを持たせる。 コネクションタイミング情報記録を行い、 connectionを使ってhostにHTTPコネクションを確立する(proxy、originを考慮)。以下の注意点あり: [HTTP] [HTTP1] [TLS]
-
requireUnreliableがtrueなら、unreliable transport対応(例:HTTP/3)のコネクションを確立する。[HTTP3]
-
unreliable transport対応コネクションの場合、WebTransport用オプション(HTTP/3の場合、
SETTINGS_ENABLE_WEBTRANSPORT
を1
・H3_DATAGRAM
を1
で初期SETTINGSフレームに含める)を有効化する。[WEBTRANSPORT-HTTP3] [HTTP3-DATAGRAM] -
credentialsがfalseなら、TLSクライアント証明書を送信しない。
-
コネクション確立に失敗した場合(UDP/TCP/TLSエラー等)は、failureを返す。
-
-
timingInfoのALPNネゴシエートプロトコルを connectionのALPN Protocol IDに設定する。以下の注意点あり:[RFC7301]
-
プロキシ利用時は、トンネルが確立されていればそのプロトコルのALPN Protocol ID、そうでなければ最初のプロキシへのALPN Protocol IDとする。
-
実験的・非登録プロトコルの場合、利用したALPN Protocol ID(あれば)を使う。ALPNを使っていない場合は別の説明的な文字列でもよい。
timingInfoのALPNネゴシエートプロトコルは、実際のネゴシエーション方法に関わらず利用中のネットワークプロトコルを識別するためのものです。
IANAはALPN Protocol IDのリストを管理しています。
-
-
connectionを返す。
コネクションタイミング情報記録は、 コネクション connectionを受け取り、 timingInfoをconnectionの タイミング情報として次を満たすこと:
-
timingInfoのコネクション終了時刻は、サーバやプロキシへのコネクション確立直後に unsafe shared current timeとする。詳細:
-
返される時刻には、トランスポートコネクション確立にかかる時間やSOCKS認証等の時間も含めること。TLSハンドシェイクのリソース要求可能になるまでの時間も含めること。
-
TLS False Start利用時は、サーバのFinishedメッセージ受信までの時間は含めないこと。[RFC7918]
-
早期データでリクエスト送信時は、サーバのServerHello受信までの時間は含めないこと。[RFC8470]
-
リクエスト送信時にハンドシェイク完了を待つ場合は、早期データ利用の他リクエストが同一コネクションであってもTLSハンドシェイク全体を含めること。
たとえば、ユーザーエージェントがTLS 1.3でHTTP/2コネクションを確立し
GET
とPOST
を送信した場合、ClientHello送信時刻をt1、GET
はearly dataで送信、POST
は安全でないため([HTTP] 9.2.1)、t2でハンドシェイク完了まで待つと、同一コネクションでもGETはt1、POSTはt2をコネクション終了時刻として報告します。 -
-
セキュアなトランスポートを使う場合、timingInfoのセキュアコネクション開始時刻は、 connectionをセキュア化するハンドシェイク直前の unsafe shared current timeとする。[TLS]
-
connectionがHTTP/3コネクションの場合、timingInfoのコネクション開始時刻とセキュアコネクション開始時刻は等しいこと(HTTP/3ではコネクション確立時にセキュアハンドシェイクも同時に行う)。[HTTP3]
コネクションタイミング情報のclampおよびcoarsenアルゴリズムは、再利用コネクションの詳細やタイム値の丸めを保証します。
2.7. ネットワークパーティションキー
ネットワークパーティションキーは、サイトと、nullまたは実装依存の値からなるタプルです。
environment environmentを与え、ネットワークパーティションキーを決定するには、次の手順を実行します:
-
topLevelOriginをenvironmentの トップレベルオリジンとする。
-
topLevelOriginがnullなら、topLevelOriginをenvironmentのトップレベル生成URLのオリジンとする。
-
topLevelSiteをtopLevelOriginを与えてサイト取得の結果とする。
-
secondKeyをnullまたは実装依存の値とする。
second keyは意図的に曖昧にされています。詳細は今後詰められます。issue #1035参照。
-
(topLevelSite, secondKey)を返す。
request requestを与え、ネットワークパーティションキーを決定するには、次の手順を実行します:
-
requestのreserved clientがnullでなければ、 requestのreserved clientを与えて ネットワークパーティションキーを決定するの結果を返す。
-
requestのclientがnullでなければ、 requestのclientを与えて ネットワークパーティションキーを決定するの結果を返す。
-
nullを返す。
2.8. HTTPキャッシュパーティション
HTTPキャッシュパーティションを決定するには、リクエスト requestを与えて次の手順を実行する:
-
keyをrequestを与えてネットワークパーティションキーを決定するの結果とする。
-
keyがnullならnullを返す。
-
keyに関連付けられた一意なHTTPキャッシュを返す。[HTTP-CACHING]
2.9. ポートブロッキング
新しいプロトコルは、TLSを用いたALPNでプロトコルをネゴシエートすることで、ポートブロックの必要性を回避できます。その場合、プロトコルはHTTPリクエストを通して偽装されることはありません。 [RFC7301]
リクエスト requestについて悪いポートによるブロックが必要か判定するには:
-
urlをrequestの現在のURLとする。
-
urlのスキームがHTTP(S)スキームであり、かつurlのポートが悪いポートであれば、blockedを返す。
-
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 |
3. HTTP拡張
3.1. Cookie
`Cookie
`リクエストヘッダーおよび`Set-Cookie
`レスポンスヘッダーは主にそれぞれの仕様で定義されています。ここでは、それらを便利に利用できるよう補助的なインフラを定義します。[COOKIES]。
3.1.1. `Cookie
` ヘッダー
リクエスト`Cookie
`ヘッダーを付加するには、リクエスト
requestを与えて、次の手順を実行する:
-
ユーザーエージェントがrequestについてCookieを無効化している場合、何もせず戻る。
-
sameSiteをrequestに対してsame-siteモードを決定するの結果とする。
-
isSecureをrequestの現在のURLの スキームが"
https
"ならtrue、そうでなければfalseとする。 -
httpOnlyAllowedをtrueとする。
これはfetchから呼ばれるためtrueとなる。たとえば
document.cookie
のgetter手順とは異なる。 -
cookiesをisSecure、requestの現在のURLのホスト、requestの現在のURLのパス、httpOnlyAllowed、sameSiteを与えてCookie取得の結果とする。
Cookieストアは順序付きのCookieリストを返す。
-
cookiesが空であれば、何もせず戻る。
-
valueをcookiesを与えてCookie直列化の結果とする。
3.1.2. `Set-Cookie
` ヘッダー
レスポンス`Set-Cookie
`ヘッダーの解析および保存は、
リクエスト
requestとレスポンス responseを与えて、次の手順を実行する:
-
ユーザーエージェントがrequestについてCookieを無効化している場合、何もせず戻る。
-
allowNonHostOnlyCookieForPublicSuffixをfalseとする。
-
isSecureをrequestの現在のURLの スキームが"
https
"ならtrue、そうでなければfalseとする。 -
httpOnlyAllowedをtrueとする。
これはfetchから呼ばれるためtrueとなる。たとえば
document.cookie
のgetter手順とは異なる。 -
sameSiteStrictOrLaxAllowedを、requestに対してsame-siteモードを決定するの結果が"
strict-or-less
"ならtrue、そうでなければfalseとする。 -
各 header をresponseのヘッダーリストから順に処理する:
-
headerの名前が
Set-Cookie
とバイト単位で大文字小文字を区別せず一致しなければ、continue。 -
Cookieの解析および保存をheaderの値、isSecure、requestの現在のURLのホスト、requestの現在のURLのパス、httpOnlyAllowed、allowNonHostOnlyCookieForPublicSuffix、sameSiteStrictOrLaxAllowedを与えて実行する。
-
Cookieのガベージコレクトをrequestの現在のURLのホストを与えて実行する。
他の場所でも指摘されているとおり、`
Set-Cookie
`ヘッダーは結合できず、各出現ごとに個別に処理される。他のヘッダーではこれは許可されない。 -
3.1.3. Cookieインフラストラクチャ
same-siteモードを決定するには、リクエスト requestを与えて次の手順を実行する:
-
requestのトップレベルナビゲーションイニシエータオリジンがnullでなく、かつrequestのURLのオリジンとsame siteでなければ、"
unset-or-less
"を返す。 -
requestのメソッドが"
GET
"かつ requestのdestinationが"document"なら、"lax-or-less
"を返す。 -
requestのclientのcross-site ancestorを持つがtrueなら、"
unset-or-less
"を返す。 -
requestのredirect-taintが"
cross-site
"なら、"unset-or-less
"を返す。 -
"
strict-or-less
"を返す。
シリアライズされたCookieデフォルトパスを、URL urlから取得するには、以下を行う:
-
cloneURLをurlのクローンとして作成する。
-
cloneURLのパスを、Cookieデフォルトパス(cloneURLのパスの)に設定する。
-
cloneURLのURLパスのシリアライズを返す。
3.2. `Origin
` ヘッダー
`Origin
`リクエストヘッダーは、
fetchがどこから発生したかを示します。
`Origin
`ヘッダーは、パスを公開しない`Referer
` [sic] ヘッダーのバージョンです。
HTTPフェッチで、
リクエストのレスポンステインティングが"cors
"の場合や、
リクエストのメソッドが`GET
`または`HEAD
`以外の場合に利用されます。
互換性上の理由から、すべてのfetchに含まれるわけではありません。
その値としては、リクエストオリジンのバイト列シリアライズ(リクエストを与える)で得られるすべての値が許可されます。
これはThe Web Origin Conceptの定義に取って代わります。[ORIGIN]
リクエスト`Origin
`ヘッダーを付加する
には、リクエスト
requestを与えて次の手順を実行する:
-
serializedOriginを、requestを与えてリクエストオリジンのバイト列シリアライズの結果とする。
-
もし request の レスポンステインティング が "
cors
" または request の モード が "websocket
" の場合、 追加 (`Origin
`, serializedOrigin) を request の ヘッダーリスト に追加する。 -
さもなければ、requestのメソッドが`
GET
`でも`HEAD
`でもない場合:-
requestのmodeが"
cors
"でなければ、 requestのreferrer policyに応じて次を行う:- "
no-referrer
" -
serializedOriginを`
null
`に設定する。 - "
no-referrer-when-downgrade
"- "
strict-origin
"- "
strict-origin-when-cross-origin
" - "
-
requestのoriginがタプルオリジンで、 そのschemeが"
https
"、かつrequestの現在のURLのschemeが"https
"でなければ serializedOriginを`null
`に設定する。 - "
same-origin
" -
requestのoriginが requestの現在のURLのオリジンと 同一オリジンでなければ serializedOriginを`
null
`に設定する。 - その他
- 何もしない。
- "
-
リクエストのreferrer policyは、 フェッチャーがサーバーとオリジンを共有することを明示的に選択していないすべてのfetchで考慮されます(例:CORSプロトコルの利用)。
3.3. CORSプロトコル
レスポンスをオリジン間で共有し、HTMLの
form
要素よりも多様なfetchを可能にするために、CORSプロトコルが存在します。
これはHTTPの上にレイヤー化されており、レスポンスが他のオリジンと共有できることを宣言できます。
これはファイアウォール(イントラネット)内のレスポンスからデータが漏洩するのを防ぐため、オプトインの仕組みである必要があります。また、リクエストに認証情報が含まれる場合も、機密データ漏洩防止のためオプトインが必要です。
この節はサーバー開発者向けにCORSプロトコルを説明します。 ユーザーエージェントの要件はfetchアルゴリズムの一部ですが、 新しいHTTPヘッダー構文を除きます。
3.3.1. 一般
CORSプロトコルは、レスポンスがオリジン間で共有できるかどうかを示す一連のヘッダーから成ります。
HTMLの
form
要素で可能なものよりも複雑なリクエストの場合、
CORSプリフライトリクエストが実行され、
リクエストの
現在のURLがCORSプロトコルに対応しているか確認されます。
3.3.2. HTTPリクエスト
CORSリクエストとは、`Origin
`ヘッダーを含むHTTPリクエストです。
ただし、CORSプロトコルに参加しているかどうかは確実には判別できません。
なぜなら、`Origin
`ヘッダーは
リクエストのメソッドが`GET
`または`HEAD
`以外の時も常に含まれるためです。
CORSプリフライトリクエストは、CORSリクエストのうち、
CORSプロトコルが理解されているか確認するためのものです。
これはOPTIONS
をメソッドとして使い、次のヘッダーを含みます:
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
` - `
Access-Control-Allow-Headers
` - `
Access-Control-Max-Age
` -
`
Access-Control-Allow-Methods
`および `Access-Control-Allow-Headers
`ヘッダーで提供された情報がキャッシュ可能な秒数(デフォルト5秒)を示します。
CORSプリフライトリクエストでない CORSリクエストへのHTTPレスポンスは、次のヘッダーも含めることができます:
サーバー開発者が共有の意図を持つCORSリクエストへの成功したHTTPレスポンスは、 上記のヘッダーとリクエストと一致した値を含める限り、任意のステータスを利用できます。
CORSプリフライトリクエストへの成功したHTTPレスポンスも同様ですが、okステータス(例: 200や204)に制限されます。
他の種類のHTTPレスポンスは成功とは見なされず、共有されないかCORSプリフライトリクエストが失敗します。サーバーが明示的に示したい場合は、403ステータスと該当するヘッダーの省略を組み合わせて使うこともできます。
「失敗」も共有したい場合は可能ですが、それは成功したHTTPレスポンスとなります。そのため、CORSプリフライトリクエストでないCORSリクエストへの成功したHTTPレスポンスのステータスは、403も含めて何でもよいです。
最終的に、サーバー開発者はHTTPレスポンスの扱いにおいて多くの自由があります。これらの戦略はCORSプリフライトリクエストと、その後のCORSリクエストで異なる場合があります:
-
静的レスポンスを返すことができます。これはキャッシュ中継サーバと連携する場合に有用です。静的レスポンスは状況により成功にも失敗にもなり得ます。これは問題ありません。
-
動的レスポンスを返し、CORSリクエストに合わせて調整することもできます。これはレスポンス本文を特定のオリジンに合わせたり、認証情報付きで特定オリジン群に成功させたい場合に有用です。
3.3.4. HTTP新ヘッダー構文
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
`レスポンスヘッダーを返しています。
hsts
やcsp
の値は、`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
`ヘッダー値でリクエストされうることを想定する必要があります:
- `
application/csp-report
` [CSP] - `
application/expect-ct-report+json
` [RFC9163] - `
application/xss-auditor-report
` - `
application/ocsp-request
` [RFC6960]
仕様は新たな例外の導入を避けるべきであり、慎重なセキュリティ検討の上でのみ追加するべきです。新しい例外の提案は issueの提出で行えます。
3.4. `Content-Length
` ヘッダー
`Content-Length
`ヘッダーは主にHTTPで定義されています。その処理モデルはHTTPで定義されたものがウェブコンテンツと互換性がないため、ここで定義されています。[HTTP]
長さを抽出するには、 ヘッダーリスト headersを与えて次の手順を実行する:
-
valuesを、headersから`
Content-Length
`を取得・デコード・分割した結果とする。 -
valuesがnullならnullを返す。
-
candidateValueをnullとする。
-
各 values の value について:
-
candidateValueがnullなら、candidateValueにvalueを設定する。
-
そうでなければ、valueがcandidateValueと異なれば、failureを返す。
-
-
candidateValueを10進数として解釈して返す。
3.5. `Content-Type
` ヘッダー
`Content-Type
`ヘッダーは主にHTTPで定義されています。その処理モデルはHTTPで定義されたものがウェブコンテンツと互換性がないため、ここで定義されています。[HTTP]
MIMEタイプを抽出するには、 ヘッダーリスト headersを与えて次の手順を実行する。これらはfailureまたはMIMEタイプを返す。
-
charsetをnullとする。
-
essenceをnullとする。
-
mimeTypeをnullとする。
-
valuesを、headersから`
Content-Type
`を取得・デコード・分割した結果とする。 -
valuesがnullならfailureを返す。
-
各 values の value について:
-
temporaryMimeTypeをvalueをMIMEタイプとして構文解析した結果とする。
-
mimeTypeにtemporaryMimeTypeを設定する。
-
mimeTypeのエッセンスがessenceと異なる場合:
-
charsetをnullに設定する。
-
mimeTypeのparameters["
charset
"]が存在すれば、charsetにその値を設定する。 -
essenceにmimeTypeのエッセンスを設定する。
-
-
そうでなければ、mimeTypeのparameters["
charset
"]が存在せず、かつcharsetがnullでなければ、mimeTypeのparameters["charset
"]にcharsetを設定する。
-
-
mimeTypeがnullならfailureを返す。
-
mimeTypeを返す。
MIMEタイプを抽出するがfailureを返した場合や、MIMEタイプのエッセンスが与えられたフォーマットに不適切な場合は、致命的エラーとして扱うこと。既存のウェブプラットフォーム機能はこのパターンに従っていないことが多く、長年にわたりセキュリティ脆弱性の主な原因となっています。一方で、MIMEタイプのパラメータは通常無視しても安全です。
MIMEタイプを抽出するの実際の動作例:
Headers(ネットワーク上の値) | 出力(直列化) |
---|---|
| text/html
|
| text/html;x=y;charset=gbk
|
| |
| text/html;x=y
|
| text/html
|
| |
|
レガシーエンコーディング抽出は、failureまたはMIMEタイプ mimeTypeとエンコーディング fallbackEncodingを与えて次の手順を実行する:
-
mimeTypeがfailureならfallbackEncodingを返す。
-
mimeType["
charset
"]が存在しなければ、fallbackEncodingを返す。 -
tentativeEncodingをmimeType["
charset
"]からエンコーディング取得した結果とする。 -
tentativeEncodingがfailureならfallbackEncodingを返す。
-
tentativeEncodingを返す。
このアルゴリズムはmimeTypeがfailureでも受け付けるため、MIMEタイプを抽出すると容易に組み合わせられます。
これが"legacy"とされるのは、現代のフォーマットはUTF-8のみ使うことが推奨されているためです。
3.6.
`X-Content-Type-Options
` ヘッダー
`X-Content-Type-Options
`
レスポンスヘッダーは、リクエストのdestinationに対して
レスポンスの`Content-Type
`ヘッダーのチェックを要求するために使用できます。
nosniffを判定するには、ヘッダーリスト listを与えて次の手順を実行する:
-
valuesをlistから`
X-Content-Type-Options
`を取得・デコード・分割した結果とする。 -
valuesがnullならfalseを返す。
-
values[0]が"
nosniff
"とASCII大文字・小文字を区別せず一致するならtrueを返す。 -
falseを返す。
ウェブ開発者および適合性チェッカーは、`X-Content-Type-Options
`の値に次のABNFを使わなければなりません:
X-Content-Type-Options = "nosniff" ; case-insensitive
3.6.1. responseをrequestへのレスポンスとしてnosniffのためにブロックすべきか?
次の手順を実行する:
-
responseのヘッダーリストに対してnosniffを判定するがfalseなら、allowedを返す。
-
mimeTypeをresponseのヘッダーリストからMIMEタイプを抽出するの結果とする。
-
destinationをrequestのdestinationとする。
-
destinationがスクリプト系で、mimeTypeがfailureまたはJavaScript MIMEタイプでなければ、blockedを返す。
-
destinationが"
style
"で、mimeTypeがfailureまたはそのエッセンスが"text/css
"でなければ、blockedを返す。 -
allowedを返す。
スクリプト系または"style
"のdestinationだけが考慮されます。なぜならそれらに関連する攻撃があるためです。また、"image
"は既存コンテンツとの互換性がありませんでした。
3.7.
`Cross-Origin-Resource-Policy
` ヘッダー
`Cross-Origin-Resource-Policy
`
レスポンスヘッダーは、リクエストの
現在のURLのオリジンを
リクエストのoriginと比較して確認するために使用できます。これはリクエストのmodeが"no-cors
"の時です。
Cross-Origin-Resource-Policy = %s"same-origin" / %s"same-site" / %s"cross-origin" ; case-sensitive
クロスオリジンリソースポリシーチェックを行うには、origin origin、環境設定オブジェクト settingsObject、文字列destination、response response、および省略可能なboolean forNavigationを与えて次の手順を実行する:
-
forNavigationが与えられていなければfalseとする。
-
クロスオリジンリソースポリシー内部チェックをorigin、"
unsafe-none
"、response、forNavigationで実行し、結果がblockedならblockedを返す。このステップは、Cross-Origin Embedder Policyに関連しない違反の報告を避けるために必要です。
-
クロスオリジンリソースポリシー内部チェックをorigin、embedderPolicyのレポート専用値、response、forNavigationで実行し、結果がblockedなら クロスオリジン埋め込み者ポリシーCORP違反レポートをキューするをresponse、settingsObject、destination、trueで実行する。
-
クロスオリジンリソースポリシー内部チェックをorigin、embedderPolicyの値、response、forNavigationで実行し、結果がallowedならallowedを返す。
-
クロスオリジン埋め込み者ポリシーCORP違反レポートをキューするをresponse、settingsObject、destination、falseで実行する。
-
blockedを返す。
HTMLのナビゲートアルゴリズムのみが、このチェックをforNavigationをtrueに設定して使用し、常にネストされたナビゲーションのために行われます。それ以外では、responseは内部レスポンスであり、不透明なフィルタリングされたレスポンスの内部レスポンスであるか、またはレスポンスであり、それが内部レスポンスである不透明なフィルタリングされたレスポンスとなります。[HTML]
クロスオリジンリソースポリシー内部チェックを行うには、 origin origin、埋め込み者ポリシー値 embedderPolicyValue、response response、boolean forNavigationを与えて次の手順を実行する:
-
forNavigationがtrueでembedderPolicyValueが"
unsafe-none
"ならallowedを返す。 -
policyをresponseのヘッダーリストから`
Cross-Origin-Resource-Policy
`を取得した結果とする。これは、`
Cross-Origin-Resource-Policy: same-site, same-origin
`のような場合は、embedderPolicyValueが"unsafe-none
"である限り、下で何にも一致しないのでallowedとなる、という意味です。`Cross-Origin-Resource-Policy
`ヘッダーが2つ以上あっても同様です。 -
policyが`
same-origin
`、`same-site
`、`cross-origin
`のいずれでもなければ、policyをnullとする。 -
policyがnullなら、embedderPolicyValueに応じて次を行う:
- "
unsafe-none
" -
何もしない。
- "
credentialless
" -
以下のいずれかが真ならpolicyを`
same-origin
`に設定する:- responseのrequest-includes-credentialsがtrue
- forNavigationがtrue
- "
require-corp
" -
policyを`
same-origin
`に設定する。
- "
-
policyに応じて次を行う:
- null
- `
cross-origin
` - `
-
allowedを返す。
- `
same-origin
` -
originがresponseのURLのoriginと同一オリジンならallowedを返す。
そうでなければblockedを返す。
- `
same-site
` -
以下がすべて真なら
このときallowedを返す。
そうでなければblockedを返す。
`
Cross-Origin-Resource-Policy: same-site
`は、セキュアな伝送で配信されたレスポンスが、たとえホストが同一サイトでも非セキュアなリクエスト元とは一致しないことに注意。セキュアなレスポンスはセキュアなイニシエータとだけ一致する。
- null
クロスオリジン埋め込み者ポリシーCORP違反レポートをキューするには、 response response、環境設定オブジェクト settingsObject、文字列destination、boolean reportOnlyを与えて次の手順を実行する:
-
endpointをsettingsObjectのポリシーコンテナの埋め込み者ポリシーのreport only reporting endpoint(reportOnlyがtrueかつ settingsObjectのポリシーコンテナの埋め込み者ポリシーの時)、それ以外はreporting endpointとする。
-
serializedURLをresponseでreporting用レスポンスURLの直列化した結果とする。
-
dispositionをreportOnlyがtrueなら"
reporting
"、そうでなければ"enforce
"とする。 -
bodyを次のプロパティを持つ新しいオブジェクトとする:
key value " type
"" corp
"" blockedURL
"serializedURL " destination
"destination " disposition
"disposition -
レポートの生成とキューを、settingsObjectのグローバルオブジェクト、"
coep
"レポートタイプ、endpoint、bodyで実行する。[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]
-
アサート:requestのmodeが"
navigate
"であるか、processEarlyHintsResponseがnullである。 -
taskDestinationをnullとする。
-
crossOriginIsolatedCapabilityをfalseとする。
-
クライアントからリクエストを埋め込む、requestを指定して実行。
-
requestのclientがnullでなければ:
-
taskDestinationにrequestのclientのグローバルオブジェクトを設定する。
-
crossOriginIsolatedCapabilityにrequestのclientのクロスオリジン分離機能を設定する。
-
-
useParallelQueueがtrueであれば、taskDestinationに新しい並列キューの開始の結果を設定する。
-
timingInfoを新しいフェッチタイミング情報として生成し、その開始時刻とリダイレクト後開始時刻を粗化された共有現在時刻(crossOriginIsolatedCapabilityを指定)で設定し、レンダーブロッキングはrequestのレンダーブロッキングで設定する。
-
fetchParamsを新しいフェッチパラメータとして生成し、requestにrequest、timing infoにtimingInfo、process request body chunk lengthにprocessRequestBodyChunkLength、process request end-of-bodyにprocessRequestEndOfBody、process early hints responseにprocessEarlyHintsResponse、process responseにprocessResponse、process response consume bodyにprocessResponseConsumeBody、process response end-of-bodyにprocessResponseEndOfBody、task destinationにtaskDestination、cross-origin isolated capabilityにcrossOriginIsolatedCapabilityを設定する。
-
以下すべての条件を満たす場合:
-
requestのURLのスキームがHTTP(S)スキーム
-
requestのmodeが"
same-origin
"、"cors
"、または"no-cors
" -
requestのclientがnullでなく、requestのclientのグローバルオブジェクトが
Window
オブジェクトである -
requestのmethodが `
GET
` -
requestのunsafe-request flagがセットされていない、またはrequestのheader listが空である
この場合:
-
onPreloadedResponseAvailableに、レスポンスresponseを受け取ったとき、fetchParamsのpreloaded response candidateをresponseに設定するアルゴリズムを割り当てる。
-
foundPreloadedResourceに、プリロード済みリソースを消費するをrequestのclient、requestのURL、requestのdestination、requestのmode、requestのcredentials mode、requestのintegrity metadata、およびonPreloadedResponseAvailableを指定して呼び出した結果を設定する。
-
foundPreloadedResourceがtrueであり、かつfetchParamsのpreloaded response candidateがnullであれば、fetchParamsのpreloaded response candidateを"
pending
"に設定する。
-
-
requestのheader listが`Accept`を含まない場合:
-
valueを `
*/*
` にする。 -
requestのinitiatorが"
prefetch
"であれば、valueをドキュメント`Accept
`ヘッダー値に設定する。 -
それ以外の場合、ユーザーエージェントはrequestのdestinationに応じて、下記の最初に一致する項目で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
`
- "
-
-
もし request の ヘッダーリスト が `Accept-Language` を含まない場合、ユーザーエージェントは 追加(`
Accept-Language
`, 適切な ヘッダー値)を request の ヘッダーリストに追加するべきです。 -
requestの内部優先度がnullであれば、requestのpriority、initiator、destination、およびレンダーブロッキングを用いて、実装定義の方法でrequestの内部優先度に実装定義のオブジェクトを設定する。
実装定義のオブジェクトは、HTTP/2のストリーム重みや依存性、HTTP/3などのトランスポートで利用されるExtensible Prioritization Scheme for HTTPの優先度、またはHTTP/1フェッチのディスパッチ・処理の優先度などを含む場合があります。[RFC9218]
-
requestがサブリソースリクエストであれば:
-
recordを新しいフェッチレコードとして生成し、requestにrequest、controllerにfetchParamsのcontrollerを設定する。
-
-
メインフェッチをfetchParamsで実行する。
-
fetchParamsのcontrollerを返す。
クライアントからリクエストを埋め込むには、リクエストrequestを指定して以下を実行します:
-
requestのユーザープロンプト用トラバーサブルが"
client
"であれば:-
requestのユーザープロンプト用トラバーサブルを"
no-traversable
"に設定する。 -
requestのclientがnullでなければ:
-
globalにrequestのclientのグローバルオブジェクトを設定する。
-
globalが
Window
オブジェクトであり、かつglobalのnavigableがnullでなければ、requestのユーザープロンプト用トラバーサブルをglobalのnavigableのtraversable navigableで設定する。
-
-
-
requestのoriginが"
client
"であれば: -
requestのポリシーコンテナが"
client
"であれば:-
requestのclientがnullでなければ、requestのpolicy containerをrequestのclientのポリシーコンテナの複製に設定する。[HTML]
-
それ以外の場合、requestのpolicy containerを新しいポリシーコンテナに設定する。
-
4.1. メインフェッチ
メインフェッチするには、フェッチパラメータfetchParamsとオプションのブール値recursive(デフォルトはfalse)を指定して、以下の手順を実行します:
-
requestにfetchParamsのrequestを設定する。
-
responseをnullとする。
-
requestのlocal-URLs-only flagがセットされていて、かつrequestのcurrent URLがローカルでなければ、responseにネットワークエラーを設定する。
-
悪いポートのためrequestをブロックすべきか、 混在コンテンツとしてrequestのフェッチをブロックすべきか、 Content Security Policyによりrequestをブロックすべきか、 整合性ポリシーによりrequestをブロックすべきか がblockedを返した場合、responseにネットワークエラーを設定する。
-
requestのreferrer policyが空文字列であれば、requestのreferrer policyをrequestのpolicy containerのreferrer policyに設定する。
-
requestのreferrerが"
no-referrer
"でなければ、requestのreferrerをリクエストのreferrerを決定するの結果に設定する。[REFERRER]Referrer Policyに記載されている通り、ユーザーエージェントはエンドユーザーに"
no-referrer
"に上書きする、またはより機微な情報のみを公開するオプションを提供できます。 -
以下すべての条件を満たす場合、requestのcurrent URLのschemeを"
https
"に設定する:- requestのcurrent URLのschemeが"
http
" - requestのcurrent URLのhostがドメインである
- requestのcurrent URLのhostのpublic
suffixが"
localhost
"または"localhost.
"ではない - requestのcurrent URLのhostをKnown HSTS Host Domain
Name
Matchingで照合した結果、
includeSubDomains
指令付きのスーパー領域一致または一致(includeSubDomains
指令の有無問わず)が得られる、もしくはDNS解決でリクエストがsection 9.5のHTTPS RRと一致する場合。[HSTS] [SVCB]
すべてのDNS操作は通常実装定義であるため、DNS解決にHTTPS RRが含まれているかどうかの判定も実装定義です。DNS操作は伝統的にコネクション取得の試行まで行われないため、ユーザーエージェントはDNS操作を早期に実施したり、ローカルDNSキャッシュを参照したり、フェッチアルゴリズムの後段で判明した場合に論理を巻き戻す必要があるかもしれません。
- requestのcurrent URLのschemeが"
-
recursiveがfalseであれば、残りの手順を並列で実行する。
-
responseがnullであれば、最初に一致する条件の手順を実行してresponseを設定する:
- fetchParamsのpreloaded response candidateがnullでない
-
-
fetchParamsのpreloaded response candidateが"
pending
"でなくなるまで待つ。 -
アサート:fetchParamsのpreloaded response candidateがレスポンスである。
-
fetchParamsのpreloaded response candidateを返す。
-
- requestのcurrent URLのoriginがrequestのoriginと同一オリジンで、かつrequestのresponse
taintingが"
basic
"である- requestのcurrent URLのschemeが"
data
"である- requestのmodeが"
navigate
"または"websocket
"である - requestのcurrent URLのschemeが"
-
-
requestのresponse taintingを"
basic
"に設定する。 -
「
scheme-fetch
」と fetchParams を指定して、override fetch を実行した結果を返す。
HTMLは、URLのschemeが"
data
"のものから作成されるドキュメントやワーカーに一意の不透明オリジンを割り当てます。Service WorkerはURLのschemeがHTTP(S)スキームのもののみから作成可能です。[HTML] [SW] -
- requestのmodeが"
same-origin
"である -
ネットワークエラーを返す。
- requestのmodeが"
no-cors
"である -
-
requestのredirect modeが"
follow
"でなければネットワークエラーを返す。 -
requestのresponse taintingを"
opaque
"に設定する。 -
「
scheme-fetch
」と fetchParams を指定して、override fetch を実行した結果を返す。
-
- requestのcurrent URLのschemeがHTTP(S)スキームでない
-
ネットワークエラーを返す。
- requestのuse-CORS-preflight flagがセットされている
- requestのunsafe-request flagがセットされていて、かつrequestのmethodがCORS安全リストメソッドでない、またはCORS安全でないリクエストヘッダー名がrequestのheader listで空でない
-
-
requestのresponse taintingを"
cors
"に設定する。 -
corsWithPreflightResponse を、「
http-fetch
」、fetchParams、および true を指定して override fetch を実行した結果とする。 -
corsWithPreflightResponseがネットワークエラーであれば、キャッシュエントリをクリアをrequestで実行する。
-
corsWithPreflightResponseを返す。
-
- その他
-
-
requestのresponse taintingを"
cors
"に設定する。 -
「
http-fetch
」と fetchParams を指定して、override fetch を実行した結果を返す。
-
-
recursiveがtrueであれば、responseを返す。
-
responseがネットワークエラーでなく、かつresponseがフィルタ済みレスポンスでなければ、以下を実行する:
-
requestのresponse taintingが"
cors
"であれば、以下を実行する:-
headerNamesにヘッダーリスト値の抽出を`
Access-Control-Expose-Headers
`とresponseのheader listで実行した結果を設定する。 -
requestのcredentials modeが"
include
"でなく、かつheaderNamesが`*
`を含んでいれば、responseのCORS公開ヘッダー名リストにresponseのheader listに含まれるすべての一意なヘッダー名を設定する。 -
それ以外でheaderNamesがnullまたは失敗でなければ、responseのCORS公開ヘッダー名リストにheaderNamesを設定する。
-
-
以下に応じてresponseをresponseを内部レスポンスとするフィルタ済みレスポンスに設定する:
- "
basic
" - 基本フィルタ済みレスポンス
- "
cors
" - CORSフィルタ済みレスポンス
- "
opaque
" - 不透明フィルタ済みレスポンス
- "
-
-
internalResponseにresponseを設定する。ただしresponseがネットワークエラーならresponse、それ以外ならresponseの内部レスポンスを設定する。
-
internalResponseのリダイレクト汚染にrequestのredirect-taintを設定する。
-
requestのtiming allow failed flagが未設定なら、internalResponseのtiming allow passed flagを設定する。
-
responseがネットワークエラーでなく、かつ下記のどれかがblockedを返す場合
この場合responseとinternalResponseをネットワークエラーに設定する。
-
responseのtypeが"
opaque
"で、internalResponseのstatusが206で、internalResponseのrange-requested flagがセットされていて、かつrequestのheader listが`Range`を含まない場合、responseとinternalResponseをネットワークエラーに設定する。従来、APIは範囲指定がなくても範囲レスポンスを受け入れます。これは、以前の範囲リクエストからの部分レスポンスがAPIに提供されることを防ぎます。
詳細
上記の手順は以下の攻撃を防ぎます:
メディア要素でクロスオリジンHTMLリソースの範囲をリクエストします(これは無効なメディア)。ただしレスポンスのクローン参照をService Workerに保持できます。後でこの部分レスポンスをscript要素のfetchレスポンスとして利用できます。もし部分レスポンスが有効なJavaScriptなら(リソース全体はそうでなくても)、実行するとプライベートデータが漏洩します。
-
responseがネットワークエラーでなく、かつrequestのmethodが`
HEAD
`または`CONNECT
`である、またはinternalResponseのstatusがnullボディステータスであれば、internalResponseのbodyをnullに設定し、以降のエンキューは無視する。この処理はHTTP違反サーバへのエラー処理の標準化です。
-
requestのintegrity metadataが空文字列でなければ、以下を実行する:
-
processBodyErrorにこの手順:fetch response handoverをfetchParamsとネットワークエラーで実行する。
-
responseのbodyがnullならprocessBodyErrorを実行し、以降の手順を中止する。
-
processBodyにbytesを受け取った場合の手順を設定する:
-
bytesが一致しない場合、requestのintegrity metadataに、processBodyErrorを実行し以降の手順を中止する。[SRI]
-
fetch response handoverをfetchParamsとresponseで実行する。
-
-
-
それ以外の場合、fetch response handoverをfetchParamsとresponseで実行する。
フェッチレスポンス引き渡しは、フェッチパラメータfetchParamsとレスポンスresponseを指定して、以下の手順を実行します:
-
timingInfoにfetchParamsのタイミング情報を設定する。
-
responseがネットワークエラーでなく、かつfetchParamsのrequestのclientがセキュアコンテキストなら、timingInfoのserver-timing headersにresponseの内部レスポンスのヘッダーリストから`
Server-Timing
`を取得・デコード・分割した結果を設定する。responseの内部レスポンスを用いるのは安全です。`
Server-Timing
`ヘッダー情報の公開は`Timing-Allow-Origin
`ヘッダーによって制御されます。ユーザーエージェントは非セキュアコンテキストのリクエストにも`
Server-Timing
`ヘッダーを公開する場合があります。 -
fetchParamsのrequestのdestinationが"
document
"であれば、fetchParamsのcontrollerのfull timing infoにfetchParamsのタイミング情報を設定する。 -
processResponseEndOfBodyに以下の手順を設定する:
-
unsafeEndTimeにunsafe shared current timeを設定する。
-
fetchParamsのcontrollerのreport timing stepsに、グローバルオブジェクトglobalを受け取る手順として以下を設定する:
-
fetchParamsのrequestのURLのschemeがHTTP(S)スキームでなければreturnする。
-
timingInfoのend timeにrelative high resolution time(unsafeEndTime, globalを指定)で設定する。
-
cacheStateにresponseのcache stateを設定する。
-
bodyInfoにresponseのbody infoを設定する。
-
responseのtiming allow passed flagが未設定なら、timingInfoに不透明タイミング情報の作成(timingInfoを指定)の結果を設定し、cacheStateを空文字列に設定する。
これはresponseがネットワークエラーの場合を含みます。
-
responseStatusを0に設定する。
-
fetchParamsのrequestのmodeが"
navigate
"でない、またはresponseのredirect taintが"same-origin
"であれば:-
responseStatusにresponseのstatusを設定する。
-
mimeTypeにMIMEタイプの抽出(responseのheader listを指定)の結果を設定する。
-
mimeTypeが失敗でなければ、bodyInfoのcontent typeにサポートされているMIMEタイプの最小化(mimeType)の結果を設定する。
-
-
fetchParamsのrequestのinitiator typeがnullでなければ、mark resource timing(timingInfo, fetchParamsのrequestのURL, fetchParamsのrequestのinitiator type, global, cacheState, bodyInfo, responseStatus)を実行する。
-
-
processResponseEndOfBodyTaskに以下の手順を設定する:
-
fetchParamsのprocess response end-of-bodyがnullでなければ、fetchParamsのprocess response end-of-body(response)を実行する。
-
fetchParamsのrequestのinitiator typeがnullでなく、かつfetchParamsのrequestのclientのグローバルオブジェクトがfetchParamsのtask destinationであれば、fetchParamsのcontrollerのreport timing steps(fetchParamsのrequestのclientのグローバルオブジェクト)を実行する。
-
フェッチタスクをキューし、processResponseEndOfBodyTaskをfetchParamsのtask destinationで実行する。
-
-
fetchParamsのprocess responseがnullでなければ、フェッチタスクをキューし、fetchParamsのprocess response(response)をfetchParamsのtask destinationで実行する。
-
internalResponseにresponseを設定する。ただしresponseがネットワークエラーならresponse、それ以外ならresponseの内部レスポンスを設定する。
-
internalResponseのbodyがnullなら、processResponseEndOfBodyを実行する。
-
それ以外の場合:
-
transformStreamに新しい
TransformStream
を設定する。 -
identityTransformAlgorithmに、chunkを受け取ったときtransformStreamにchunkをenqueueするアルゴリズムを設定する。
-
transformStreamのセットアップを行い、transformAlgorithmをidentityTransformAlgorithmに、flushAlgorithmをprocessResponseEndOfBodyに設定する。
-
internalResponseのbodyのstreamに、internalResponseのbodyのstreamをpipe throughした結果をtransformStreamで設定する。
この
TransformStream
は、ストリームの終端到達時の通知目的で必要です。それ以外は恒等変換ストリームです。 -
-
fetchParamsのprocess response consume bodyがnullでなければ、以下を実行する:
-
processBodyにnullOrBytesを受け取ったときfetchParamsのprocess response consume body(response, nullOrBytes)を実行する手順を設定する。
-
processBodyErrorにfetchParamsのprocess response consume body(response, failure)を実行する手順を設定する。
-
internalResponseのbodyがnullなら、フェッチタスクをキューし、processBody(null)をfetchParamsのtask destinationで実行する。
-
それ以外の場合、完全に読み取るをinternalResponseのbodyに対してprocessBody, processBodyError, fetchParamsのtask destinationで実行する。
-
4.2. オーバーライドフェッチ
オーバーライドフェッチは、「scheme-fetch
」または「http-fetch
」の
type、fetch params
fetchParams、さらにオプションの boolean makeCORSPreflight(デフォルトは false)を受け取る:
-
request を fetchParams の request とする。
-
response を request に対して 要求のオーバーライド可能なレスポンス を実行した結果とする。
-
response が null でなければ、response を返す。
-
type に応じて以下を実行する:
-
response を返す。
要求のオーバーライド可能なレスポンスアルゴリズムは、request request を受け取り、response または null を返す。その動作は 実装定義であり、ユーザーエージェントが request に直接レスポンスを返すか、null を返してリクエストを続行することができる。
デフォルトでは、アルゴリズムは以下の簡易的な実装となる:
-
null を返す。
ユーザーエージェントは一般的に、このデフォルト実装をより複雑な動作で上書きする。例えば、ユーザーエージェントは利用者の安全を守るために「https://unsafe.example/」へのリクエストを一般的にブロックしつつ、広く利用されている「https://unsafe.example/widget.js」向けのリソースには互換性を保つためのシムを合成するかもしれない。その実装例は次のようになる:
4.3. スキームフェッチ
スキームフェッチは、fetch params fetchParams を受け取る:
-
fetchParams が キャンセル済みの場合、fetchParamsに対して 適切なネットワークエラー を返す。
-
request を fetchParams の request とする。
-
request の current URL の scheme に応じて以下の手順を実行する:
- "
about
" -
request の current URL の path が "
blank
" の場合、response を新規作成し、 status message を `OK
`、 header list を « (`Content-Type
`, `text/html;charset=utf-8
`) »、 body を空のバイト列 本文として設定して返す。URL(例:"about:config")は ナビゲーション時に処理され、 fetchの文脈では ネットワークエラー となる。
- "
blob
" -
-
blobURLEntry を request の current URL の blob URL entry とする。
-
request の method が `
GET
` でないか、blobURLEntry が null の場合は、ネットワークエラー を返す。 [FILEAPI]`
GET
` method の制限は相互運用性以外に意味はない。 -
requestEnvironment を request に対して 環境決定を実行した結果とする。
-
isTopLevelNavigation を request の destination が "
document
" なら true、そうでなければ false とする。 -
isTopLevelNavigation が false かつ requestEnvironment が null の場合、ネットワークエラー を返す。
-
navigationOrEnvironment を isTopLevelNavigation が true なら "
navigation
"、そうでなければ requestEnvironment とする。 -
blob を Blob オブジェクト取得を blobURLEntry と navigationOrEnvironment で実行した結果とする。
-
response を新しい response とする。
-
fullLength を blob の
size
とする。 -
type を blob の
type
とする。 -
request の header list に `
Range
` が含まれていない場合:-
bodyWithType を 安全抽出で blob から取得した結果とする。
-
response の status message を `
OK
` に設定する。 -
response の header list を « (`
Content-Length
`, serializedFullLength), (`Content-Type
`, type) » に設定する。
-
-
それ以外の場合:
-
response の range-requested flag を設定する。
-
rangeHeader を request の header list から `
Range
` を取得した結果とする。 -
rangeValue を 単一レンジヘッダー値のパースを rangeHeader と true で実行した結果とする。
-
rangeValue が失敗なら、ネットワークエラー を返す。
-
(rangeStart, rangeEnd) を rangeValue とする。
-
rangeStart が null の場合:
-
rangeStart を fullLength − rangeEnd に設定する。
-
rangeEnd を rangeStart + rangeEnd − 1 に設定する。
-
-
それ以外の場合:
-
rangeStart が fullLength 以上の場合、ネットワークエラー を返す。
-
rangeEnd が null または fullLength 以上の場合、rangeEnd を fullLength − 1 に設定する。
-
-
slicedBlob を スライス blob を blob、rangeStart、rangeEnd + 1、type で呼び出した結果とする。
Rangeヘッダーはバイト範囲を包含的に示すが、slice blob アルゴリズムの入力範囲はそうではない。そのため、slice blob アルゴリズムを使うには rangeEnd をインクリメントする必要がある。
-
slicedBodyWithType を 安全抽出で slicedBlob から取得した結果とする。
-
serializedSlicedLength を slicedBlob の
size
を シリアライズし、等形エンコードしたものとする。 -
contentRange を content range 構築 を rangeStart、rangeEnd、fullLength で呼び出した結果とする。
-
response の status を 206 に設定する。
-
response の status message を `
Partial Content
` に設定する。 -
response の header list を « (`
Content-Length
`, serializedSlicedLength), (`Content-Type
`, type), (`Content-Range
`, contentRange) » に設定する。
-
-
response を返す。
-
- "
data
" -
-
dataURLStruct を request の current URL に対して
data:
URLプロセッサ を実行した結果とする。 -
dataURLStruct が失敗なら、ネットワークエラー を返す。
-
新しい response を作成し、 status message を `
OK
`、 header list を « (`Content-Type
`, mimeType) »、 body を dataURLStruct の body 本文として設定して返す。
-
- "
file
" -
現時点では残念ながら、
file:
URL の処理は読者への課題として残されている。不明な場合は、ネットワークエラー を返す。
- HTTP(S) scheme
-
HTTPフェッチ を fetchParams で実行した結果を返す。
- "
-
ネットワークエラー を返す。
環境を決定するためには、request request を受け取る:
-
request の reserved client が null でなければ、 request の reserved client を返す。
-
null を返す。
4.4. HTTPフェッチ
HTTPフェッチは、 fetch params fetchParams と、オプションの boolean makeCORSPreflight(デフォルトは false)を受け取り、以下の手順を実行する:
-
request を fetchParams の request とする。
-
response と internalResponse を null とする。
-
request の service-workers mode が "
all
" の場合:-
requestForServiceWorker を clone で request を複製したものとする。
-
requestForServiceWorker の body が null でなければ:
-
transformStream を新しい
TransformStream
とする。 -
transformAlgorithm を chunk を受け取るアルゴリズムとして以下とする:
-
fetchParams が キャンセル済みなら、これらの手順を中止する。
-
chunk が
Uint8Array
オブジェクトでなければ、 terminate で fetchParams の controller を終了する。 -
それ以外の場合、enqueue で chunk を transformStream に追加する。ユーザーエージェントは、チャンクを 実装定義の適切なサイズに分割して enqueue してもよいし、チャンク群を 実装定義の適切なサイズに連結して enqueue してもよい。
-
-
transformStream を transformAlgorithm にセットアップする。
-
requestForServiceWorker の body の stream を requestForServiceWorker の body の stream を pipe through transformStream した結果に設定する。
-
-
serviceWorkerStartTime を coarsened shared current time を fetchParams の cross-origin isolated capability で実行した結果とする。
-
response を handle fetch で requestForServiceWorker、fetchParams の controller、fetchParams の cross-origin isolated capability を渡して呼び出した結果とする。 [HTML] [SW]
-
response が null でなければ:
-
fetchParams の timing info の final service worker start time を serviceWorkerStartTime に設定する。
-
request の body が null でなければ cancel で request の body を undefined でキャンセルする。
-
internalResponse を response が filtered response でなければ response に、そうでなければ response の internal response に設定する。
-
以下のいずれかが真の場合:
-
response の type が "
error
" -
request の redirect mode が "
manual
" でなく response の type が "opaqueredirect
" -
request の redirect mode が "
follow
" でなく response の URL list に複数の項目がある場合
この場合、ネットワークエラー を返す。
-
-
-
-
response が null の場合:
-
makeCORSPreflight が true かつ以下のいずれかが真の場合:
-
method cache entry match が request の method で存在せず、かつ request の method が CORS-safelisted method でないか、 request の use-CORS-preflight flag が設定されている場合
-
item が CORS-unsafe request-header names に存在し、 request の header list に該当し、 header-name cache entry match が request に対して存在しない場合
この場合:
-
preflightResponse を CORSプリフライトフェッチ を request で実行した結果とする。
-
preflightResponse が ネットワークエラーの場合、 preflightResponse を返す。
この手順は CORSプリフライトキャッシュ を確認し、 適切なエントリがなければ CORSプリフライトフェッチ を行い、成功すればキャッシュに登録する。 CORSプリフライトフェッチ の目的は 取得されるリソースが CORSプロトコルに対応していることを保証することである。 キャッシュは CORSプリフライトフェッチ の回数を減らすためにある。
-
-
request の redirect mode が "
follow
" の場合、 request の service-workers mode を "none
" に設定する。ネットワーク由来のリダイレクト(サービスワーカー由来でない場合)はサービスワーカーに公開しない。
-
response と internalResponse を HTTPネットワークまたはキャッシュフェッチ を fetchParams で実行した結果に設定する。
-
request の response tainting が "
cors
" かつ CORSチェック を request と response で実行した結果が失敗の場合、 ネットワークエラー を返す。CORSチェックは response の status が 304 または 407、 またはサービスワーカー由来のレスポンスには適用されないため、ここで適用する。
-
TAOチェック を request と response で実行した結果が失敗なら、 request の timing allow failed flag を設定する。
-
-
request の response tainting または response の type が "
opaque
" かつ クロスオリジンリソースポリシーチェック を request の origin、 request の client、request の destination、internalResponse で実行した結果が blocked の場合、 ネットワークエラー を返す。クロスオリジンリソースポリシーチェックは ネットワークやサービスワーカー由来のレスポンスに対しても行われる。 CORSチェックとは異なり、 request の client とサービスワーカー間で 別々の埋め込みポリシーを持つ場合がある。
-
internalResponse の status が リダイレクトステータスの場合:
-
internalResponse の status が 303 でなく request の body が null でなく connection が HTTP/2 を利用している場合、 ユーザーエージェントは
RST_STREAM
フレームを送信してもよい(推奨)。303 は特定コミュニティで特別視されるため除外されている。
-
request の redirect mode に応じて:
- "
error
" -
-
response を ネットワークエラー に設定する。
-
- "
manual
" -
-
request の mode が "
navigate
" の場合、 fetchParams の controller の next manual redirect steps に HTTPリダイレクトフェッチ を fetchParams と response で実行する手順を設定する。 -
それ以外の場合、 response を opaque-redirect filtered response に設定し、 その internal response を internalResponse にする。
-
- "
follow
" -
-
response を HTTPリダイレクトフェッチ を fetchParams と response で実行した結果に設定する。
-
- "
-
-
response を返す。通常、internalResponse の body の stream は この返却後もエンキューされ続けている。
4.5. HTTP リダイレクト フェッチ
HTTP-redirect fetchを、fetch params fetchParams と response response を与えて実行するには、次の手順を行う:
-
request を fetchParams の request とする。
-
internalResponse を、response が filtered response でないなら response、そうでなければ response の internal response とする。
-
locationURL を、internalResponse の location URL とし、 request の current URL の fragment を考慮する。
-
locationURL が null なら、response を返す。
-
locationURL が failure なら、network error を返す。
-
locationURL の scheme が HTTP(S) scheme でなければ、network error を返す。
-
request の redirect count が 20 の場合、network error を返す。
-
request の redirect count を 1 増やす。
-
もし request の mode が "
cors
" で、 locationURL が include credentials を満たし、かつ request の origin が locationURL の origin と same origin でない場合、network error を返す。 -
もし request の response tainting が "
cors
" で、 locationURL が include credentials を満たす場合、network error を返す。これはクロスオリジンのリソースが同一オリジンの URL へリダイレクトする場合を捕捉する。
-
もし internalResponse の status が 303 でなく、request の body が non-null で、かつその source が null なら、network error を返す。
-
もし次のいずれかが真なら:
-
internalResponse の status が 301 または 302 で、かつ request の method が `
POST
` である -
internalResponse の status が 303 で、かつ request の method が `
GET
` または `HEAD
` でない
その場合:
-
For each headerName of request-body-header name、delete headerName を request の header list から削除する。
-
-
もし request の current URL の origin が locationURL の origin と same origin でない場合、for each headerName of CORS non-wildcard request-header name、 delete headerName を request の header list から削除する。
つまり、初回のリクエスト後に別のオリジンが現れた瞬間に `
Authorization
` ヘッダーが削除される。 -
もし request の body が non-null なら、request の body を、safely extracting による結果の body に設定する。
-
timingInfo を fetchParams の timing info とする。
-
timingInfo の redirect end time と post-redirect start time を、 fetchParams の cross-origin isolated capability を指定して得られる coarsened shared current time に設定する。
-
もし timingInfo の redirect start time が 0 なら、 timingInfo の redirect start time を timingInfo の start time に設定する。
-
set request’s referrer policy on redirect を request と internalResponse に対して呼び出す。[REFERRER]
-
recursive を true にする。
-
もし request の redirect mode が "
manual
" なら: -
fetchParams と recursive を与えて main fetch を実行した結果を返す。
これは main fetch を呼び出して request の response tainting を正しく得る必要があるためである。
4.6. HTTP ネットワークまたはキャッシュ フェッチ
HTTP-network-or-cache fetchを、fetch params fetchParams、オプションの boolean isAuthenticationFetch(デフォルト false)、およびオプションの boolean isNewConnectionFetch(デフォルト false)を与えて実行するには、次の手順を実行する:
一部の実装は部分コンテンツのキャッシュをサポートするかもしれない(HTTP Caching に従う)。しかし、これはブラウザのキャッシュで広くサポートされているわけではない。[HTTP-CACHING]
-
request を fetchParams の request とする。
-
httpFetchParams を null とする。
-
httpRequest を null とする。
-
response を null とする。
-
storedResponse を null とする。
-
httpCache を null とする。
-
revalidatingFlag を unset にする。
-
次の手順を実行する。ただし abort when fetchParams が canceled の場合は中止する:
-
もし request の traversable for user prompts が "
no-traversable
" でかつ request の redirect mode が "error
" なら、httpFetchParams を fetchParams に、httpRequest を request に設定する。 -
それ以外の場合:
-
httpRequest を request の clone に設定する。
実装は、request の body の stream を tee することを避けることが推奨される。なぜならその場合単一の body しか必要でないからである。例えば request の source が null のとき、リダイレクトや認証は結果的にフェッチに失敗する。
-
httpFetchParams を fetchParams のコピーに設定する。
-
httpFetchParams の request を httpRequest に設定する。
ユーザーへのプロンプトやリダイレクトが可能な場合、ユーザー応答後に新しいヘッダセットでリクエストを再送する必要があるかもしれない。その時点で元のリクエストボディは既に部分的に送信されている可能性があるため、予備のコピーを用意するために事前にリクエスト(ボディを含む)をクローンする必要がある。
-
-
includeCredentials を以下のいずれかが真なら true にする:
- request の credentials mode が
"
include
" - request の credentials mode が
"
same-origin
" で、かつ request の response tainting が "basic
"
それ以外は false とする。
- request の credentials mode が
"
-
Cross-Origin-Embedder-Policy allows credentials を request に対して評価して false なら、includeCredentials を false に設定する。
-
contentLength を、もし httpRequest の body が non-null ならその length に設定し、そうでなければ null とする。
-
contentLengthHeaderValue を null にする。
-
もし httpRequest の body が null で、かつ httpRequest の method が `
POST
` または `PUT
` なら、contentLengthHeaderValue を `0
` に設定する。 -
もし contentLength が non-null なら、contentLengthHeaderValue を contentLength の serialized かつ isomorphic encoded な値に設定する。
-
もし contentLengthHeaderValue が non-null なら、append (`
Content-Length
`, contentLengthHeaderValue) を httpRequest の header list に追加する。 -
もし contentLength が non-null でかつ httpRequest の keepalive が true なら:
-
inflightKeepaliveBytes を 0 にする。
-
group を httpRequest の client の fetch group に設定する。
-
inflightRecords を group 内の fetch records の集合として定義する。これらは各 fetchRecord の request の keepalive が true であり、かつ done flag が unset であるものとする。
-
For each fetchRecord of inflightRecords:
-
もし contentLength と inflightKeepaliveBytes の和が 64 KiB を超えるなら、network error を返す。
上記の制限は、環境設定オブジェクトを超えて存続することが許可されており、かつボディを含むリクエストが、サイズに上限があり、無期限に存続することができないようにするためのものです。
-
-
もし httpRequest の referrer が URL なら:
-
referrerValue を httpRequest の referrer の serialized かつ isomorphic encoded な値とする。
-
Append (`
Referer
`, referrerValue) を httpRequest の header list に追加する。
-
-
Append a request `
Origin
` header を httpRequest に対して実行する。 -
Append the Fetch metadata headers for httpRequest を実行する。[FETCH-METADATA]
-
もし httpRequest の initiator が "
prefetch
" なら、set a structured field value を呼び出し、(`Sec-Purpose
`, tokenprefetch
) を httpRequest の header list に設定する。 -
もしhttpRequestのヘッダーリストが、`
User-Agent
` を含まない場合、ユーザーエージェントは次を行うべきである:-
userAgent を、httpRequestのクライアントの 環境のデフォルト `
User-Agent
` 値として取得する。
-
-
もし httpRequest の cache mode が "
default
" で、かつ httpRequest の header list が `If-Modified-Since
`, `If-None-Match
`, `If-Unmodified-Since
`, `If-Match
`, または `If-Range
` のいずれかを含むなら、httpRequest の cache mode を "no-store
" に設定する。 -
もし httpRequest の cache mode が "
no-cache
" で、かつ httpRequest の prevent no-cache cache-control header modification flag が unset で、httpRequest の header list が `Cache-Control
` を含まないなら、append (`Cache-Control
`, `max-age=0
`) を httpRequest の header list に追加する。 -
もし httpRequest の cache mode が "
no-store
" または "reload
" なら:-
もし httpRequest の header list が `
Pragma
` を含まないなら、append (`Pragma
`, `no-cache
`) を追加する。 -
もし httpRequest の header list が `
Cache-Control
` を含まないなら、append (`Cache-Control
`, `no-cache
`) を追加する。
-
-
もし httpRequest の header list が `
Range
` を含むなら、append (`Accept-Encoding
`, `identity
`) を httpRequest の header list に追加する。これは、エンコードされたレスポンスの一部を扱う際に content codings を扱う ときの失敗を回避するためである。
さらに、多くのサーバー は `
Range
` ヘッダーを誤って無視することがある。 -
HTTP に従って httpRequest の header list を修正する。もし既に同名のヘッダーが存在する場合は同じヘッダー名を追加してはならない。
これをもっと規範的にできれば良い。現状では `
Accept-Encoding
`, `Connection
`, `DNT
`, `Host
` のようなヘッダーは必要に応じて追加されるべきである。`
Accept
`, `Accept-Charset
`, `Accept-Language
` はこの時点で含めてはならない。`
Accept
` と `Accept-Language
` は既に含まれている(ただしfetch()
を用いる場合は後者はデフォルトで含まれない)。`Accept-Charset
` はバイトの無駄である。詳細は HTTP header layer division を参照のこと。 -
もし includeCredentials が true なら:
-
Append a request `
Cookie
` header を httpRequest に対して実行する。 -
もし httpRequest の header list が `
Authorization
` を含まないなら:-
authorizationValue を null にする。
-
もし httpRequest に対する authentication entry が存在し、かつ httpRequest の use-URL-credentials flag が unset であるか、または httpRequest の current URL が include credentials を満たさないなら、authorizationValue をその authentication entry に設定する。
-
さもなければ、もし httpRequest の current URL が include credentials を満たし、かつ isAuthenticationFetch が true なら、authorizationValue を httpRequest の current URL を `
Authorization
` 値に変換したものに設定する(訳注: 実装依存の変換処理を示す) -
もし authorizationValue が non-null なら、append (`
Authorization
`, authorizationValue) を httpRequest の header list に追加する。
-
-
-
もし proxy-authentication entry が存在するなら、適切に使用する。
これはわざと httpRequest の credentials mode に依存しないようになっている。
-
httpCache を、determine the HTTP cache partition を httpRequest に対して実行した結果に設定する。
-
もし httpCache が null なら、httpRequest の cache mode を "
no-store
" に設定する。 -
もし httpRequest の cache mode が "
no-store
" でも "reload
" でもないなら:-
storedResponse を、もしあれば httpCache からレスポンスを選択した結果(必要なら検証を行う)に設定する(これは HTTP Caching の "Constructing Responses from Caches" に従う)。[HTTP-CACHING]
HTTP の要請により、これは `
Vary
` ヘッダーも考慮する。 -
もし storedResponse が non-null なら:
-
もし cache mode が "
default
" で、かつ storedResponse が stale-while-revalidate response であり、httpRequest の client が non-null なら:-
response を storedResponse に設定する。
-
response の cache state を "
local
" に設定する。 -
revalidateRequest を request の clone に設定する。
-
revalidateRequest の cache mode を "
no-cache
" に設定する。 -
revalidateRequest の prevent no-cache cache-control header modification flag を設定する。
-
revalidateRequest の service-workers mode を "
none
" に設定する。 -
In parallel に、main fetch を新しい fetch params(その request が revalidateRequest)で実行する。
このフェッチはキャッシュの状態を更新するためだけのもので、現在のリクエストに対するレスポンスとしては使われない。これはクライアントの文脈で発行されるので、クライアントが消えるとリクエストは終了される。
-
-
さもなければ:
-
もし storedResponse が stale response なら、revalidatingFlag をセットする。
-
もし revalidatingFlag がセットされていて、かつ httpRequest の cache mode が "
force-cache
" でも "only-if-cached
" でもないなら:-
もし storedResponse の header list が `
ETag
` を含むなら、append (`If-None-Match
`, `ETag
` の value) を httpRequest の header list に追加する。 -
もし storedResponse の header list が `
Last-Modified
` を含むなら、append (`If-Modified-Since
`, `Last-Modified
` の value) を httpRequest の header list に追加する。
また HTTP Caching の "Sending a Validation Request" を参照のこと。[HTTP-CACHING]
-
-
さもなければ、response を storedResponse に設定し、response の cache state を "
local
" に設定する。
-
-
-
-
-
If aborted なら、fetchParams に対する appropriate network error を返す。
-
もし response が null なら:
-
もし httpRequest の cache mode が "
only-if-cached
" なら、network error を返す。 -
forwardResponse を、HTTP-network fetch を httpFetchParams, includeCredentials, isNewConnectionFetch で実行した結果とする。
-
もし httpRequest の method が unsafe で、かつ forwardResponse の status が 200 から 399 の範囲内なら、httpCache 内の適切な stored responses を無効化し、storedResponse を null に設定する(これは HTTP Caching の "Invalidating Stored Responses" に従う)。[HTTP-CACHING]
-
もし revalidatingFlag がセットされていて、かつ forwardResponse の status が 304 なら:
-
storedResponse の header list を forwardResponse の header list を用いて更新する(これは HTTP Caching の "Freshening Stored Responses upon Validation" に従う)。[HTTP-CACHING]
これによりキャッシュ内の stored response も更新される。
-
response を storedResponse に設定する。
-
response の cache state を "
validated
" に設定する。
-
-
もし response が null なら:
-
response を forwardResponse に設定する。
-
httpRequest と forwardResponse を httpCache に保存する(これは HTTP Caching の "Storing Responses in Caches" に従う)。[HTTP-CACHING]
もし forwardResponse が network error であれば、これは事実上ネットワークエラーをキャッシュすることになり、"negative caching" と呼ばれることがある。
関連する body info もレスポンスと共にキャッシュに保存される。
-
-
-
response の URL list を、clone した httpRequest の URL list に設定する。
-
もし httpRequest の header list が `
Range
` を含むなら、response の range-requested flag を設定する。 -
response の request-includes-credentials を includeCredentials に設定する。
-
もし response の status が 401 で、かつ httpRequest の response tainting が "
cors
" でなく、includeCredentials が true で、かつ request の traversable for user prompts が traversable navigable であるなら:-
テストが必要: 複数の `
WWW-Authenticate
` ヘッダー、欠落、パースの問題。 -
もし request の body が non-null なら:
-
もし request の body の source が null なら、network error を返す。
-
request の body を、safely extracting の結果の body に設定する。
-
-
もし request の use-URL-credentials flag が unset であるか、または isAuthenticationFetch が true なら:
-
もし fetchParams が canceled なら、fetchParams に対する appropriate network error を返す。
-
エンドユーザーに対して request の traversable for user prompts で username と password の入力を求め、それらを username と password に格納する。
-
Set the username を request の current URL と username に対して実行する。
-
Set the password を request の current URL と password に対して実行する。
-
-
response を、HTTP-network-or-cache fetch を fetchParams と true で実行した結果に設定する。
-
-
もし response の status が 407 なら:
-
もし request の traversable for user prompts が "
no-traversable
" なら、network error を返す。 -
テストが必要: 複数の `
Proxy-Authenticate
` ヘッダー、欠落、パースの問題。 -
もし fetchParams が canceled なら、fetchParams に対する appropriate network error を返す。
-
エンドユーザーに request の traversable for user prompts で適切にプロンプトを表示し、その結果を proxy-authentication entry として保存する。[HTTP]
プロキシ認証に関する残りの詳細は HTTP によって定義される。
-
response を、HTTP-network-or-cache fetch を fetchParams で実行した結果に設定する。
-
-
もし 次のすべてが真 なら:
-
response の status が 421
-
isNewConnectionFetch が false
-
request の body が null、または request の body が non-null でかつその source が non-null
その場合:
-
もし fetchParams が canceled なら、fetchParams に対する appropriate network error を返す。
-
response を、HTTP-network-or-cache fetch を fetchParams, isAuthenticationFetch, true で実行した結果に設定する。
-
-
もし isAuthenticationFetch が true なら、request と与えられた realm に対する authentication entry を作成する。
4.7. HTTP-network フェッチ
HTTP-network fetchを、fetch params fetchParams、 オプションの boolean includeCredentials(デフォルト false)、およびオプションの boolean forceNewConnection(デフォルト false)を与えて実行するには、次の手順を行う:
-
request を fetchParams の request とする。
-
response を null とする。
-
timingInfo を fetchParams の timing info とする。
-
networkPartitionKey を、request に対するネットワークパーティションキーの決定 を実行して得た結果とする。
-
newConnection を、もし forceNewConnection が true なら "
yes
"、そうでなければ "no
" にする。 -
request の mode に応じて分岐する:
- "
websocket
" -
connection を、WebSocket 接続の取得(request の current URL を与えて)で得た結果とする。
- それ以外
-
connection を、接続の取得(networkPartitionKey、 request の current URL、 includeCredentials、および newConnection を与えて)で得た結果とする。
- "
-
次の手順を実行する。ただし abort when fetchParams が canceled の場合は中止する:
-
もし connection が failure なら、network error を返す。
-
timingInfo の final connection timing info を、 clamp and coarsen connection timing info を connection の timing info、 timingInfo の post-redirect start time、 および fetchParams の cross-origin isolated capability と共に呼び出した結果に設定する。
-
もし connection が HTTP/1.x 接続で、かつ request の body が non-null であり、かつその source が null なら、network error を返す。
-
timingInfo の final network-request start time を、coarsened shared current time(fetchParams の cross-origin isolated capability を用いて得たもの)に設定する。
-
connection 上で request を用いた HTTP リクエストを行い、その結果を response に設定する。ただし以下の注意を伴う:
-
HTTP に関する関連要件に従うこと。[HTTP] [HTTP-CACHING]
-
もし request の body が non-null で、かつその source が null なら、ユーザーエージェントは最大 64 KiB のバッファを保持して request の一部の body をそこに保存してよい。もしユーザーエージェントがそのバッファサイズを超えて request の body を読み、かつ再送が必要になった場合は、代わりに network error を返す。
-
次の処理を繰り返す:
-
timingInfo の final network-response start time を、ユーザーエージェントの HTTP パーサがレスポンスの最初のバイトを受け取った直後(例:HTTP/2 のフレームヘッダバイトや HTTP/1.x のステータス行)に、coarsened shared current time(fetchParams の cross-origin isolated capability を用いて得たもの)に設定する。
-
すべての HTTP レスポンスヘッダが送信されるまで待つ。
-
status を HTTP レスポンスのステータスコードとする。
-
もし status が 100〜199 の範囲にあるなら:
-
もし timingInfo の first interim network-response start time が 0 なら、timingInfo の同名の値を timingInfo の final network-response start time に設定する。
-
もし request の mode が "
websocket
" で、かつ status が 101 なら break する。 -
もし status が 103 で、かつ fetchParams の process early hints response が non-null なら、queue a fetch task して fetchParams の同名の処理を response と共に実行する。
この種の HTTP レスポンスは最終的に "final" な HTTP レスポンスに続く。
-
-
Fetch と HTTP の正確なレイヤリングはまだ整理が必要であり、ここでは response が HTTP レスポンスも表すものとして扱われている。
もし HTTP リクエストが TLS クライアント証明書ダイアログを必要とする場合は、次を行う:
-
もし request の traversable for user prompts が traversable navigable であれば、ダイアログをその request の traversable for user prompts に表示可能にする。
-
それ以外の場合、network error を返す。
request の body(ここでは body と呼ぶ)を送信するには、次の手順を実行する:
-
もし body が null で、かつ fetchParams の process request end-of-body が non-null なら、queue a fetch task して fetchParams の同名の処理を fetchParams の task destination で実行する。
-
それ以外で body が non-null の場合:
-
processBodyChunk(bytes を受け取る)を次の手順として定義する:
-
もし fetchParams が canceled なら、これらの手順を中止する。
-
このステップを in parallel で実行する:bytes を送信する。
-
もし fetchParams の process request body chunk length が non-null なら、fetchParams の同名の処理を bytes の length を与えて実行する。
-
-
processEndOfBody を次の手順として定義する:
-
もし fetchParams が canceled なら、中止する。
-
もし fetchParams の process request end-of-body が non-null なら、それを実行する。
-
-
processBodyError(引数 e)を次の手順として定義する:
-
もし fetchParams が canceled なら中止する。
-
もし e が "
AbortError
"DOMException
であれば、abort で fetchParams の controller を中断する。 -
それ以外の場合は、terminate で fetchParams の controller を終了する。
-
-
Incrementally read を使って、request の body を processBodyChunk、processEndOfBody、processBodyError、および fetchParams の task destination を与えて逐次的に読み取る。
-
-
-
-
If aborted なら、次を実行する:
-
もし connection が HTTP/2 を使用しているなら、
RST_STREAM
フレームを送信する。 -
fetchParams に対する appropriate network error を返す。
-
-
buffer を空の byte sequence とする。
これはユーザーエージェントのネットワークレイヤ内部の内部バッファを表す。
-
stream を新しい
ReadableStream
とする。 -
pullAlgorithm を次の手順とする:
-
promise を 新しい Promise とする。
-
次の手順を 並行して 実行する:
-
もし buffer のサイズがユーザーエージェントが選んだ下限より小さく、かつ 現在のフェッチが suspended であるなら、フェッチを resume する。
-
buffer が空でなくなるまで待つ。
-
Queue a fetch task して、以下を fetchParams の task destination で実行する。
-
Pull from bytes で buffer から stream にデータを引き出す。
-
もし stream が errored なら、terminate で fetchParams の controller を終了する。
-
Resolve promise を undefined で完了する。
-
-
-
promise を返す。
-
-
cancelAlgorithm を、与えられた reason に対して abort を行い fetchParams の controller を中断するアルゴリズムとする。
-
Set up で stream をバイト読み取り対応でセットアップし、pullAlgorithm を pullAlgorithm、cancelAlgorithm を cancelAlgorithm に設定する。
-
もし includeCredentials が true なら、ユーザーエージェントは request と response を与えて レスポンスの `
Set-Cookie
` ヘッダをパースして保存 すべきである。 -
次の手順を 並行して 実行する:
-
次の手順を実行する。ただし abort when fetchParams が canceled の場合は中止する:
-
繰り返し実行する:
-
もし response のメッセージ本文から 1 バイト以上が送信されているなら:
-
bytes を送信されたバイトとする。
-
codings を、`
Content-Encoding
` と response の header list から header list values を抽出 した結果とする。 -
filteredCoding を "
@unknown
" にする。 -
もし codings が null または failure なら filteredCoding を空文字にする。
-
そうでなく、かつ codings の size が 1 より大きければ、filteredCoding を "
multiple
" にする。 -
それ以外で、もし codings[0] が空文字、またはユーザーエージェントがサポートしており、かつ バイトケース非区別 な比較で HTTP Content Coding Registry に記載されたエントリに一致するなら、filteredCoding を byte-lowercasing を行った codings[0] にする。[IANA-HTTP-PARAMS]
-
response の body info の content encoding を filteredCoding に設定する。
-
response の body info の encoded size を bytes の length だけ増やす。
-
bytes を、handle content codings に codings と共に与えて処理した結果にする。
これにより `
Content-Length
` ヘッダの信頼性が、元々の信頼性に応じて損なわれる可能性がある。 -
response の body info の decoded size を bytes の length だけ増やす。
-
もし bytes が failure なら、terminate で fetchParams の controller を終了する。
-
bytes を buffer に追記する。
-
もし buffer のサイズがユーザーエージェントが選んだ上限より大きければ、ユーザーエージェントに継続中のフェッチを suspend するよう要求する。
-
-
それ以外で、もし response のメッセージ本文のバイト送信が正常に完了しており、かつ stream が readable なら、close で stream を閉じ、これらの並行ステップを中止する。
-
-
-
If aborted なら、次を実行する:
-
もし fetchParams が aborted なら、次を実行する:
-
response の aborted flag を設定する。
-
もし stream が readable なら、error で stream を、fetchParams の controller の serialized abort reason を deserialize a serialized abort reason に渡した結果と実装定義の realm を用いてエラー化する。
-
-
それ以外で、もし stream が readable なら、error で stream を TypeError にする。
-
もし connection が HTTP/2 を使用しているなら、
RST_STREAM
フレームを送信する。 -
それ以外の場合、パフォーマンス上問題がない限りユーザーエージェントは connection を閉じるべきである。
例えば、再利用可能な接続で残りの転送がごく少量とわかっている場合、接続を閉じて次のフェッチでハンドシェイクをやり直すよりも、接続を開いたままにしておくほうが良いことがある。
-
これらは並行して実行される。現時点では response の body が関連するかどうか不明(response がリダイレクトである可能性がある)ためである。
-
4.8. CORSプリフライトフェッチ
これは実質的に、CORSプロトコルが理解されているかどうかを確認するためのユーザーエージェント実装である。いわゆるCORSプリフライトリクエスト。成功すると、CORSプリフライトキャッシュに登録され、このフェッチの回数を最小限に抑える。
CORSプリフライトフェッチは、request request を受け取って、次の手順を実行する:
-
preflight を新しい request とし、 method を `
OPTIONS
`、 URL list を request の clone、 initiator を request の initiator、 destination を request の destination、 origin を request の origin、 referrer を request の referrer、 referrer policy を request の referrer policy、 mode を "cors
"、 response tainting を "cors
" にする。preflight の service-workers mode は重要ではない。このアルゴリズムは HTTP-network-or-cache fetch を使い、 HTTP fetch は使用しない。
-
append (`
Accept
`, `*/*
`) を preflight の header list に追加する。 -
append (`
Access-Control-Request-Method
`, request の method) を preflight の header list に追加する。 -
headers を CORS非セーフリストリクエストヘッダー名で request の header list に適用したものとする。
-
headers が 空でない場合は、
-
value を headers 内の項目を `
,
` で区切った文字列とする。 -
append (`
Access-Control-Request-Headers
`, value) を preflight の header list に追加する。
意図的にcombineは使わない。0x2Cの後の0x20は実装された通りであり、良し悪しは別としてそうなっている。
-
-
response を HTTP-network-or-cache fetch を、新しい fetch params(その request が preflight)で実行した結果とする。
-
もし CORSチェック を request と response で実行した結果が成功であり、かつ response の status が ok status なら:
CORSチェックは preflight ではなく request に対して行う。これは正しいcredentials modeを使うためである。
-
methods を extracting header list values を `
Access-Control-Allow-Methods
` と response の header list で実行した結果とする。 -
headerNames を extracting header list values を `
Access-Control-Allow-Headers
` と response の header list で実行した結果とする。 -
methods または headerNames が failure なら、network error を返す。
-
methods が null かつ request の use-CORS-preflight flag が設定されている場合は、methods を request の method だけを持つ新しいリストに設定する。
これは request の use-CORS-preflight flag が設定されて発生した CORSプリフライトフェッチがキャッシュされることを保証する。
-
request の method が methods に含まれない、または request の method が CORSセーフリストメソッドでない、かつ request の credentials mode が "
include
" または methods に `*
` が含まれない場合は、network error を返す。 -
request の header list の names のいずれかが CORS非ワイルドカードリクエストヘッダー名 であり、かつ headerNames の item とバイトケース非区別で一致しない場合は、network error を返す。
-
for each unsafeName in CORS非セーフリストリクエストヘッダー名(request の header listに適用)、unsafeName が headerNames の item とバイトケース非区別で一致せず、かつ request の credentials mode が "
include
" または headerNames に `*
` が含まれない場合は、network error を返す。 -
max-age を extracting header list values を `
Access-Control-Max-Age
` と response の header list で実行した結果とする。 -
max-age が failure または null なら、max-age を 5 に設定する。
-
max-age が課された上限を超える場合は、max-age をその上限に設定する。
-
ユーザーエージェントがキャッシュを提供しない場合は、response を返す。
-
methods 内の各 method について、method cache entry match が request に対して存在するなら、そのエントリの max-age を max-age に設定する。
-
methods 内の各 method について、method cache entry match が request に対して存在しないなら、create a new cache entry を request、max-age、method、null で実行する。
-
headerNames 内の各 headerName について、header-name cache entry match が request に対して存在するなら、そのエントリの max-age を max-age に設定する。
-
headerNames 内の各 headerName について、header-name cache entry match が request に対して存在しないなら、create a new cache entry を request、max-age、null、headerName で実行する。
-
response を返す。
-
-
それ以外の場合は、network error を返す。
4.9. CORSプリフライトキャッシュ
ユーザーエージェントは CORSプリフライトキャッシュ を持つ。 CORSプリフライトキャッシュは リストであり、 キャッシュエントリのリストである。
キャッシュエントリは以下から構成される:
- キー(ネットワークパーティションキー)
- バイト列化されたオリジン(バイト列)
- URL(URL)
- max-age(秒数)
- 認証情報(boolean値)
- メソッド(null, `
*
` または method) - ヘッダー名(null, `
*
` または header name)
キャッシュエントリは、その max-age フィールドに指定された秒数が格納から経過したら削除されなければならない。 キャッシュエントリは、それより前に削除されてもよい。
キャッシュエントリ作成は、request、 max-age、method、headerName を受け取って、以下の手順を実行する:
-
entry を キャッシュエントリとして以下で初期化する:
- キー
-
request を与えて ネットワークパーティションキーの決定 の結果
- バイト列化されたオリジン
-
request を与えて リクエストオリジンのバイト列化 の結果
- URL
-
request の current URL
- max-age
-
max-age
- 認証情報
-
request の credentials mode が "
include
" なら true、それ以外は false - メソッド
-
method
- ヘッダー名
-
headerName
-
append で entry をユーザーエージェントの CORSプリフライトキャッシュ に追加する。
キャッシュのクリアは request を受け取り、 ユーザーエージェントの CORSプリフライトキャッシュ の中で、 remove を使って、 キー が request に対する ネットワークパーティションキーの決定の結果、 バイト列化されたオリジン が request に対する リクエストオリジンのバイト列化 の結果、 URL が request の current URL である キャッシュエントリを削除する。
キャッシュエントリ一致は キャッシュエントリ entry と request に対して成立する条件は、 entry の キー が request に対する ネットワークパーティションキーの決定の結果、 entry の バイト列化されたオリジン が request に対する リクエストオリジンのバイト列化 の結果、 entry の URL が request の current URL で、次のいずれかが真であること:
- entry の 認証情報 が true
- entry の 認証情報 が false かつ request の
credentials mode が "
include
" でない
場合に成立する。
メソッドキャッシュエントリ一致は
method と request に対して、ユーザーエージェントの CORSプリフライトキャッシュ 内に
キャッシュエントリ一致が
request で成立し、
その メソッド が
method か `*
` である
キャッシュエントリが存在する場合に成立する。
ヘッダー名キャッシュエントリ一致は headerName と request に対して、ユーザーエージェントの CORSプリフライトキャッシュ 内に キャッシュエントリ一致が request で成立し、次のいずれかが真である キャッシュエントリが存在する場合に成立する:
- その ヘッダー名 が headerName と バイトケース非区別で一致する
- その ヘッダー名 が `
*
` であり、 headerName が CORS非ワイルドカードリクエストヘッダー名でない場合
の場合に成立する。
4.10. CORSチェック
CORSチェックを request と response で実行するには、以下の手順を行う:
-
origin を response の header list から `
Access-Control-Allow-Origin
` を 取得した結果とする。 -
origin が null なら failure を返す。
null は `
null
` とは異なる。 -
request の credentials mode が "
include
" でなく、かつ origin が `*
` の場合、success を返す。 -
request に対して リクエストオリジンのバイト列化 を実行した結果が origin でなければ failure を返す。
-
request の credentials mode が "
include
" でなければ success を返す。 -
credentials を response の header list から `
Access-Control-Allow-Credentials
` を 取得した結果とする。 -
credentials が `
true
` なら success を返す。 -
failure を返す。
4.11. TAOチェック
TAOチェックを request と response で実行するには、以下の手順を行う:
-
request の timing allow failed flag が設定されていれば、failure を返す。
-
values を response の header list から `
Timing-Allow-Origin
` を 取得・デコード・分割した結果とする。 -
values が "
*
" を含むなら success を返す。 -
values が request に対して リクエストオリジンのシリアライズ を実行した結果を含むなら success を返す。
-
request の mode が "
navigate
" かつ request の current URL の origin が request の origin と 同一オリジンでない場合、failure を返す。これはネストされたナビゲーションのために必要である。その場合、request の origin はコンテナー文書の origin であり、TAOチェックは失敗となる。ナビゲーションタイミングは TAOチェック の結果を検証しないため、ネストされた文書は完全なタイミング情報にアクセスできるが、コンテナー文書はできない。
-
request の response tainting が "
basic
" なら success を返す。 -
failure を返す。
4.12. 遅延フェッチ
遅延フェッチは、呼び出し元がフェッチを可能な限り遅いタイミング(すなわちフェッチグループが終了されたとき、または タイムアウト後)に実行するよう依頼できるようにします。
遅延フェッチタスクソースは、
遅延フェッチの結果を更新するためのタスクソースです。
ユーザーエージェントは、このタスクソース内のタスクを他のタスクソースよりも優先して処理しなければなりません。
特に、DOM操作タスクソースなどスクリプトが実行される可能性のあるタスクソースよりも優先し、
fetchLater()
呼び出しの最新状態が、それに依存するスクリプト実行前に反映されるようにします。
遅延フェッチをキューするには、
request
request、
nullまたはDOMHighResTimeStamp
activateAfter、
引数なしアルゴリズム onActivatedWithoutTermination を受け取って以下を行う:
-
クライアントからリクエストを設定するをrequestに対して実行する。
-
request の service-workers mode を "
none
" に設定する。 -
request の keepalive を true に設定する。
-
deferredRecord を新しい 遅延フェッチレコード( request が request、notify invoked が onActivatedWithoutTermination )として作成する。
-
appendでdeferredRecordをrequestの clientのfetch groupの deferred fetch recordsに追加する。
-
activateAfter が non-null なら、以下を並行して実行する:
-
deferredRecord を返す。
総リクエスト長を request request で計算するには:
-
totalRequestLength を、request の URLを シリアライズ( exclude fragmentをtrueにした状態)した 長さとする。
-
for each (name, value) of request の header list: totalRequestLength に name の 長さ + value の 長さ を加算する。
-
totalRequestLength を返す。
遅延フェッチの処理を fetch group fetchGroup に対して実行するには:
-
for each deferred fetch record deferredRecord of fetchGroup の deferred fetch records: 遅延フェッチを処理(deferredRecord)。
遅延フェッチを処理(deferredRecord):
-
deferredRecord の invoke state が "
pending
" でなければ return。 -
deferredRecord の invoke state を "
sent
" にする。 -
グローバルタスクをキューし、遅延フェッチタスクソース上で deferredRecord の request の client の global object で deferredRecord の notify invoked を実行する。
4.12.1. 遅延フェッチのクォータ
この節は規範的ではありません。
遅延フェッチクォータは、トップレベルトラバーサブル(「タブ」)ごとに640キビバイト割り当てられます。 トップレベル文書と同一オリジンの直接ネスト文書はこのクォータを使って遅延フェッチをキューしたり、パーミッションポリシーを使って一部をクロスオリジンのネスト文書に委譲したりできます。
デフォルトでは、640キビバイトのうち128キビバイトがクロスオリジンのネスト文書への委譲に割り当てられ、各文書は8キビバイトを予約します。
トップレベルのdocumentおよびそのネスト文書は、パーミッションポリシーを使って自身のクォータのうちどれだけをクロスオリジンの子文書に委譲するかを制御できます。デフォルトでは、
"deferred-fetch-minimal
"
ポリシーは任意のオリジンに対して有効、
"deferred-fetch
"
はトップレベル文書のオリジンだけに有効です。特定のオリジンやネスト文書に対して
"deferred-fetch
"
ポリシーを緩和すれば、そのネスト文書に64キビバイトを割り当てられます。同様に
"deferred-fetch-minimal
"
ポリシーを特定のオリジンやネスト文書に対して制限すれば、その文書がデフォルトで受け取る8キビバイト予約を防ぐことができます。トップレベル文書自身に
"deferred-fetch-minimal
"
ポリシーを無効化すれば、128キビバイトの委譲クォータがメインプール(640キビバイト)に戻されます。
あるdocumentに割り当てられたクォータのうち、同じレポートオリジン(request の URL の origin)に同時に使えるのは64キビバイトだけです。これにより、特定のサードパーティーライブラリがデータ送信前に機会的にクォータを予約してしまう事態を防げます。
以下のいずれかのfetchLater()
呼び出しは、リクエスト自体がレポートオリジンに割り当てられた64キビバイトクォータを超えるためthrowされます。リクエストのサイズはURL自体、body、header list、referrerを含みます。
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});
以下のツリーは異なるネスト文書にクォータがどのように分配されるかを示します:
-
https://top.example.com
(Permissions-policy: deferred-fetch=(self "https://ok.example.com")が設定されている)-
https://top.example.com/frame
:トップレベル遷移可能と同じオリジンなのでクォータを共有する。-
https://x.example.com
:8キビバイトを受け取る。
-
-
https://x.example.com
:8キビバイトを受け取る。-
https://top.example.com
:0。同一オリジンだがクロスオリジンの中間層があるため自動でクォータは共有されない。
-
-
https://ok.example.com/good
:"deferred-fetch
"ポリシーによって64キビバイトを受け取る。-
https://x.example.com
:クォータなし。トップレベル遷移可能と同一オリジンのみが"deferred-fetch-minimal
"ポリシーにより8キビバイトを付与できる。
-
-
https://ok.example.com/redirect
からhttps://x.example.com
へ遷移:クォータなし。https://ok.example.com
用に予約された64キビバイトはhttps://x.example.com
では利用不可。 -
https://ok.example.com/back
からhttps://top.example.com
へ戻る:同一オリジンなのでトップレベル遷移可能とクォータを共有する。
-
上記の例では、トップレベル遷移可能とその同一オリジンの子孫は384キビバイトのクォータを共有します。その値は以下のように計算されます:
-
640キビバイトが最初にトップレベル遷移可能に付与される。
-
128キビバイトが"
deferred-fetch-minimal
"ポリシー用に予約される。 -
64キビバイトが
https://ok.example/good
への遷移用に予約される。 -
64キビバイトが
https://ok.example/redirect
への遷移用に予約され、遷移時に失われる。 https://ok.example.com/back
は64キビバイトを予約しない。なぜならトップレベル遷移可能のオリジンに戻ったため。-
640 − 128 − 64 − 64 = 384キビバイト。
この仕様は、文字列"deferred-fetch
"で識別されるポリシー制御機能を定義します。そのデフォルト許可リストは"self
"です。
この仕様は、文字列"deferred-fetch-minimal
"で識別されるポリシー制御機能を定義します。そのデフォルト許可リストは"*
"です。
deferred-fetch-minimal
用に予約されたクォータは128キビバイトです。
各ナビゲーション可能コンテナは関連付けられた数値遅延フェッチ用予約クォータを持ちます。その値はミニマルクォータ(8キビバイト)、ノーマルクォータ(0または64キビバイト)。特に記載がない場合は0です。
利用可能な遅延フェッチクォータ を、document document と、origin-または-null の origin を指定して取得するには:
-
controlDocumentにdocumentの遅延フェッチ制御文書を設定する。
-
navigableにcontrolDocumentのノード遷移可能を設定する。
-
isTopLevelにcontrolDocumentのノード遷移可能がトップレベル遷移可能ならtrue、そうでなければfalseを設定する。
-
deferredFetchAllowedにcontrolDocumentが"
deferred-fetch
"ポリシー制御機能の利用を許可されていればtrue、そうでなければfalseを設定する。 -
deferredFetchMinimalAllowedにcontrolDocumentが"
deferred-fetch-minimal
"ポリシー制御機能の利用を許可されていればtrue、そうでなければfalseを設定する。 -
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
-
quotaForRequestOriginに64キビバイトを設定する。
-
各navigable(controlDocumentのノード遷移可能の包括的子孫遷移可能で、アクティブ文書の遅延フェッチ制御文書がcontrolDocumentであるもの)について:
-
各container(navigableのアクティブ文書のshadow-including包括的子孫のうちナビゲーション可能コンテナ)について、quotaからcontainerの遅延フェッチ用予約クォータを減算する。
-
各deferred fetch recorddeferredRecord(navigableのアクティブ文書の関連設定オブジェクトのfetch groupのdeferred fetch records)について:
-
-
quotaが0以下なら0を返す。
-
quotaがquotaForRequestOrigin未満ならquotaを返す。
-
quotaForRequestOriginを返す。
遅延フェッチクォータの予約は、ナビゲーション可能コンテナcontainerとoriginoriginToNavigateToを指定して以下を実行します:
これはナビゲーション時、ナビゲーション元文書がnavigableの親文書である場合に呼ばれます。パーミッションポリシーで許可されていれば、コンテナおよびそのナビゲーション可能要素に最大64kbまたは8kbのクォータを予約します。予約されたクォータが実際に使われたかどうかはコンテナ文書から観測できません。このアルゴリズムは、コンテナの文書がナビゲート先コンテナにクォータを委譲する可能性があると仮定し、予約されたクォータはその場合のみ適用され、共有されることになった場合は無視されます。クォータが予約され、その文書が親と同一オリジンとなった場合、クォータは解放されます。
-
containerの遅延フェッチ用予約クォータを0に設定する。
-
controlDocumentにcontainerのノード文書の遅延フェッチ制御文書を設定する。
-
"
deferred-fetch
" の継承ポリシー(container, originToNavigateTo)が"Enabled"
であり、controlDocumentの利用可能な遅延フェッチクォータがノーマルクォータ以上であれば、containerの遅延フェッチ用予約クォータをノーマルクォータに設定してreturnする。 -
以下すべてが真の場合:
-
controlDocumentのノード遷移可能がトップレベル遷移可能である
-
"
deferred-fetch-minimal
" の継承ポリシー(container, originToNavigateTo)が"Enabled"
である -
controlDocumentのノード遷移可能の子孫遷移可能(除外:コンテナのnavigable containerの遅延フェッチ用予約クォータがミニマルクォータでないものを除外)のサイズが、deferred-fetch-minimal用予約クォータ / ミニマルクォータ より小さい
この場合、containerの遅延フェッチ用予約クォータをミニマルクォータに設定する。
-
遅延フェッチクォータの解放(可能性あり)は、文書documentに対して、documentのノード遷移可能のコンテナ文書がnullでなく、かつそのoriginがdocumentと同一オリジンであれば、documentのノード遷移可能のnavigable containerの遅延フェッチ用予約クォータを0に設定する。
これは文書が生成されたときに呼ばれます。同一オリジンのネスト文書は親クォータを共有するため予約しません。これは文書生成時のみ呼ばれ、originはリダイレクト処理後にのみ判明するためです。
遅延フェッチ制御文書の取得は、文書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)を持つ。
これは初期状態では空である。これは他のもの、例えば
header
listへのポインタでもよく、
Request
オブジェクトの
request
の場合が例である。
Headers
オブジェクトには、さらに関連付けられたガード(headers guard)があります。headers
guardは、"immutable
"、"request
"、"request-no-cors
"、"response
"、"none
"のいずれかです。
headers = new Headers([init])
-
新しい
Headers
オブジェクトを生成します。initで内部のヘッダーリストを初期化できます(下記例参照)。 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に対して行うには:
-
headersのガードが"
request
"かつ(name, value)が禁止リクエストヘッダーなら、falseを返す。 -
headersのガードが"
response
"かつnameが禁止レスポンスヘッダー名なら、falseを返す。 -
trueを返す。
"request-no-cors
"の手順は共有されません。なぜならCORS安全リストリクエストヘッダーに対して常に成功する偽の値(delete()
用)を持つことができないためです。
追加(ヘッダー(name, value))をHeaders
オブジェクトheadersに対して行うには、以下を実行する:
-
valueを正規化する。
-
バリデート(name, value)がheadersでfalseなら、returnする。
-
headersのガードが"
request-no-cors
"なら:-
temporaryValueにheadersのheader listからnameを取得した結果を設定する。
-
temporaryValueがnullなら、temporaryValueをvalueに設定する。
-
それ以外の場合、temporaryValueをtemporaryValue+「, 」+valueに設定する。
-
(name, temporaryValue)がno-CORS安全リストリクエストヘッダーでない場合、returnする。
-
-
追加(name, value)をheadersのheader listに対して実行する。
-
headersのガードが"
request-no-cors
"なら、特権no-CORSリクエストヘッダーの削除をheadersに対して実行する。
fill(Headers
オブジェクトheaders、与えられたオブジェクトobject)は以下を実行する:
特権no-CORSリクエストヘッダーの削除(Headers
オブジェクト(headers))は以下を実行する:
-
各headerName(特権no-CORSリクエストヘッダー名)について:
-
削除(headerName)をheadersのheader listに対して実行する。
-
これは、特権のないコードによってヘッダーが変更された時に呼ばれます。
delete(name)
メソッドの手順は以下の通りです:
-
バリデート(name, ``)がthisでfalseなら、returnする。
ダミーのヘッダー値を渡しても悪影響はありません。
-
thisのガードが"
request-no-cors
"、かつnameがno-CORS安全リストリクエストヘッダー名でも特権no-CORSリクエストヘッダー名でもない場合、returnする。 -
thisのheader listがnameを含まない場合、returnする。
-
削除(name)をthisのheader listに対して実行する。
-
thisのガードが"
request-no-cors
"なら、特権no-CORSリクエストヘッダーの削除をthisに対して実行する。
get(name)
メソッドの手順は以下の通りです:
-
nameを取得(thisのheader listから)し、その結果を返す。
getSetCookie()
メソッドの手順は以下の通りです:
-
thisのheader listが`
Set-Cookie
`を含まない場合、« »を返す。 -
値(thisのheader listのうち、nameが`
Set-Cookie
`とバイト大文字小文字無視で一致するヘッダー)の値を順序通り返す。
has(name)
メソッドの手順は以下の通りです:
-
thisのheader listがnameを含むならtrue、そうでなければfalseを返す。
set(name, value)
メソッドの手順は以下の通りです:
-
valueを正規化する。
-
thisのガードが"
request-no-cors
"かつ(name, value)がno-CORS安全リストリクエストヘッダーでない場合、returnする。 -
セット(name, value)をthisのheader listに対して実行する。
-
thisのガードが"
request-no-cors
"なら、特権no-CORSリクエストヘッダーの削除をthisに対して実行する。
反復対象の値ペアは、ソートおよび結合(thisのheader list)の実行結果です。
5.2. BodyInit ユニオン型
typedef (Blob or BufferSource or FormData or URLSearchParams or USVString );
XMLHttpRequestBodyInit typedef (ReadableStream or XMLHttpRequestBodyInit );
BodyInit
安全抽出は、型付きbodyをバイト列またはBodyInit
オブジェクトobjectから抽出するための手順です:
-
objectが
ReadableStream
オブジェクトなら: -
extract(object)の結果を返す。
安全抽出操作は、例外を投げないことが保証されるextract操作のサブセットです。
extractは、
型付きbodyをバイト列またはBodyInit
オブジェクトobjectから抽出するための手順です。オプションのブール値
keepalive(デフォルトfalse)を受け取ります:
-
streamをnullに設定する。
-
objectが
ReadableStream
オブジェクトなら、streamにobjectを設定する。 -
それ以外でobjectが
Blob
オブジェクトなら、streamにobjectのget streamの結果を設定する。 -
それ以外の場合、streamに新しい
ReadableStream
オブジェクトを設定し、 バイト読み取り対応でセットアップする。 -
アサート:streamは
ReadableStream
オブジェクトであること。 -
actionをnullに設定する。
-
sourceをnullに設定する。
-
lengthをnullに設定する。
-
typeをnullに設定する。
-
objectの型によって分岐:
Blob
-
sourceにobjectを設定する。
lengthにobjectの
size
属性値を設定する。objectの
type
属性値が空でなければ、typeにその値を設定する。 - バイト列
-
sourceにobjectを設定する。
BufferSource
-
sourceにobjectが保持するバイトのコピーを設定する。
FormData
-
actionに次の手順:
multipart/form-data
エンコーディングアルゴリズムをobjectのentry listとUTF-8で実行する、を設定する。sourceにobjectを設定する。
lengthに未確定、詳細は html/6424参照を設定する。
typeに`
multipart/form-data; boundary=
`+multipart/form-data
境界文字列(multipart/form-data
エンコーディングアルゴリズムで生成)を設定する。 URLSearchParams
-
sourceに
application/x-www-form-urlencoded
シリアライザ(objectのlistを使う)を実行した結果を設定する。typeに`
application/x-www-form-urlencoded;charset=UTF-8
`を設定する。 - スカラー値文字列
-
sourceにUTF-8エンコード(object)の結果を設定する。
typeに`
text/plain;charset=UTF-8
`を設定する。 ReadableStream
-
keepaliveがtrueなら、TypeError例外を投げる。
-
sourceがバイト列なら、actionに「sourceを返す」手順を設定し、lengthにsourceのlengthを設定する。
-
actionがnullでなければ、以下の手順を並列で実行する:
-
actionを実行する。
バイトが1つ以上利用可能になり、かつstreamがerroredでなければ、enqueue(利用可能なバイトから
Uint8Array
を生成した結果、stream)を行う。actionが終了したら、close(stream)を行う。
-
-
bodyにbody(stream: stream, source: source, length: length)を設定する。
-
(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 でなく、
かつその
body の stream が 乱された または
ロック済み の場合、
使用不可
であると言う。
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に対して以下を実行します:
-
headersをnullに設定する。
-
requestOrResponseが
Request
オブジェクトなら、headersにrequestOrResponseのrequestのheader listを設定する。 -
それ以外の場合、headersにrequestOrResponseのresponseのheader listを設定する。
-
mimeTypeにMIMEタイプ抽出(headers)の結果を設定する。
-
mimeTypeが失敗ならnullを返す。
-
mimeTypeを返す。
consume body
アルゴリズムは、Body
を含むオブジェクトobjectと、バイト列を受け取りJavaScript値を返す(または例外を投げる)アルゴリズムconvertBytesToJSValueを受け取り、以下を実行します:
-
objectが使用不可なら、TypeErrorでrejectされたpromiseを返す。
-
promiseに新しいpromiseを設定する。
- errorSteps(error)にpromiseをerrorでrejectする手順を設定する。
- successSteps(バイト列data)にpromiseをconvertBytesToJSValue(data)の結果でresolveする手順(例外ならerrorStepsを実行)を設定する。
-
それ以外なら、完全に読み取る(objectのbody、successSteps、errorSteps、objectの関連グローバルオブジェクト)を実行する。
-
promiseを返す。
arrayBuffer()
メソッドの手順は、consume body(this、バイト列bytesの場合はArrayBuffer作成(bytes、thisの関連realm))を返すこと。
このメソッドはRangeError
でrejectされる場合があります。
blob()
メソッドの手順は、consume body(this、バイト列bytesの場合はBlob
(内容:bytes、type属性:MIMEタイプ取得(this)))を返すこと。
bytes()
メソッドの手順は、consume body(this、バイト列bytesの場合はUint8Array作成(bytes、thisの関連realm))を返すこと。
このメソッドはRangeError
でrejectされる場合があります。
formData()
メソッドの手順は、consume body(this、バイト列bytesの場合は以下の手順)を返すこと:
-
mimeTypeがnullでなければ、mimeTypeのessenceごとに分岐する:
- "
multipart/form-data
" -
-
bytesをmimeTypeの`
boundary
`パラメータ値を使ってRFC7578の規則に従いパースする。`
Content-Disposition
`ヘッダーに`filename
`パラメータを持つ各部品は、その内容からFile
オブジェクトとしてパースされる。そのname
属性はその`filename`パラメータ値、type
属性は部品の`Content-Type`ヘッダー値(なければ`text/plain`)となる。`
filename
`を持たない部品は、UTF-8デコード(BOMなし)した内容としてパースされる(`Content-Type`や`charset`の有無・値は無視)。`
Content-Disposition
`ヘッダーに`name
`パラメータが`_charset_`の場合でもエンコーディングは変わりません。 -
何らかの理由で失敗した場合は
TypeError
例外を投げる。 -
パース結果の各エントリを
FormData
オブジェクトのentry listに追加し新たなFormDataを返す。
上記は`multipart/form-data`に必要な処理の概略です。より詳細な仕様策定が必要です。協力者歓迎。
-
- "
application/x-www-form-urlencoded
"
- "
-
TypeError
例外を投げる。
json()
メソッドの手順は、consume body(this、JSONパース)を返すこと。
このメソッドはSyntaxError
でrejectされる場合があります。
text()
メソッドの手順は、consume body(this、UTF-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 ; // can only be set to null };
window 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
オブジェクトには関連付けられたrequest(request)があります。
Request
オブジェクトには、関連付けられたheaders(nullまたはHeaders
オブジェクト、初期値はnull)があります。
Request
オブジェクトには、関連付けられたsignal(nullまたはAbortSignal
オブジェクト、初期値はnull)があります。
Request
オブジェクトのbodyは、そのrequestのbodyです。
request = new Request(input [, init])
-
requestの
url
プロパティは、inputが文字列の場合はその値、inputがRequest
オブジェクトの場合はそのurl
になります。init引数は以下のようにプロパティを設定できるオブジェクトです:
method
- 文字列でrequestの
method
を設定します。 headers
Headers
オブジェクト、リテラルオブジェクト、または2要素配列の配列でrequestのheaders
を設定します。body
BodyInit
オブジェクトまたはnullでrequestのbodyを設定します。referrer
- 同一オリジンのURL、"
about:client
"、または空文字列でrequestのreferrerを設定します。 referrerPolicy
- referrer policyでrequestの
referrerPolicy
を設定します。 mode
- リクエストがCORSを使うか、同一オリジンに制限されるかを示す文字列。requestの
mode
を設定します。inputが文字列の場合、デフォルトは"cors
"です。 credentials
- リクエストに認証情報を常に送るか、送らないか、同一オリジンのURLのみ送るか、またレスポンスの認証情報を常に使うか、使わないか、同一オリジンのレスポンスのみ使うかを示す文字列。requestの
credentials
を設定します。inputが文字列の場合、デフォルトは"same-origin
"です。 cache
- リクエストがブラウザのキャッシュとどうやり取りするかを示す文字列。requestの
cache
を設定します。 redirect
- リダイレクトに従うか、エラーにするか、リダイレクト(不透明な形)を返すかを示す文字列。requestの
redirect
を設定します。 integrity
- 取得するリソースの暗号学的ハッシュ。requestの
integrity
を設定します。 keepalive
- グローバルが破棄されてもrequestが生き残れるかどうかを示す真偽値。requestの
keepalive
を設定します。 signal
AbortSignal
でrequestのsignal
を設定します。window
- nullのみ可。requestを
Window
から切り離すのに使われます。 duplex
- "
half
"のみ有効。ハーフデュプレックスフェッチ(リクエスト送信後にレスポンス処理)用。"full"は将来用で、フルデュプレックス(リクエスト送信中にレスポンス処理)用に予約されています。bodyがReadableStream
の場合は必須。"full"の仕様化はissue #1254参照。 priority
- 文字列でrequestのpriorityを設定します。
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 はデフォルトでリダイレクトを追従する。
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
request、headers
guard guard、
AbortSignal
オブジェクトsignal、realm realmを指定して次の手順で作成します:
-
requestObjectのrequestをrequestに設定する。
-
requestObjectのheadersを、realmで新しい
Headers
オブジェクト(headers listはrequestのheaders list、guardはguard)に設定する。 -
requestObjectのsignalをsignalに設定する。
-
requestObjectを返す。
new Request(input, init)
コンストラクタの手順は次の通りです:
-
requestをnullに設定する。
-
fallbackModeをnullに設定する。
-
baseURLにthisのrelevant settings objectのAPI base URLを設定する。
-
signalをnullに設定する。
-
inputが文字列なら:
-
それ以外の場合:
-
originにthisのrelevant settings objectのoriginを設定する。
-
traversableForUserPromptsを"
client
"に設定する。 -
requestのtraversable for user promptsがenvironment settings objectであり、そのoriginがoriginと同一オリジンなら、traversableForUserPromptsをrequestのtraversable for user promptsに設定する。
-
init["
window
"]が存在すれば、traversableForUserPromptsを"no-traversable
"に設定する。 -
requestに次のプロパティでrequestを新規作成して設定する:
- URL
- requestのURL
- method
- requestのmethod
- header list
- requestのheader listのコピー
- unsafe-request flag
- セットする
- client
- thisのrelevant settings object
- traversable for user prompts
- traversableForUserPrompts
- internal priority
- requestのinternal priority
- origin
- requestのorigin。オリジンの伝播はサービスワーカーによるナビゲーションリクエスト処理時のみ重要です。この場合リクエストのオリジンが現在のクライアントと異なることがあります。
- referrer
- requestのreferrer
- referrer policy
- requestのreferrer policy
- mode
- requestのmode
- credentials mode
- requestのcredentials mode
- cache mode
- requestのcache mode
- redirect mode
- requestのredirect mode
- integrity metadata
- requestのintegrity metadata
- keepalive
- requestのkeepalive
- reload-navigation flag
- requestのreload-navigation flag
- history-navigation flag
- requestのhistory-navigation flag
- URL list
- requestのURL listのクローン
- initiator type
- "
fetch
"
-
initが空でない場合:
-
requestのmodeが"
navigate
"なら、"same-origin
"に設定する。 -
requestのreload-navigation flagを解除する。
-
requestのhistory-navigation flagを解除する。
-
requestのoriginを"
client
"に設定する。 -
requestのreferrerを"
client
"に設定する。 -
requestのreferrer policyを空文字列に設定する。
-
requestのURLをrequestのcurrent URLに設定する。
サービスワーカーがクロスオリジンスタイルシート中の画像等からリダイレクトしてリクエストを書き換える場合、もはや元のソース(クロスオリジンスタイルシート)から来たようには見えず、リダイレクトしたサービスワーカーから来たと扱われる。元ソースが同種リクエストを生成できない場合があるため、これが重要。元ソースを信頼するサービスが攻撃される恐れもある(稀だが)。
-
-
init["
referrerPolicy
"]が存在すれば、requestのreferrer policyをその値に設定する。 -
modeが"
navigate
"ならTypeError例外を投げる。 -
modeがnullでなければ、requestのmodeをmodeに設定する。
-
init["
credentials
"]が存在すれば、requestのcredentials modeをその値に設定する。 -
init["
cache
"]が存在すれば、requestのcache modeをその値に設定する。 -
requestのcache modeが"
only-if-cached
"かつmodeが"same-origin
"でなければTypeError例外を投げる。 -
init["
redirect
"]が存在すれば、requestのredirect modeをその値に設定する。 -
init["
integrity
"]が存在すれば、requestのintegrity metadataをその値に設定する。 -
-
requestのinternal priorityがnullでなければ、実装定義の方法でinternal priorityを更新する。
-
-
signalsにsignalがnullでなければ« signal »、そうでなければ« »を設定する。
-
thisのsignalをdependent abort signalの作成(signals、
AbortSignal
、thisのrelevant realm)の結果に設定する。 -
thisのheadersを新しい
Headers
オブジェクト(thisのrelevant realm、header listはrequestのheader list、guardは"request
")に設定する。 -
initが空でない場合:
このモードで許可されないヘッダーが含まれる可能性があるためヘッダーをサニタイズする。そうでなければ、以前にサニタイズ済みか特権APIで設定され変更されていない。
-
inputBodyにinputが
Request
オブジェクトならinputのrequestのbody、それ以外ならnullを設定する。 -
init["
body
"]が存在しかつnullでない、またはinputBodyがnullでない場合で、requestのmethodが`GET
`または`HEAD
`ならTypeError例外を投げる。 -
initBodyをnullに設定する。
-
inputOrInitBodyにinitBodyがnullでなければそれを、そうでなければinputBodyを設定する。
-
inputOrInitBodyがnullでなく、そのsourceがnullなら:
-
finalBodyにinputOrInitBodyを設定する。
-
initBodyがnullかつinputBodyがnullでない場合:
method
ゲッターの手順は、thisのrequestのmethodを返すこと。
url
ゲッターの手順は、thisのrequestのURLを直列化して返すこと。
headers
ゲッターの手順は、thisのheadersを返すこと。
destination
ゲッターの手順は、thisのrequestのdestinationを返すこと。
referrer
ゲッターの手順は次の通りです:
referrerPolicy
ゲッターの手順は、thisのrequestのreferrer policyを返すこと。
mode
ゲッターの手順は、thisのrequestのmodeを返すこと。
credentials
ゲッターの手順は、thisのrequestのcredentials modeを返すこと。
cache
ゲッターの手順は、thisのrequestのcache
modeを返すこと。
redirect
ゲッターの手順は、thisのrequestのredirect modeを返すこと。
integrity
ゲッターの手順は、thisのrequestのintegrity metadataを返すこと。
keepalive
ゲッターの手順は、thisのrequestのkeepaliveを返すこと。
isReloadNavigation
ゲッターの手順は、thisのrequestのreload-navigation
flagがセットされていればtrue、そうでなければfalseを返すこと。
isHistoryNavigation
ゲッターの手順は、thisのrequestのhistory-navigation
flagがセットされていればtrue、そうでなければfalseを返すこと。
signal
ゲッターの手順は、thisのsignalを返すこと。
Thisのsignalは常に constructor内および cloning時に初期化されます。
duplex
ゲッターの手順は"half
"を返すこと。
clone()
メソッドの手順は以下の通りです:
-
clonedSignal を « this の signal » から dependent abort signal を作成することにより取得する。使用するのは
AbortSignal
と this の relevant realm である。 -
clonedRequestObject を creating より
Request
オブジェクトとして生成する。与える値は clonedRequest, this の headers の guard, clonedSignal, そして this の relevant realm である。 -
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 = 302); [
status 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 = 200;
status ByteString = "";
statusText HeadersInit ; };
headers enum {
ResponseType ,
"basic" ,
"cors" ,
"default" ,
"error" ,
"opaque" };
"opaqueredirect"
Response
オブジェクトには関連付けられたresponse(response)があります。
Response
オブジェクトには、関連付けられたheaders(nullまたはHeaders
オブジェクト、初期値はnull)があります。
Response
オブジェクトのbodyは、そのresponseのbodyです。
response = new Response(body = null [, init])
-
Response
オブジェクトを生成し、bodyはbody、status・status message・headersはinitで指定されます。 response = Response . error()
-
ネットワークエラーの
Response
オブジェクトを生成します。 response = Response . redirect(url, status = 302)
-
urlへstatusでリダイレクトする
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
response、headers
guard guard、
realm
realm を受け取って以下を実行する:
-
responseObject の response を response に設定する。
-
responseObject の headers を 新しい
Headers
オブジェクト(realm付き)で、headers listは response の headers list、guardは guardに設定する。 -
responseObject を返す。
レスポンスを初期化するには、
Response
オブジェクト response、
ResponseInit
init、null または body with type bodyを受け取って以下を実行する:
-
init["
status
"] が 200 〜 599 の範囲外なら、 RangeError をスローする。 -
init["
statusText
"] が空文字列でない、かつ reason-phrase トークン生成規則に一致しない場合は、 TypeError をスローする。 -
response の response の status message を init["
statusText
"] に設定する。 -
init["
headers
"] exists なら、 fill で response の headers を init["headers
"] で埋める。 -
body が non-null なら:
-
response の status が null body status なら TypeError をスローする。
101と103は null body status に含まれるが、 他で使用されるためこの手順には影響しない。
-
body の type が non-null かつ、 response の header list に `
Content-Type
` が含まれていなければ、 append (`Content-Type
`, body の type) を response の header list に追加する。
-
new Response(body, init)
コンストラクターの手順は以下の通りです:
-
this の headers を new
Headers
オブジェクト(this の relevant realmを持ち、 header listは this の response の header list、 guardは "response
" )に設定する。 -
bodyWithType を null にする。
-
body が null でない場合、bodyWithType を extracting body の結果に設定する。
-
initialize a response を this, init, bodyWithType を与えて実行する。
静的 error()
メソッドの手順は、
新しい network
error、
"immutable
"、
current
realm を与えて 作成した
Response
オブジェクトを返すこと。
静的 redirect(url, status)
メソッドの手順は:
-
parsedURL を パースで url、current settings object の API base URL を使って取得する。
-
parsedURL が failure なら TypeError をスローする。
-
status が redirect status でなければ RangeError をスローする。
-
responseObject を 作成で新しい response、"immutable"、current realm を与えて生成する。
-
append (`
Location
`, value) を responseObject の response の header list に追加する。 -
responseObject を返す。
静的 json(data, init)
メソッドの手順は:
-
bytes を JavaScript値をJSONバイト列へシリアライズで data を処理した結果とする。
-
body を extracting bytes の結果とする。
-
responseObject を 作成で新しい response、"response"、current realm を与えて生成する。
-
レスポンスの初期化を responseObject、init、(body, "
application/json
") で実行する。 -
responseObject を返す。
type
の getter の手順は、this の
response の type を返すことである。
url
の getter の手順は、this の response の URL が null
なら空文字列を返す。
それ以外の場合は this の
response の URL を
serialize し、exclude fragment を true に設定して返す。
redirected
の getter の手順は、
this の response の URL list の size が
1 より大きければ true、そうでなければ false を返すことである。
リダイレクトの結果となる response を除外したい場合は、API を直接使って、
例えば fetch(url, { redirect:"error" })
のようにする。
この方法であれば、潜在的に安全でない response が誤って漏洩することがなくなる。
status
の getter の手順は、
this の response の status を返すことである。
ok
の getter の手順は、
this の response の status が ok status なら true、それ以外は false を返す。
statusText
の getter の手順は、
this の response の status
message を返すことである。
headers
の getter の手順は、
this の headers を返すことである。
clone()
メソッドの手順は以下の通りである:
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 ,SecureContext ]FetchLaterResult fetchLater (RequestInfo ,
input optional DeferredRequestInit = {}); };
init
fetch(input, init)
メソッドの手順は以下の通りです:
-
p を 新しい promise とする。
-
requestObject を
Request
の初期値をコンストラクターとして input と init を引数にして呼び出した結果とする。例外が投げられた場合は、 reject p でその例外を渡し、p を返す。 -
request を requestObject の request とする。
-
もし requestObject の signal が abort されている なら、以下を実行する:
-
fetch() 呼び出しを中止する。引数は p, request, null, そして requestObject の signal の abort reason。
-
p を返す。
-
- globalObject を request の client の global object とする。
-
globalObject が
ServiceWorkerGlobalScope
オブジェクトなら、request の service-workers mode を "none
" に設定する。 -
responseObject を null とする。
-
relevantRealm を this の relevant realm とする。
-
locallyAborted を false とする。
これにより、abort のリクエストが fetch の呼び出し元と同じスレッドから来た場合、promise を予測可能なタイミングで reject できるようになる。
-
controller を null とする。
-
以下の abort 手順を追加する。追加先は requestObject の signal:
-
locallyAborted を true に設定する。
-
Assert: controller は null でない。
-
Abort controller。引数は requestObject の signal の abort reason。
-
fetch() 呼び出しを中止する。引数は p, request, responseObject, そして requestObject の signal の abort reason。
-
-
controller を fetch の呼び出し結果とする。引数は request と processResponse。response には以下の手順を与える:
-
locallyAborted が true なら、これ以降の手順を中止する。
-
response の aborted flag が設定されていたら、以下を実行:
-
deserializedError を serialize された abort reason をデシリアライズする。引数は controller の serialized abort reason と relevantRealm。
-
fetch() 呼び出しを中止する。引数は p, request, responseObject, deserializedError。
-
これ以降の手順を中止する。
-
-
response が network error なら、reject p に
TypeError
を与えて、これ以降の手順を中止する。 -
responseObject を creating で
Response
オブジェクトとして生成する。引数は response, "immutable
", relevantRealm。 -
resolve p に responseObject を与える。
-
-
p を返す。
fetch() 呼び出しを中止する ためには、promise、request、responseObject、error を受け取って以下を実行する:
-
promise を error で拒否する。
すでに promise が解決済みの場合は何もしない(no-op)。
-
もし request の body が non-null かつ readable なら、 cancel で request の body を error でキャンセルする。
-
responseObject が null なら return する。
-
response を responseObject の response とする。
-
もし response の body が non-null かつ readable なら、 error で response の body を error でエラー化する。
FetchLaterResult
には関連付けられたactivated getter steps(booleanを返すアルゴリズム)があります。
activated
の getter の手順は、
this の activated getter steps を実行した結果を返すことである。
fetchLater(input, init)
メソッドの手順は以下の通りである:
-
requestObject を
Request
の初期値をコンストラクターとして input および init を引数に呼び出した結果とする。 -
requestObject の signal が abort されている 場合、 signal の abort reason を投げる。
-
request を requestObject の request とする。
-
activateAfter を null とする。
-
init が与えられていて、かつ init["
activateAfter
"] が存在する場合、activateAfter を init["activateAfter
"] に設定する。 -
activateAfter が 0 より小さい場合、
RangeError
を投げる。 -
this の relevant global object の associated document が fully active でないなら、
TypeError
を投げる。 -
request の URL の scheme が HTTP(S) scheme でない場合、
TypeError
を投げる。 -
request の URL が potentially trustworthy URL でない場合、
TypeError
を投げる。 -
request の body が null でなく、かつ request の body の length が null なら、
TypeError
を投げる。body が
ReadableStream
オブジェクトである場合、deferred にすることはできない。 -
available deferred-fetch quota(引数は request の client および request の URL の origin)が request の total request length より小さい場合、 "
QuotaExceededError
"DOMException
を投げる。 -
activated を false とする。
-
deferredRecord を queue a deferred fetch(引数は request, activateAfter, および次の手順: activated を true に設定する)を呼び出した結果とする。
-
以下の abort 手順を追加する。追加先は requestObject の signal: deferredRecord の invoke state を "
aborted
" に設定する。 -
新しい
FetchLaterResult
を返す。その activated getter steps は activated を返すものとする。
次の呼び出しは、ドキュメントが終了したときにフェッチされるリクエストをキューします:
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" );
5.7. ガベージコレクション
ユーザーエージェントは、スクリプトから観測できない場合、進行中のfetchを終了してもよい。
「スクリプトから観測できる」とは、fetch()
の引数と戻り値で観測できることを意味します。それ以外の方法(サーバーとのサイドチャネル通信など)は含みません。
サーバーがガベージコレクションを観測できる例は既に存在します。例えば
WebSocket
や XMLHttpRequest
オブジェクトなどです。
ユーザーエージェントは、終了が観測できないため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を受け取り、次の手順を実行します:
-
inputにURL直列化(dataURL、exclude fragmentをtrue)した結果を設定する。
-
inputの先頭の"
data:
"を削除する。 -
positionをinputの最初に設定する。
-
mimeTypeにpositionからU+002C(,)以外のコードポイントを収集した結果を設定する。
-
先頭・末尾のASCII空白をmimeTypeから除去する。
これによりU+0020 SPACEコードポイントのみが削除されます(ある場合)。
-
positionがinputの終端を超えていれば失敗を返す。
-
positionを1進める。
-
encodedBodyにinputの残り部分を設定する。
-
bodyにencodedBodyのパーセントデコード結果を設定する。
-
mimeTypeがU+003B(;)で終わり、その後ゼロ個以上のU+0020 SPACE、さらにASCII大文字小文字無視で"
base64
"が続く場合、次を実行:-
stringBodyにbodyのisomorphic decode結果を設定する。
-
bodyにstringBodyのforgiving-base64 decode結果を設定する。
-
bodyが失敗なら失敗を返す。
-
mimeTypeから最後の6つのコードポイントを削除する。
-
mimeTypeから末尾のU+0020 SPACEコードポイントを削除する(あれば)。
-
mimeTypeから最後のU+003B(;)を削除する。
-
-
mimeTypeが"
;
"で始まるなら、"text/plain
"を先頭に追加する。 -
mimeTypeRecordにMIMEタイプをパース(mimeType)の結果を設定する。
-
mimeTypeRecordが失敗なら
text/plain;charset=US-ASCII
に設定する。 -
新しい
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リダイレクトのアトミックな取り扱い
リダイレクト(response の status または internal 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
など)にリソースを共有できます。
これはcurl
やwget
と同様です。
言い換えれば、リソースがWeb上の任意のデバイスからcurl
やwget
でアクセスできない場合、上記のヘッダーは含めるべきではありません。アクセスできる場合は問題ありません。
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
オブジェクトは特殊な種類の
フェッチ(request の mode が "websocket
"
であるリクエストを使う)を開始します。これにより、多くのフェッチポリシーの判断(例えば HTTP Strict Transport Security (HSTS)
など)を共有できます。最終的に、フェッチは WebSockets に呼び出され、専用の接続を取得することになります。[WEBSOCKETS]
[HSTS]
フェッチは以前、WebSocket の接続を取得するや WebSocket 接続を確立する を直接定義していましたが、現在はどちらも WebSockets で定義されています。[WEBSOCKETS]
他の標準での fetch の利用
本質的に フェッチは request と response の交換です。実際には、標準で正しく採用・利用するにはかなり複雑な仕組みです。この節ではそのための助言を提供します。
必ずドメインの専門家にレビューを依頼してください。
この仕様は作業中です。
リクエストの準備
フェッチの最初のステップは request を作成し、 各種項目を設定することです。
まず request の URL と method を
HTTP の定義に従って設定します。もし `POST
` や `PUT
` の request がボディを必要とする場合は、
request の
body を バイト列または、
body(その stream が自作の ReadableStream
)に設定します。[HTTP]
request の
destination を destination
table のガイダンスに従って選択してください。destination は
Content Security Policy
に影響し、`Sec-Fetch-Dest
`
ヘッダーなど他にも重要な意味があります。新機能で destination が destination
table に無い場合は
issue
を提出して議論してください。[CSP]
request の
client を
操作対象の
environment settings object に設定します。
Web に公開される API は一般に Web IDL で定義されますが、そこでは interface
を実装する各オブジェクトが
relevant settings object を持ちます。例えば、request が
element に紐づく場合は、その request の client はその要素の
node document の relevant settings object になります。JavaScript、HTML、CSS、その他 Document
サブリソースから直接公開される機能は、必ず client を持つべきです。
もし フェッチ が直接 Web
から公開されていない場合(例:現在の Window
や Worker
に依存せず、バックグラウンドで送信する場合)は、
request の
client を
null のままにし、
request の origin、
policy container、service-workers
mode、
referrer を適切な値に設定してください(例えば事前に environment settings object
からコピー)。こうした高度なケースでは、Content Security Policy や
referrer policy の扱いを明確にしてください。また、コールバック(フェッチ呼び出しとレスポンス処理参照)が
parallel queue でポストされるため、並行処理も考慮しましょう。[REFERRER] [CSP]
クロスオリジンリソースをどのように扱うかも検討してください。ある機能が 同一オリジンでのみ動作する場合は
request の mode を
"same-origin
" に設定します。それ以外は、Web公開機能の場合はほぼ常に
mode を
"cors
" にすべきです。Web公開ではない場合や CORS を使わずにクロスオリジンリソースをフェッチしたい場合は、
issue
で議論してください。
クロスオリジンリクエストの場合、credentials
を含めるかどうかも決定します。含める場合は
request の credentials mode を
"include
" に設定します。
フェッチを Resource Timing に報告する必要がある場合や、どの initiator type で報告するかも考えてください。 initiator type を request に渡すことで、 フェッチ完了時に Resource Timing への自動報告が行われます(レスポンスが完全にダウンロードされたとき)。[RESOURCE-TIMING]
追加の HTTP ヘッダーが必要な場合は、header list を
必要なヘッダーを含む header
list に設定してください。例えば « (`My-Header-Name
`,
`My-Header-Value
`) » のように。カスタムヘッダーの送信は CORSプリフライトフェッチ を要求する場合があるので注意してください。
デフォルトのキャッシュ機構を上書きしたい場合、例えばこの request のキャッシュを無効にしたい場合は、
cache
mode を "default
" 以外に設定してください。
リクエストがリダイレクトを許容するかどうかも決めてください。許容しない場合は
redirect mode を "error
" に設定します。
request の他のパラメータも確認し、必要であれば参照してください。これらは特殊用途で使われることが多く、§ 2.2.5 Requests セクションで詳しく説明されています。
fetch の呼び出しとレスポンス処理
request の他に fetch 操作は複数のオプション引数を取ります。アルゴリズムを取る引数の場合、そのアルゴリズムはタスク(または parallel queue、useParallelQueue が true の場合)から呼び出されます。
request をセットアップしたら、 fetch にどのアルゴリズムを渡すか決め、 response のどの段階でコールバックを受け取りたいかを決定してください:
- 完了時
-
ほとんどの呼び出し元は response をこのように処理します(例:スクリプトや スタイルリソース)。response の body をすべて バイト列として読み取り、その後呼び出し元で処理します。
完了時に response を処理するには、processResponseConsumeBody 引数にアルゴリズムを渡して fetch を呼び出します。渡されたアルゴリズムには response と、完全に読み取られた body(response の internal response のもの)を表す引数が渡されます。第2引数の意味は次の通りです:
- null
- response の body が null である場合は、 レスポンスが ネットワークエラー であるか、null body status であるためです。
- failure
- 内容を完全に読み取る 試みが response の body に対して失敗した場合(例えば I/O エラーによるもの)です。
- バイト列
-
内容を完全に読み取ることが response の internal response の body で成功した場合です。
バイト列には完全な内容が含まれており、 request の mode が "
no-cors
" であっても渡されます。呼び出し元はその内容を扱う際に注意する必要があります。リクエスト元の オリジン からアクセスできないようにすべきです。例えば、呼び出し元は "no-cors
" response の内容をユーザーに直接画像として表示することはできますが、 その画像内容は埋め込みドキュメントのスクリプトから直接アクセスされるべきではありません。
-
request を request(URL が
https://stuff.example.com/
、client が this の relevant settings object)とする。 -
fetch で request を呼び出し、processResponseConsumeBody に次の手順を渡す( response response と null/failure/バイト列 contents を受け取る):
-
contents が null または failure なら、ユーザーにエラーを表示する。
-
それ以外なら contents を response のメタデータを考慮してパースし、独自処理を行う。
-
- まずヘッダー、次にチャンクごと
-
動画再生や画像の漸進的ロードなど、呼び出し元がレスポンスをチャンクごとにストリーム処理したい場合もあります。この場合 response は ヘッダー受信後に呼び出し元に渡され、以降は呼び出し元が処理を継続します。
チャンクごとに response を処理するには、processResponse 引数にアルゴリズムを渡して fetch を呼び出します。渡されたアルゴリズムには レスポンスヘッダー受信時に response が渡され、以降は response の body の stream を自分でダウンロード処理します。また、便利のため processResponseEndOfBody 引数にもアルゴリズムを渡せます(完全に読み取り終わったときに呼ばれる)。ただし processResponseConsumeBody と違い、 processResponse や processResponseEndOfBody を使っても、 レスポンスが完全に読み取られる保証はありません。呼び出し元が責任を持って読み取る必要があります。
processResponse 引数は、 response の header list や status のみを処理したい場合にも有用です(例:ok status でないレスポンスなど)。
-
request を request(URL が
https://stream.example.com/
、client が this の relevant settings object)とする。 -
fetch で request を呼び出し、processResponse に次の手順を渡す( response response を受け取る):
-
response が network error なら、ユーザーにエラーを表示する。
-
それ以外の場合、reader を取得し、 response の body の stream を MIME タイプ(extracting a MIME type)に応じて処理する。
-
-
- レスポンスを無視
-
場合によっては response が不要なこともあります(例:
navigator.sendBeacon()
)。 レスポンス処理やコールバック渡しは任意なので、コールバックを省略すれば fetch はレスポンス不要で実行されます。この場合 response の body の stream は破棄され、 無駄に内容をダウンロードする心配はありません。fetch で request(URL が
https://fire-and-forget.example.com/
、method が `POST
`、client が this の relevant settings object)を呼び出す。
レスポンス処理用コールバック以外にも、fetch には高度なケース用の追加コールバックがあります。processEarlyHintsResponse は特に response の status が 103 の場合に使われ、現在はナビゲーションのみ対応しています。processRequestBodyChunkLength や processRequestEndOfBody はリクエストボディアップロード進捗を通知します。
fetch 操作は呼び出し元と同じスレッドで開始され、以降は内部処理が 並行して動きます。上記コールバックは、デフォルトで イベントループ(通常は client の global object)にポストされます。自分でメインスレッドとのやり取りを処理したい場合は、 fetch の useParallelQueue を true に設定してください。
進行中の fetch の操作
すでに開始された fetch 操作を操作するには、 fetch 呼び出しで返される fetch controller を使います。例えば、ユーザーやページのロジックで abort したり、 ブラウザ内部の事情で terminate することができます。
terminate や abort 以外にも、タイミングの報告 や
initiator
type を渡していない場合の報告、
完全なタイミング情報の取得(ナビゲーションのみ)なども可能です。
fetch controller は
次の手動リダイレクトの処理にも使われます(
request の
redirect 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 に基づきライセンスされます。
これは現行標準です。 特許審査版に関心がある場合は 現行標準レビュー草案を参照してください。