URL

現行標準 — 最終更新

参加方法:
GitHub whatwg/url (新しい課題, 未解決の課題)
Matrixでチャット
コミット:
GitHub whatwg/url/commits
このコミット時点のスナップショット
テスト:
web-platform-tests url/ (進行中の作業)
翻訳 (参考情報):
日本語
简体中文
한국어

概要

URL標準は、URL、ドメイン、IPアドレス、application/x-www-form-urlencoded形式、およびそれらのAPIを定義します。

目標

URL標準は、URLの完全な相互運用性を実現するため、以下のアプローチを取ります:

編集者が本件について知識を深めるにつれ、目標の範囲が広がる可能性があります。

1. 基盤

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

本仕様で使われるいくつかの用語は、以下の標準・仕様書で定義されています:


整数を直列化するには、可能な限り短い10進数で表現します。

1.1. 記述

バリデーションエラーは、入力が有効な入力と一致しないことを示します。ユーザーエージェント、特に適合性チェッカーは、これをどこかに報告することが推奨されます。

バリデーションエラーが発生しても、パーサーが終了するわけではありません。パーサーの終了は、常に明示的に(例えばreturn文によって)記述されます。

バリデーションエラーを通知することは有用です。なぜなら、エラー処理は直感的でない場合があり、古いユーザーエージェントが正しいエラー処理を実装していないこともあり、記述の意図が他の開発者にとって不明瞭である可能性があるためです。

エラーの種類 エラーの説明 失敗
IDNA
domain-to-ASCII

Unicode ToASCII は、CheckHyphens、 UseSTD3ASCIIRules、および VerifyDnsLength がすべて true に設定されている場合にエラーを記録する。[UTS46]

Unicode ToASCII エラーの詳細が 記録されている場合、ユーザーエージェントにはそれらを渡すことが推奨される。

URL が 特殊である場合、 ホストは処理される前に パーセントデコードされる。これにより、 以下のホスト部分は "exa#mple.org" になり、その結果このエラーが発生する。

"https://exa%23mple.org"

Yes
(beStrict が true の場合、または domain が ASCII 文字列ではなく、緩和された パラメーターでの Unicode ToASCII も失敗した場合)
ホストの構文解析
domain-percent-encoded

ドメインとして処理される入力の host に、 パーセントエンコードされたバイトが含まれる。

"https://exam%70le.org"

·
host-invalid-code-point

(特殊でない URL 内の)opaque host に、 禁止されたホストコードポイントが含まれる。

"foo://exa[mple.org"

Yes
IPv4-empty-part

IPv4 アドレスが U+002E (.) で終わる。

"https://127.0.0.1./"

·
IPv4-too-few-parts

IPv4 アドレスの 部分が 4 個未満である。

"https://1.2.3/"

·
IPv4-too-many-parts

IPv4 アドレスの 部分が 4 個を超えている。

"https://1.2.3.4.5/"

Yes
IPv4-non-numeric-part

IPv4 アドレスの 部分が数値ではない。

"https://test.42"

Yes
IPv4-non-decimal-part

IPv4 アドレスに、 16 進または 8 進の数字で表された数値が含まれる。

"https://127.0.0x0.1"

·
IPv4-out-of-range-part

IPv4 アドレスの 部分が 255 を超えている。

"https://255.255.4000.1"

Yes
(最後の部分に適用される場合のみ)
IPv4-non-ASCII-input

IPv4 アドレスが、 IDNA 処理を通じて非 ASCII 文字列から導出されている。

"https://①.②.③.④"

·
IPv6-unclosed

IPv6 アドレスに、 閉じる U+005D (]) がない。

"https://[::1"

Yes
IPv6-invalid-compression

IPv6 アドレスが 不適切な圧縮で始まっている。

"https://[:1]"

Yes
IPv6-too-many-pieces

IPv6 アドレスに 8 個を超える piece が含まれる。

"https://[1:2:3:4:5:6:7:8:9]"

Yes
IPv6-multiple-compression

IPv6 アドレスが 複数の箇所で圧縮されている。

"https://[1::1::1]"

Yes
IPv6-invalid-code-point

IPv6 アドレスに、 ASCII 16 進数字 でも U+003A (:) でもないコードポイントが含まれる。または、予期せず終了している。

"https://[1:2:3!:4]"

"https://[1:2:3:]"

Yes
IPv6-too-few-pieces

圧縮されていない IPv6 アドレスに含まれる piece が 8 個未満である。

"https://[1:2:3]"

Yes
IPv6-piece-leading-zero

IPv6 アドレスの piece に先頭の U+0030 (0) が含まれる。

"https://[::01]"

·
IPv4-in-IPv6-too-many-pieces

IPv6 アドレスが IPv4 アドレス構文を伴う場合:IPv6 アドレスに 6 個を超える piece がある。

"https://[1:1:1:1:1:1:1:127.0.0.1]"

Yes
IPv4-in-IPv6-invalid-code-point

IPv6 アドレスが IPv4 アドレス構文を伴う場合:

  • IPv4 部分が空である、または非 ASCII 数字を含む。
  • IPv4 部分に先頭の 0 が含まれる。
  • IPv4 部分が多すぎる。

"https://[ffff::.0.0.1]"

"https://[ffff::127.0.xyz.1]"

"https://[ffff::127.0xyz]"

"https://[ffff::127.00.0.1]"

"https://[ffff::127.0.0.1.2]"

Yes
IPv4-in-IPv6-out-of-range-part

IPv6 アドレスが IPv4 アドレス構文を伴う場合:IPv4 部分が 255 を超えている。

"https://[ffff::127.0.0.4000]"

Yes
IPv4-in-IPv6-too-few-parts

IPv6 アドレスが IPv4 アドレス構文を伴う場合:IPv4 アドレスに含まれる 部分が少なすぎる。

"https://[ffff::127.0.0]"

Yes
URL の構文解析
invalid-URL-unit

URL unit ではないコードポイントが見つかった。

"https://example.org/>"

" https://example.org "

"ht
tps://example.org
"

"https://example.org/%s"

·
special-scheme-missing-following-solidus

入力の scheme の後に "//" が続いていない。

"file:c:/my-secret-folder"

"https:example.org"

const url = new URL("https:foo.html", "https://example.org/");
·
missing-scheme-non-relative-URL

入力に scheme がない。これは、入力が ASCII alpha で始まらず、かつ base URL が提供されていない、 または base URL に opaque path があるため base URL として 使用できない場合である。

入力の scheme がなく、base URL が与えられていない:

const url = new URL("💩");

入力の scheme はないが、base URL に opaque path がある。

const url = new URL("💩", "mailto:user@example.org");
Yes
invalid-reverse-solidus

URL が special scheme を持ち、U+002F (/) の代わりに U+005C (\) を使用している。

"https://example.org\path\to\file"

·
invalid-credentials

入力が 資格情報を含んでいる。

"https://user@example.org"

"ssh://user@example.org"

·
host-missing

入力が special scheme を持つが、host を含まない。

"https://#fragment"

"https://:443"

"https://user:pass@"

Yes
port-out-of-range

入力の port が大きすぎる。

"https://example.org:70000"

Yes
port-invalid

入力の port が無効である。

"https://example.org:7z"

Yes
file-invalid-Windows-drive-letter

入力は relative-URL string であり、Windows ドライブ文字で始まり、 かつ base URL の scheme が "file" である。

const url = new URL("/c:/path/to/file", "file:///c:/");
·
file-invalid-Windows-drive-letter-host

file: URL の host が Windows ドライブ文字である。

"file://c:"

·

1.2. パーサー

EOFコードポイントは、文字列やコードポイント列の終端を示す概念的なコードポイントです。

文字列 inputのポインターは、input内のコードポイントを指す整数です。初期値はinputの先頭を指します。−1の場合はどこも指していません。inputのコードポイント長以上の場合、EOFコードポイントを指します。

ポインターが使われるとき、cはコードポイントのうち、ポインターが指すものを参照します(どこも指していない場合を除く)。ポインターがどこも指していない場合、cは使用できません。

ポインターが使われるとき、remainingは、コードポイント部分文字列(ポインター+1から末尾まで)を参照します。ただし、cがEOFコードポイントでない場合のみです。 cがEOFコードポイントの場合、remainingは使用できません。

「mailto:username@example」が処理中の文字列で、ポインターが@を指している場合、cはU+0040(@)、remainingは「example」です。

空文字列を処理していて、ポインターが先頭を指し、その後1減らされた場合、cやremainingを使用するのはエラーです。

1.3. パーセントエンコードされたバイト

パーセントエンコードされた バイトとは、U+0025 (%) に 2 つの ASCII 16 進数字が続く文字列である。

パーセントエンコードされたバイトの並びは、 一般に、パーセント復号された後に BOM なしで UTF-8 復号または失敗に渡されたとき、 failure にならないようにするのがよい考えである。これがどの程度重要かは、 パーセントエンコードされたバイトがどこで使われるかによって異なる。例えば、ホストパーサーでは この助言に従わないことは致命的である。一方、URL レンダリングでは、 パーセントエンコードされた バイトはパーセント復号されてレンダリングされることはない。

byte byteをパーセントエンコードするには、U+0025 (%) の後にbyteを表す2つのASCII大文字16進数字を付けた文字列を返します。

バイト列inputをパーセントデコードするには、以下の手順を実行します:

inputにASCIIバイト以外のバイトが含まれている場合、BOMなしUTF-8デコード以外を使うのはセキュリティ的に推奨されません。

  1. outputを空のバイト列とする。

  2. inputの各バイトbyteについて:

    1. byteが0x25(%)でなければ、byteをoutputに追加する。

    2. そうでなく、byteが0x25(%)かつinputの次の2バイトが0x30(0)~0x39(9)、0x41(A)~0x46(F)、0x61(a)~0x66(f)のいずれにも該当しない場合、byteをoutputに追加する。

    3. それ以外の場合:

      1. bytePointをinputのbyteの次の2バイトを等価デコードし、16進数として解釈した値とする。

      2. bytePointの値のバイトをoutputに追加する。

      3. inputの次の2バイトをスキップする。

  3. outputを返す。

スカラー値文字列 inputをパーセントデコードするには:

  1. inputのUTF-8エンコーディングをbytesとする。

  2. bytesをパーセントデコードした結果を返す。

一般に、パーセントエンコードの結果は入力よりU+0025(%)が多い文字列となり、パーセントデコードの結果は入力より0x25(%)が少ないバイト列となります。


パーセントエンコード集合は、集合であり、符号点からなる。

C0 コントロールパーセントエンコード集合は、 パーセントエンコード集合であり、 C0 コントロールと U+007E (~) より大きいすべての符号点からなる。

フラグメント パーセントエンコード集合は、 パーセントエンコード集合であり、 C0 コントロールパーセントエンコード集合 と U+0020 SPACE, U+0022 ("), U+003C (<), U+003E (>), U+0060 (`) からなる。

クエリ パーセントエンコード集合は、 パーセントエンコード集合であり、 C0 コントロールパーセントエンコード集合と U+0020 SPACE, U+0022 ("), U+0023 (#), U+003C (<), U+003E (>) からなる。

クエリ パーセントエンコード集合は フラグメント パーセントエンコード集合から U+0060 (`) を除いて定義することはできない。

スペシャルクエリ パーセントエンコード集合は、 パーセントエンコード集合であり、 クエリ パーセントエンコード集合 と U+0027 (') からなる。

パス パーセントエンコード集合は、 パーセントエンコード集合であり、 クエリ パーセントエンコード集合 と U+003F (?), U+005E (^), U+0060 (`), U+007B ({), U+007D (}) からなる。

ユーザー情報パーセントエンコード集合は、 パーセントエンコード集合であり、 パス パーセントエンコード集合と U+002F (/), U+003A (:), U+003B (;), U+003D (=), U+0040 (@), U+005B ([) から U+005D (]) まで、U+007C (|) からなる。

コンポーネント パーセントエンコード集合は、 パーセントエンコード集合であり、 ユーザー情報パーセントエンコード集合 と U+0024 ($) から U+0026 (&) まで、U+002B (+)、U+002C (,) からなる。

これは HTML の registerProtocolHandler() で使われ、他の標準で URL の パス、クエリ、 フラグメント または opaque host に埋め込むためにデータをパーセントエンコードする際にも使われる可能性がある。 UTF-8 パーセントエンコード と組み合わせて使うことで JavaScript の encodeURIComponent() [sic] と同じ結果になる。[HTML] [ECMA-262]

application/x-www-form-urlencoded パーセントエンコード集合は、 パーセントエンコード集合であり、 コンポーネント パーセントエンコード集合と U+0021 (!), U+0027 (') から U+0029 RIGHT PARENTHESIS まで、U+007E (~) からなる。

application/x-www-form-urlencoded パーセントエンコード集合 は すべての符号点(ASCII 英数字、 U+002A (*)、U+002D (-)、U+002E (.)、および U+005F (_) を除く)を含む。

エンコード後パーセントエンコードするには、エンコーディング encoding、スカラ値文字列 input、そして パーセントエンコード集合 percentEncodeSet が与えられたとき:

  1. アサート:encoding は UTF-8 であるか、 percentEncodeSet は スペシャルクエリ パーセントエンコード集合 または application/x-www-form-urlencoded パーセントエンコード集合である。

  2. percentEncodeSet が application/x-www-form-urlencoded パーセントエンコード集合なら spaceAsPlus を true とし、そうでなければ false とする。

  3. encoder を、エンコーダ取得を encoding に対して実行した結果とする。

  4. inputQueue を、input を I/O キュー に変換したものとする。

  5. output を空文字列とする。

  6. potentialError を 0 とする。

    これは後続の while ループを開始するために非 null 値である必要がある。

  7. potentialError が non-null である間、次を繰り返す:

    1. encodeOutput を空の I/O キューとする。

    2. potentialError を エンコードまたは失敗を inputQueue, encoder, encodeOutput で実行した結果とする。

    3. encodeOutput をバイト列に変換した各 byte について次を行う:

      1. spaceAsPlus が true で byte が 0x20 (SP) なら、 U+002B (+) を output に追加し、 続行する。

      2. isomorph を、符号点で 値 が byte の 値 であるものとする。

      3. アサート:percentEncodeSet はすべての非ASCII 符号点を含む。

      4. isomorph が percentEncodeSet に含まれていなければ、 isomorph を output に追加する。

      5. そうでなければ、パーセントエンコードを byte に実行し、 結果を output に追加する。

    4. potentialError が non-null なら、"%26%23"、続いて ASCII 数字 による potentialError の 10 進表現の最短列、"%3B" を output に追加する。

      これは encoding が UTF-8 でない場合に起こり得る。

  8. output を返す。

引数 percentEncodeSet の値のうち、U+0025 (%) をエンコードし“ラウンドトリップ可能なデータ”を生成するのは コンポーネント パーセントエンコード集合 と application/x-www-form-urlencoded パーセントエンコード集合 の 2 つだけである。他の値(URL パーサー が利用するもの)では U+0025 (%) を残し、 適切に表現するには先に UTF-8 パーセントエンコード する必要がある。

UTF-8 パーセントエンコードするには、 スカラ値 scalarValue、 percentEncodeSet を使い、エンコード後パーセントエンコードを UTF-8、 scalarValue を 文字列とし、 percentEncodeSet で実行した結果を返す。

UTF-8 パーセントエンコードするには、 スカラ値文字列 inputと percentEncodeSet を使い、 エンコード後パーセントエンコードを UTF-8、input、percentEncodeSet で実行した結果を返す。


上記で定義した操作の例によるまとめを示す:

操作 入力 出力
パーセントエンコード input 0x23 "%23"
0x7F "%7F"
パーセントデコード input `%25%s%1G` `%%s%1G`
パーセントデコード input "‽%25%2E" 0xE2 0x80 0xBD 0x25 0x2E
エンコード後パーセントエンコード ( Shift_JIS, input, スペシャルクエリ パーセントエンコード集合 ) " " "%20"
"≡" "%81%DF"
"‽" "%26%238253%3B"
エンコード後パーセントエンコード (ISO-2022-JP, input, スペシャルクエリ パーセントエンコード集合) "¥" "%1B(J\%1B(B"
エンコード後パーセントエンコード (Shift_JIS, input, application/x-www-form-urlencoded パーセントエンコード集合) "1+1 ≡ 2%20‽" "1%2B1+%81%DF+2%2520%26%238253%3B"
UTF-8 パーセントエンコード input (ユーザー情報パーセントエンコード集合) U+2261 (≡) "%E2%89%A1"
U+203D (‽) "%E2%80%BD"
UTF-8 パーセントエンコード input (ユーザー情報パーセントエンコード集合) "Say what‽" "Say%20what%E2%80%BD"

2. セキュリティの考慮事項

URLのセキュリティは、その環境によって左右されます。URLの表示、解釈、受け渡し時には注意が必要です。

URLの表示や新規割り当ての際には「なりすまし」に注意する必要があります。すなわち、あるホストやURLが別のものと誤認される攻撃です。たとえば、1/l/I、m/rn/rri、0/O、а/aが酷似して見える場合や、U+202A LEFT-TO-RIGHT EMBEDDINGなど不可視コードポイントが使われる場合などです。 [UTR36]

あるURLを当事者AからBに渡すとき、両者は何が起こるか慎重に検討する必要があります。Aは意図しないデータを漏洩してしまうかもしれず、Bは予期しない入力を受けて利用者に害を及ぼす行動を取る可能性があります。特に、BはAを決して信用してはなりません。なぜなら、AからのURLが信頼できないソース由来となることがあるためです。

3. ホスト(ドメインおよびIPアドレス)

概略として、ホスト、有効なホスト文字列、ホストパーサー、ホストシリアライザーの関係は以下の通りです:

パースとシリアライズのラウンドトリップの結果は、ホストパーサーのisOpaque引数に応じて次のようになります:

入力 出力 (isOpaque = false) 出力 (isOpaque = true)
EXAMPLE.COM example.com (ドメイン) EXAMPLE.COM (不透明ホスト)
example%2Ecom example%2Ecom (不透明ホスト)
faß.example xn--fa-hia.example (ドメイン) fa%C3%9F.example (不透明ホスト)
0 0.0.0.0 (IPv4) 0 (不透明ホスト)
%30 %30 (不透明ホスト)
0x 0x (不透明ホスト)
0xffffffff 255.255.255.255 (IPv4) 0xffffffff (不透明ホスト)
[0:0::1] [::1] (IPv6)
[0:0::1%5D 失敗
[0:0::%31]
09 失敗 09 (不透明ホスト)
example.255 example.255 (不透明ホスト)
example^example 失敗

3.1. ホストの表現

ホストは、ドメイン、IPアドレス、不透明ホスト、または空ホストです。通常、ホストはネットワークアドレスとして機能しますが、ネットワークアドレスが不要なURLにおいて不透明識別子として使われることもあります。

典型的なURLで、ホストが不透明ホストなのは git://github.com/whatwg/url.gitです。

以下で参照されるRFCは参考情報であり、ホストの記述・解析・直列化に影響しません(後続のセクションで特に記載がない限り)。

ドメインは、ネットワーク内の領域を識別する非空のASCII文字列です。[RFC1034]

ドメイン domainのドメインラベルは、domainをU+002E(.)で厳密分割した結果です。

example.comとexample.com.というドメインは等価ではなく、通常区別されます。

IPアドレスはIPv4アドレスまたはIPv6アドレスです。

IPv4アドレスは32ビット符号なし整数でネットワークアドレスを識別します。[RFC791]

IPv6アドレスは128ビット符号なし整数でネットワークアドレスを識別します。この整数は、8つの16ビット符号なし整数からなるリストで構成され、IPv6アドレスのピースとも呼ばれます。[RFC4291]

<zone_id>のサポートは意図的に除外されています。

不透明ホストは、さらなる処理に使用できる非空のASCII文字列です。

空ホストは空文字列です。

3.2. ホストその他

禁止ホストコードポイントは、U+0000(NULL)、U+0009(TAB)、U+000A(LF)、U+000D(CR)、U+0020(スペース)、U+0023(#)、U+002F(/)、U+003A(:)、U+003C(<)、U+003E(>)、U+003F(?)、U+0040(@)、U+005B([)、U+005C(\)、U+005D(])、U+005E(^)、U+007C(|)です。

禁止ドメインコードポイントは、禁止ホストコードポイント、C0コントロール、U+0025(%)、U+007F(DELETE)です。

ホスト hostのパブリックサフィックスを取得するには、以下の手順を実行します。これはnullまたはPublic Suffix Listに含まれるhostの一部を表すドメインを返します。[PSL]

  1. hostがドメインでなければ、nullを返す。

  2. hostが「.」で終わるならtrailingDotを「.」、そうでなければ空文字列とする。

  3. publicSuffixをPublic Suffix Listアルゴリズムでhostをドメインとして実行した結果とする。[PSL]

  4. Assert:publicSuffix は、ASCII文字列であり、最後が trailingDot である。

  5. publicSuffix を返す。

ホスト hostの登録可能ドメインを取得するには、以下の手順を実行します。これはnullまたはhostのパブリックサフィックスとその直前のドメインラベルから構成されるドメインを返します。

  1. hostのパブリックサフィックスがnull、またはhostのパブリックサフィックスがhostと等価なら、nullを返す。

  2. hostが「.」で終わるならtrailingDotを「.」、そうでなければ空文字列とする。

  3. registrableDomainをPublic Suffix Listアルゴリズムでhostをドメインとして実行した結果とする。[PSL]

  4. Assert:registrableDomain は、ASCII文字列であり、最後が trailingDot である。

  5. registrableDomain を返す。

ホスト入力 パブリックサフィックス 登録可能ドメイン
com com null
example.com com example.com
www.example.com com example.com
sub.www.example.com com example.com
EXAMPLE.COM com example.com
example.com. com. example.com.
github.io github.io null
whatwg.github.io github.io whatwg.github.io
إختبار xn--kgbechtv null
example.إختبار xn--kgbechtv example.xn--kgbechtv
sub.example.إختبار xn--kgbechtv example.xn--kgbechtv
[2001:0db8:85a3:0000:0000:8a2e:0370:7334] null null

仕様はセキュリティ判断のためオリジン概念を優先すべきです。「パブリックサフィックス」や「登録可能ドメイン」は堅固なセキュリティ境界を提供できません。パブリックサフィックスリストはクライアントごとに異なります。これを無視する仕様は、URLのスキームを判断に組み込むべきか慎重に検討してください。例えばsame siteやschemelessly same site概念を使うかどうかなどです。

3.3. IDNA

ドメイン パーサーアルゴリズムは、 スカラー値文字列 domain と真偽値 beStrict が与えられたとき、次の 手順を実行する。これらは failure またはドメインを返す。

  1. strictResult を、domain および true で domain parser ToASCII を実行した結果とする。

  2. strictResult が failure 値である場合、domain-to-ASCII 検証 エラーとする。この手順は return しない。

  3. beStrict が true の場合:

    1. strictResult が failure 値である場合、failure を返す。

    2. strictResult を返す。

  4. result を null とする。

  5. domain が ASCII 文字列である場合、result を domain を小文字化したものに設定する。

    beStrict が false で、domain が ASCII 文字列である場合、 このアルゴリズムはウェブ互換性のため、 Unicode ToASCII の結果にかかわらず、 domain を小文字化して返す。 IgnoreInvalidPunycode だけでは十分ではない。Punycode は正常に復号できても、 なお妥当性基準に失敗することがあるためである。例えば、xn--8i7caa は www に復号されるが、 その符号位置のステータスは "mapped" である。[UTS46]

  6. そうでない場合:

    1. result を、domain および false で domain parser ToASCII を実行した結果に設定する。

    2. result が failure 値である場合、failure を返す。

  7. result が空文字列である場合、failure を返す。

  8. result が禁止されたドメイン符号位置を含む場合、failure を返す。

    ウェブ互換性、および DNS ベースではないシステムとの互換性のため、 禁止されたドメイン符号位置は、 UseSTD3ASCIIRules が true のときに許可されないものの部分集合である。issue #397 も参照。

  9. result を返す。

この文書、およびウェブプラットフォーム全体では、 IDNA2008 ではなく Unicode IDNA Compatibility Processing を使用する。例えば、 ☕.example は failure ではなく xn--53h.example になる。[UTS46] [RFC5890]

domain parser ToASCII アルゴリズムは、スカラー 値文字列 domain と真偽値 beStrict が与えられたとき、 domain_name を domain に設定し、 CheckHyphens を beStrict に、CheckBidi を true に、CheckJoiners を true に、UseSTD3ASCIIRules を beStrict に、Transitional_Processing を false に、VerifyDnsLength を beStrict に、IgnoreInvalidPunycode を false に設定して Unicode ToASCII を実行した結果を返す。[UTS46]

domain to Unicode アルゴリズムは、ドメイン domain が与えられたとき、次の手順を実行する:

  1. result を、 domain_name を domain に設定し、 CheckHyphens を false に、CheckBidi を true に、CheckJoiners を true に、 UseSTD3ASCIIRules を false に、Transitional_Processing を false に、 IgnoreInvalidPunycode を false に設定して Unicode ToUnicode を実行した結果とする。[UTS46]

  2. エラーが記録された場合、domain を返す。

    domain はホスト パーサーからしか生じないため、記録された どのエラーもすでに検証エラーとして示されている。 domain を返すことで、 ドメインパーサーとdomain to Unicode が、xn--8i7caa のような入力で往復変換できることを保証する。

  3. result を返す。

3.4. ホストの記述

妥当なホスト文字列は、妥当なドメイン文字列、 妥当な IPv4 アドレス文字列、または、U+005B ([) に続けて 妥当な IPv6 アドレス文字列、さらに U+005D (]) が続くものでなければならない。

文字列 input は、次の手順が true を返す場合、妥当な ドメインである:

  1. domain を、input と true を用いて ドメインパーサーを実行した結果とする。

  2. domain が失敗なら、false を返す。

  3. domain に対して 数値で終わるかを検査するものを実行した結果が true を返すなら、 false を返す。

  4. true を返す。

理想的には、もぐら叩き式ではなく、 妥当なドメインを構成する 符号位置の列としてこれを定義する: issue 245。

妥当なドメイン文字列は、 妥当なドメインである文字列でなければならない。

妥当な IPv4 アドレス文字列は、0 から 255 までの 範囲(両端を含む)の 10 進数を表す、可能な限り最短の ASCII 数字の文字列 4 つであり、 それらが U+002E (.) によって互いに区切られていなければならない。

妥当な IPv6 アドレス文字列は、次のいずれかでなければならない:

妥当な IPv6 ピースおよび IPv4 文字列は、妥当な IPv6 ピース文字列の後に U+003A (:) が続き、その後に 妥当な IPv4 アドレス文字列が続くもの、または 妥当な IPv4 アドレス文字列単独のいずれかである。

妥当な IPv6 ピース 文字列は、1 つ以上の 妥当な IPv6 ピース文字列であり、それらが U+003A (:) によって互いに区切られているものである。

妥当な IPv6 ピース 文字列は、0 から 0xFFFF までの範囲(両端を含む)の 16 進数を表す、 可能な限り最短の ASCII 16 進 数字の文字列である。

妥当な IPv6 ピース文字列の 実効ピース 長は、それに含まれる 妥当な IPv6 ピース文字列の数である。 妥当な IPv6 ピースおよび IPv4 文字列の 実効ピース長は、それに含まれる 妥当な IPv6 ピース文字列の数に 2 を加えたものである。

これは A Recommendation for IPv6 Address Text Representation に由来する。IPv4 との一貫性のため、 先頭のゼロは許可されない。[RFC5952]

妥当な不透明ホスト 文字列は、次のいずれかでなければならない:

これは妥当なホスト文字列の定義の一部ではない。 区別するには文脈が必要だからである。

3.5. ホストの解析

ホストパーサーは、 スカラー値文字列 input と、省略可能なブール値 isOpaque(既定値は false)を取り、次の手順を実行する。これらは失敗、または ホストを返す。

  1. input が U+005B ([) で始まる場合:

    1. input が U+005D (]) で終わらない場合、IPv6-unclosed 検証エラーとし、失敗を返す。

    2. input から先頭の U+005B ([) と末尾の U+005D (]) を取り除いたものに対して IPv6 構文解析を行った結果を返す。

  2. isOpaque が true の場合、 opaque-host 構文解析を input に 対して行った結果を返す。

  3. アサート:input は空文字列ではない。

  4. input に パーセントエンコードされたバイトが含まれる場合、 domain-percent-encoded 検証エラーとする。

  5. domain を、input の パーセントデコードに対して BOM なし UTF-8 デコードを実行した結果とする。

    別の方法として、失敗時に早期リターンすることと組み合わせて BOM なし UTF-8 デコードまたは失敗を 使用できる。これは、ドメインパーサーが U+FFFD (�) で失敗するためである。

  6. asciiDomain を、 domain と false で ドメインパーサーを 実行した結果とする。

  7. asciiDomain が失敗である場合、失敗を返す。

  8. asciiDomain が数値で終わる場合:

    1. domain が ASCII 文字列でない場合、IPv4-non-ASCII-input 検証エラーとする。

    2. IPv4 構文解析を asciiDomain に 対して行った結果を返す。

  9. asciiDomain を返す。


数値で終わるかの チェッカーは、ASCII 文字列 input を取り、 次の手順を実行する。これらはブール値を返す。

  1. アサート:input は空文字列ではない。

  2. parts を、input を U+002E (.) で 厳密に 分割した結果とする。

  3. parts の最後の項目が空文字列である場合、 parts から最後の項目を 削除する。

  4. last を、parts 内の最後の項目とする。

  5. last が空文字列でなく、ASCII 数字のみを含む場合、true を返す。

    誤った入力 "09" は、後の段階で IPv4 パーサーによって捕捉される。

  6. last を IPv4 数値として構文解析して失敗が返されない場合、true を返す。

    これは、last が "0X" または "0x" であり、その後に 0 個以上の ASCII 16 進数字が続くことを確認するのと同等である。

  7. false を返す。

IPv4 パーサーは、 ASCII 文字列 input を取り、次の手順を実行する。これらは失敗、または IPv4 アドレスを返す。

IPv4 パーサーを直接呼び出してはならない。代わりに、 ホストパーサーの返値が IPv4 アドレスであることを確認すること。

  1. parts を、input を U+002E (.) で 厳密に 分割した結果とする。

  2. parts の最後の項目が空文字列である場合:

    1. IPv4-empty-part 検証エラーとする。

    2. parts のサイズが 1 より大きい場合、parts から最後の項目を 削除する。

  3. parts のサイズが 4 未満である場合、IPv4-too-few-parts 検証 エラーとする。

  4. parts のサイズが 4 より大きい場合、IPv4-too-many-parts 検証 エラーとし、失敗を返す。

  5. numbers を空のリストとする。

  6. parts の各 part について反復する:

    1. result を、part を構文解析した結果とする。

    2. result が失敗である場合、IPv4-non-numeric-part 検証エラーとし、 失敗を返す。

    3. result[1] が true である場合、IPv4-non-decimal-part 検証エラーとする。

    4. result[0] を numbers に付加する。

  7. numbers 内のいずれかの項目が 255 より大きい場合、IPv4-out-of-range-part 検証 エラーとする。

  8. numbers 内の最後以外のいずれかの項目が 255 より大きい場合、失敗を返す。

  9. numbers 内の最後の項目が 256(5 − numbers のサイズ) 以上である場合、 失敗を返す。

  10. ipv4 を、numbers 内の最後の項目とする。

  11. numbers から最後の項目を 削除する。

  12. counter を 0 とする。

  13. numbers の各 n について反復する:

    1. ipv4 を n × 256(3 − counter) だけ増加させる。

    2. counter を 1 増加させる。

  14. ipv4 を返す。

IPv4 数値 パーサーは、ASCII 文字列 input を取り、 次の手順を実行する。これらは失敗、または数値とブール値のタプルを返す。

  1. input が空文字列である場合、失敗を返す。

  2. validationError を false とする。

  3. R を 10 とする。

  4. input が少なくとも 2 つのコードポイントを含み、最初の 2 つのコードポイントが "0X" または "0x" のいずれかである場合:

    1. validationError を true に設定する。

    2. input から最初の 2 つのコードポイントを削除する。

    3. R を 16 に設定する。

  5. そうでなく、input が少なくとも 2 つのコードポイントを含み、最初のコードポイントが U+0030 (0) である場合:

    1. validationError を true に設定する。

    2. input から最初のコードポイントを削除する。

    3. R を 8 に設定する。

  6. input が空文字列である場合、(0, true) を返す。

  7. input に基数 R の数字ではないコードポイントが含まれる場合、 失敗を返す。

  8. output を、input が基数 R 表記で表す数学的整数値とする。 値 0 から 15 までの数字には ASCII 16 進数字を用いる。

  9. (output, validationError) を返す。


IPv6 パーサーは、 スカラー値文字列 input を取り、次の手順を実行する。これらは失敗、または IPv6 アドレスを返す。

IPv6 パーサーは理論上は直接呼び出すことができるが、 実際にそうする場合は、まずこの文書の編集者と相談してほしい。

  1. address を、IPv6 アドレスの新しい値とし、その pieces はすべて 0 とする。

  2. pieceIndex を 0 とする。

  3. compress を null とする。

  4. pointer を、input に対するポインターとする。

  5. c が U+003A (:) である場合:

    1. remaining が U+003A (:) で始まらない場合、IPv6-invalid-compression 検証エラーとし、失敗を返す。

    2. pointer を 2 増加させる。

    3. pieceIndex を 1 増加させ、その後 compress を pieceIndex に設定する。

  6. c が EOF コードポイントでない間:

    1. pieceIndex が 8 である場合、IPv6-too-many-pieces 検証エラーとし、 失敗を返す。

    2. c が U+003A (:) である場合:

      1. compress が非 null である場合、IPv6-multiple-compression 検証エラーとし、失敗を返す。

      2. pointer と pieceIndex を 1 増加させ、compress を pieceIndex に設定し、その後継続する。
    3. value と length を 0 とする。

    4. length が 4 未満であり、かつ c が ASCII 16 進数字である間、 value を value × 0x10 + 16 進数として解釈した c に設定し、 pointer と length を 1 増加させる。

    5. c が U+002E (.) である場合:

      1. length が 0 である場合、IPv4-in-IPv6-invalid-code-point 検証エラーとし、失敗を返す。

      2. pointer を length だけ減少させる。

      3. pieceIndex が 6 より大きい場合、IPv4-in-IPv6-too-many-pieces 検証エラーとし、失敗を返す。

      4. numbersSeen を 0 とする。

      5. c が EOF コードポイントでない間:

        1. ipv4Piece を null とする。

        2. numbersSeen が 0 より大きい場合:

          1. c が U+002E (.) であり、かつ numbersSeen が 4 未満である場合、 pointer を 1 増加させる。

          2. そうでなければ、IPv4-in-IPv6-invalid-code-point 検証エラーとし、 失敗を返す。
        3. c が ASCII 数字でない場合、IPv4-in-IPv6-invalid-code-point 検証エラーとし、 失敗を返す。

        4. c が ASCII 数字である間:

          1. number を、10 進数として解釈した c とする。

          2. ipv4Piece が null である場合、ipv4Piece を number に設定する。

          3. そうでなく、ipv4Piece が 0 である場合、IPv4-in-IPv6-invalid-code-point 検証エラーとし、 失敗を返す。

          4. そうでなければ、ipv4Piece を ipv4Piece × 10 + number に設定する。

          5. ipv4Piece が 255 より大きい場合、IPv4-in-IPv6-out-of-range-part 検証エラーとし、 失敗を返す。

          6. pointer を 1 増加させる。

        5. address[pieceIndex] を address[pieceIndex] × 0x100 + ipv4Piece に設定する。

        6. numbersSeen を 1 増加させる。

        7. numbersSeen が 2 または 4 である場合、pieceIndex を 1 増加させる。

      6. numbersSeen が 4 でない場合、IPv4-in-IPv6-too-few-parts 検証エラーとし、失敗を返す。

      7. 中断する。

    6. そうでなく、c が U+003A (:) である場合:

      1. pointer を 1 増加させる。

      2. c が EOF コードポイントである場合、IPv6-invalid-code-point 検証エラーとし、失敗を返す。

    7. そうでなく、c が EOF コードポイントでない場合、IPv6-invalid-code-point 検証エラーとし、失敗を返す。

    8. length が 1 より大きく、かつ value が 0x10length − 1 未満である場合、IPv6-piece-leading-zero 検証 エラーとする。

    9. address[pieceIndex] を value に設定する。

    10. pieceIndex を 1 増加させる。

  7. compress が非 null である場合:

    1. swaps を pieceIndex − compress とする。

    2. pieceIndex を 7 に設定する。

    3. pieceIndex が 0 でなく、かつ swaps が 0 より大きい間、 address[pieceIndex] と address[compress + swaps − 1] を入れ替え、その後 pieceIndex と swaps の両方を 1 減少させる。

  8. そうでなく、compress が null であり、かつ pieceIndex が 8 でない場合、 IPv6-too-few-pieces 検証エラーとし、失敗を返す。

  9. address を返す。


opaque-host パーサーは、 スカラー値文字列 input を取り、次の手順を 実行する。これらは失敗、または opaque hostを返す。

  1. input に 禁止されたホストコードポイントが含まれる場合、 host-invalid-code-point 検証エラーとし、失敗を返す。

  2. input に、コードポイントであって URL コードポイントでも U+0025 (%) でもないものが含まれる場合、invalid-URL-unit 検証エラーとする。

  3. input に U+0025 (%) が含まれ、その後に続く 2 つのコードポイントが ASCII 16 進数字でない場合、invalid-URL-unit 検証 エラーとする。

  4. input に対し、C0 control percent-encode setを用いて UTF-8 パーセントエンコードを実行した結果を返す。

3.6. ホストの直列化

ホスト シリアライザーは、 ホスト host を取り、 次の手順を実行する。これらは ASCII 文字列を返す。

  1. host が IPv4 アドレスである場合、host に対して IPv4 シリアライザーを実行した結果を返す。

  2. そうでなく、host が IPv6 アドレスである場合、U+005B ([)、続いて host に対して IPv6 シリアライザーを実行した結果、続いて U+005D (]) を返す。

  3. そうでなければ、host は ドメイン、opaque host、または empty hostであり、 host を返す。

IPv4 シリアライザーは、IPv4 アドレス address を取り、次の手順を実行する。これらは ASCII 文字列を返す。

  1. output を空文字列とする。

  2. n を address の値とする。

  3. 1 から 4 までの範囲(両端を含む)の各 i について反復する:

    1. n % 256 をシリアライズしたものを output の先頭に追加する。

    2. i が 4 でない場合、U+002E (.) を output の先頭に追加する。

    3. n を floor(n / 256) に設定する。

  4. output を返す。

IPv6 シリアライザーは、IPv6 アドレス address を取り、次の手順を実行する。これらは ASCII 文字列を返す。

  1. output を空文字列とする。

  2. compress を、address が与えられたときの IPv6 アドレスの圧縮される piece インデックスを見つける結果とする。

  3. ignore0 を false とする。

  4. address の pieces の インデックスの各 pieceIndex について反復する:

    1. ignore0 が true であり、かつ address[pieceIndex] が 0 である場合、 継続する。

    2. そうでなく、ignore0 が true である場合、ignore0 を false に設定する。

    3. compress が pieceIndex である場合:

      1. separator を、pieceIndex が 0 である場合は "::"、 そうでなければ U+003A (:) とする。

      2. separator を output に付加する。

      3. ignore0 を true に設定し、継続する。

    4. address[pieceIndex] を、可能な限り短い 小文字の 16 進数として表して、output に付加する。

    5. pieceIndex が 7 でない場合、U+003A (:) を output に付加する。

  5. output を返す。

このアルゴリズムには、 A Recommendation for IPv6 Address Text Representation からの推奨が必要である。 [RFC5952]

IPv6 アドレス address が与えられたときに、 IPv6 アドレスの圧縮ピースインデックスを見つけるには:

  1. longestIndex を null とする。

  2. longestSize を 1 とする。

  3. foundIndex を null とする。

  4. foundSize を 0 とする。

  5. address の ピースの インデックスの各 pieceIndex について 反復する:

    1. address のピース[pieceIndex] が 0 でないなら:

      1. foundSize が longestSize より大きいなら、 longestIndex を foundIndex に設定し、longestSize を foundSize に設定する。

      2. foundIndex を null に設定する。
      3. foundSize を 0 に設定する。
    2. そうでなければ:

      1. foundIndex が null なら、foundIndex を pieceIndex に設定する。

      2. foundSize を 1 増加させる。

  6. foundSize が longestSize より大きいなら、 foundIndex を返す。

  7. longestIndex を返す。

0:f:0:0:f:f:0:0 では、2 番目の 0 を指す。

3.7. ホストの同値性

ある ホストが A 等しい ホスト Bかどうかを判定するには、 AとBが等しい場合は true を返し、それ以外の場合は false を返す。

証明書比較では、ドメインの末尾のドット(あれば)を無視した同値性判定が必要です。ただし、証明書ホストはDNS長なども強制されますが、URLではここで強制されません。両者をより近づける方法や統一モデルの良案があれば、issueをファイルしてください。

4. URL

高水準では、URL、妥当な URL 文字列、URL パーサー、および URL シリアライザーは、次のように関係する:

入力 基底 妥当 出力
https:example.org ❌ https://example.org/
https://////example.com/// ❌ https://example.com///
https://example.com/././foo ✅ https://example.com/foo
hello:world https://example.com/ ✅ hello:world
https:example.org https://example.com/ ❌ https://example.com/example.org
\example\..\demo/.\ https://example.com/ ❌ https://example.com/demo/
example https://example.com/demo ✅ https://example.com/example
file:///C|/demo ❌ file:///C:/demo
.. file:///C:/demo ✅ file:///C:/
file://localhost/ ✅ file:///
file://loc%61lhost/ ❌ file:///
https://user:password@example.org/ ❌ https://user:password@example.org/
https://example.org/foo bar ❌ https://example.org/foo%20bar
https://EXAMPLE.com/../x ✅ https://example.com/x
https://ex ample.org/ ❌ Failure
example ❌、基底がないため Failure
https://example.com:demo ❌ Failure
http://[www.example.com]/ ❌ Failure
https://example.org// ✅ https://example.org//
https://example.com/[]?[]#[] ❌ https://example.com/[]?[]#[]
https://example/%?%#% ❌ https://example/%?%#%
https://example/%25?%25#%25 ✅ https://example/%25?%25#%25

基底および出力のURLは、 簡潔にするため シリアライズ形式で表されている。

4.1. URLの表現

ある URL は、汎用識別子を 表す 構造体である。 妥当な URL 文字列と区別するため、これは URL レコードとも呼ばれる。

URLの等価性は、URL A および Bが与えられたとき、 AがBと等しい場合は true を返し、それ以外の場合は false を返す。

URLのスキームは、 ASCII 文字列であり、URLの種類を識別し、 URLを構文解析した後のさらなる 処理へ振り分けるために使用できる。 初期値は空文字列である。

URLのユーザー名は、 ユーザー名を識別するASCII 文字列である。初期値は空文字列である。

URLのパスワードは、 パスワードを識別するASCII 文字列である。初期値は空文字列である。

URLのホストは null または ホストである。初期値は null である。

次の表は、許可されるURLのスキーム / ホストの組み合わせを示す。

スキーム ホスト
ドメイン IPv4 アドレス IPv6 アドレス 不透明ホスト 空ホスト null
"file" を除く特別な スキーム ✅ ✅ ✅ ❌ ❌ ❌
"file" ✅ ✅ ✅ ❌ ✅ ❌
その他 ❌ ❌ ✅ ✅ ✅ ✅

URLのポートは null または ネットワークポートを識別する16 ビット符号なし整数である。初期値は null である。

URLの パス はURL パスであり、通常は 場所を識別する。初期値は « » である。

特別な URLのパスは常に リストであり、すなわち、 不透明になることはない。

URLのクエリは、 null またはASCII 文字列である。初期値は null である。

URLのフラグメントは、 null または ASCII 文字列であり、URLの他の構成要素が識別するリソースに対するさらなる処理に使用できる。 初期値は null である。

URLには、関連付けられた blob URL エントリもあり、これは null または blob URL エントリである。初期値は null である。

これは、"blob" URL が参照するオブジェクトと そのオリジンをキャッシュすることをサポートするために使用される。URLは、構文解析と取得の間に blob URL ストアから削除される可能性がある一方で、取得は依然として 成功する必要があるため、これらをキャッシュすることが重要である。

次の表は、妥当な URL 文字列が構文解析されたとき、 URLの構成要素にどのように対応するかを示す。ユーザー名、パスワード、 および blob URL エントリは省略されている。以下の例では、それぞれ空文字列、 空文字列、および null である。

入力 スキーム ホスト ポート パス クエリ フラグメント
https://example.com/ "https" "example.com" null « 空文字列 » null null
https://localhost:8000/search?q=text#hello "https" "localhost" 8000 « "search" » "q=text" "hello"
urn:isbn:9780307476463 "urn" null null "isbn:9780307476463" null null
file:///ada/Analytical%20Engine/README.md "file" 空文字列 null « "ada", "Analytical%20Engine", "README.md" » null null

URL パスは、URL パスセグメントまたは、0 個以上のリスト のURL パス セグメントのいずれかである。後者の場合、URL パスセグメントには U+002F (/) が含まれることはない。

URL パスセグメントは ASCII 文字列である。通常は ディレクトリまたはファイルを参照するが、あらかじめ定義された意味はない。

URL パスが URL パスセグメントである場合、 それは不透明であり、 web+demo:a/bのように U+002F (/) を含むことができる。URL パーサーは U+002F (/) で始まるものを生成することはないが、 URL Patternはパターンを正規化する際にこれを生成するため、これは不変条件ではない。 [URLPATTERN]

ある 単一ドット URL パスセグメント は、"."であるか、"%2e"に ASCII 大文字・小文字を区別しない 一致をするURL パスセグメント である。

ある 二重ドット URL パスセグメント は、".."であるか、 ".%2e"、"%2e."、または"%2e%2e"に ASCII 大文字・小文字を区別しない 一致をするURL パスセグメント である。

4.2. URL その他

特殊スキームは、次の表の第 1 列に 記載されている ASCII 文字列である。特殊スキームの 既定ポートは、同じ行の 第 2 列に記載されている。他の任意の ASCII 文字列に対する 既定ポートは null である。

特別なスキーム デフォルトポート
"ftp" 21
"file" null
"http" 80
"https" 443
"ws" 80
"wss" 443

URL は、そのスキームが 特別なスキームである場合、特別である。URL は、そのスキームが 特別なスキームで ない場合、特別ではない。

URL は、その 資格情報を含むのは、 ユーザー名またはパスワードが 空文字列でない場合である。

URL は、その不透明 パスを持つのは、そのパスが URL パスセグメントである場合である。

URL は、そのユーザー名/ パスワード/ポートを持つことができないのは、 ホストが null または 空文字列であるか、またはそのスキームが "file" である場合である。

URL は基底 URLとして指定できる。

基底 URLは、入力が 相対 URL 文字列である可能性がある場合、URL パーサーにとって有用である。


Windowsドライブレターは2つのコードポイントで、最初がASCII英字、2番目がU+003A(:)またはU+007C(|)です。

正規化Windowsドライブレターは、2番目のコードポイントがU+003A(:)であるWindowsドライブレターです。

URLの記述セクションに従い、正規化Windowsドライブレターのみが適合となります。

文字列が、以下すべてを満たす場合、Windowsドライブレターで始まるといいます:

文字列 Windowsドライブレターで始まるか
"c:" ✅
"c:/" ✅
"c:a" ❌

urlのパスを短縮するには:

  1. アサート:urlは不透明パスではない

  2. pathをurlのパスとする。

  3. urlのスキームが"file"、pathのサイズが1、path[0]が正規化Windowsドライブレターなら、何もしないで返す。

  4. pathの末尾要素があれば削除する。

4.3. URLの記述

有効なURL文字列は、相対URL(フラグメント付き)文字列または絶対URL(フラグメント付き)文字列のいずれかでなければなりません。

絶対URL(フラグメント付き)文字列は、絶対URL文字列、任意でU+0023(#)とURLフラグメント文字列が続くものです。

絶対URL文字列は、以下のいずれかでなければなりません:

いずれも、任意で U+003F (?) と URL クエリ文字列が続いてもよい。

URL スキーム文字列は、1 つの ASCII 英字で、その後に 0 個以上の ASCII 英数字、U+002B (+)、U+002D (-)、および U+002E (.) が続くものでなければならない。 スキームは、 IANA URI [sic] Schemes 登録簿に登録されるべきである。 [IANA-URI-SCHEMES] [RFC7595]

フラグメント付き相対 URL 文字列は、 基底 URLが 不透明パスを持つ場合、 U+0023 (#) とその後に続く URL フラグメント文字列でなければならない。そうでなければ、 相対 URL 文字列で、任意で U+0023 (#) と URL フラグメント文字列が続いてもよい。

相対 URL 文字列は、次のいずれかでなければならない:

いずれも、任意で U+003F (?) と URL クエリ文字列が続いてもよい。

フラグメント付き相対 URL 文字列を 構文解析する場合、 null でない 基底 URLが必要である。

スキーム相対特別 URL 文字列は、 "//" で、その後に 妥当なホスト文字列、 任意で U+003A (:) と URL ポート文字列、 任意で パス絶対 URL 文字列が続くものでなければならない。

URL ポート文字列は、次のいずれかでなければならない:

スキーム相対 URL 文字列は、 "//" で、その後に 不透明ホストおよびポート文字列、任意で パス絶対 URL 文字列が続くものでなければならない。

不透明ホストおよびポート文字列は、空文字列、または次のいずれかでなければならない: 妥当な 不透明ホスト文字列で、任意で U+003A (:) と URL ポート文字列が続くもの。

スキーム相対 file URL 文字列は、 "//" で、その後に任意で次のいずれかが続くものでなければならない:

パス絶対 URL 文字列は、U+002F (/) で、 その後に 0 個以上の URL パス区分文字列が互いに U+002F (/) で区切られて続くものでなければならない。

パス絶対非オーソリティ URL 文字列は、 2 つの U+002F (/) 符号位置で始まらない パス絶対 URL 文字列でなければならない。

パス相対 URL 文字列は、0 個以上の URL パス区分文字列が互いに U+002F (/) で区切られているもので、かつ U+002F (/) で始まってはならない。

パス相対スキームなし URL 文字列は、 URL スキーム文字列と その後に続く U+003A (:) で始まらない パス相対 URL 文字列でなければならない。

不透明パス URL 文字列は、U+003F (?) を除く 0 個以上の URL 単位でなければならず、 その最初のもの(もしあれば)は U+002F (/) であってはならない。

URL パス区分文字列は、次のいずれかでなければならない:

URL クエリ文字列は、0 個以上の URL 単位でなければならない。

URL フラグメント文字列は、0 個以上の URL 単位でなければならない。

URL 符号位置は、 ASCII 英数字、 U+0021 (!)、 U+0024 ($)、 U+0026 (&)、 U+0027 (')、 U+0028 LEFT PARENTHESIS、 U+0029 RIGHT PARENTHESIS、 U+002A (*)、 U+002B (+)、 U+002C (,)、 U+002D (-)、 U+002E (.)、 U+002F (/)、 U+003A (:)、 U+003B (;)、 U+003D (=)、 U+003F (?)、 U+0040 (@)、 U+005F (_)、 U+007E (~)、 および U+00A0 から U+10FFFD までの範囲(両端を含む)の符号位置であり、サロゲートおよび 非文字を除いたものである。

U+007F DELETE より大きい符号位置は、URL パーサーによって パーセント符号化 バイトに変換される。

HTML では、文書エンコーディングがレガシーエンコーディングである場合、 U+007F DELETE より大きいURL クエリー文字列内の符号位置は、 文書のエンコーディングを用いてパーセント符号化 バイトに変換される。これは、 ある文書で機能する URL が、異なる文書エンコーディングを用いる別の文書へコピーされた場合に問題を引き起こす可能性がある。 どこでもUTF-8エンコーディングを使用すれば、 この問題は解決する。

例えば、次の HTML 文書について考える:

<!doctype html>
<meta charset="windows-1252">
<a href="?sm&ouml;rg&aring;sbord">テスト</a>

文書のエンコーディングは windows-1252 であるため、リンクのURLのクエリ は "sm%F6rg%E5sbord" となる。文書のエンコーディングが UTF-8 であった場合、代わりに "sm%C3%B6rg%C3%A5sbord" となる。

URL 単位は、URL コードポイントおよびパーセントエンコードされた バイトである。

パーセントエンコードされたバイトは、 URL コードポイントではない、または 書き込まれることから除外されているコードポイントをエンコードするために使用できる。


ユーザー名またはパスワードを、 URL レコードの妥当な URL 文字列内で表現する方法はない。

4.4. URLの解析

URL パーサーは スカラー値文字列 inputを、省略可能な null または基底 URL base(既定値は null)および省略可能なエンコーディング encoding(既定値は UTF-8) とともに受け取り、次の手順を実行する:

Web ブラウザー以外の実装は、基本 URL パーサーのみを実装すればよい。

Web ブラウザーのアドレスバーへのユーザー入力が URL レコードに変換される方法は、 この標準の範囲外である。この標準には、 信頼に関する判断に関連するURL レンダリング要件が含まれる。

  1. urlを、基本 URL パーサーを inputに対して実行した結果とし、 baseおよびencodingを用いる。

  2. urlが失敗である場合、失敗を返す。

  3. urlのスキームが "blob" でない場合、urlを返す。

  4. urlのblob URL エントリを、 blob URL を解決する処理をurlに対して行った結果が 失敗を返さなかった場合はその結果に、 それ以外の場合は null に設定する。

  5. urlを返す。


基本 URL パーサーは、 スカラー値文字列 inputを、省略可能な null または基底 URL base(既定値は null)、省略可能なエンコーディング encoding(既定値は UTF-8)、 省略可能なURL url、 および省略可能な状態オーバーライドstate overrideを受け取り、 次の手順を実行する:

encoding引数は、HTMLにのみ関連するレガシーな概念である。 urlおよびstate override引数は、各種 API で使用するためだけのものである。[HTML]

urlおよびstate override引数が渡されない場合、 基本 URL パーサーは、新しいURLまたは失敗を返す。それらが 渡された場合、 アルゴリズムは渡されたurlを変更し、何も返さずに終了できる。

  1. urlが与えられていない場合:

    1. urlを新しいURLに設定する。

    2. inputに先頭または末尾のC0 制御文字または空白が含まれる場合、 invalid-URL-unit 検証エラー。

    3. inputから先頭および末尾のC0 制御文字または空白をすべて除去する。

  2. input に ASCII タブまたは改行が含まれているなら、 invalid-URL-unit 検証 エラー。

  3. input からすべての ASCII タブまたは改行を除去する。

  4. state を、state override が与えられている場合はそれ、 そうでなければ scheme start state とする。

  5. encoding を、encoding から 出力エンコーディングを取得する結果に設定する。

  6. buffer を空文字列とする。

  7. atSignSeen、insideBrackets、および passwordTokenSeen を false とする。

  8. pointer を input の ポインターとする。

  9. state で分岐して、次の状態機械を実行し続ける。実行後に pointer が EOF 符号位置を指している場合は、次の手順へ進む。 そうでなければ、pointer を 1 増やし、状態機械を継続する。

    scheme start state
    1. c が ASCII 英字であるなら、 c を 小文字化したものを buffer に付加し、 state を scheme state に設定する。

    2. そうでなく、state override が与えられていない場合、 state を no scheme state に設定し、pointer を 1 減らす。

    3. そうでなければ、失敗を返す。

      この失敗の通知は、 Location オブジェクトの protocol セッターによってのみ使用される。

    scheme state
    1. c が ASCII 英数字、U+002B (+)、U+002D (-)、または U+002E (.) であるなら、 c を 小文字化したものを buffer に付加する。

    2. そうでなく、c が U+003A (:) であるなら、次を行う:

      1. state override が与えられている場合、次を行う:

        1. url のスキームが 特別スキームであり、 buffer が 特別 スキームでないなら、return する。

        2. url のスキームが 特別スキームでなく、 buffer が 特別 スキームであるなら、return する。

        3. url が 資格情報を含む または非 null の ポートを持ち、 かつ buffer が "file" であるなら、return する。

        4. url のスキームが "file" であり、その ホストが 空ホストであるなら、return する。

      2. url のスキームを buffer に設定する。

      3. state override が与えられている場合、次を行う:

        1. url のポートが url の スキームの 既定ポートであるなら、 url のポートを null に設定する。

        2. Return する。

      4. buffer を空文字列に設定する。

      5. url のスキームが "file" であるなら、 次を行う:

        1. remaining が "//" で始まらないなら、 special-scheme-missing-following-solidus 検証エラー。

        2. state を file state に設定する。

      6. そうでなく、url が 特別であり、base が 非 null であり、 base のスキームが url の スキームであるなら:

        1. Assert: base は 特別である(したがって 不透明パスを持たない)。

        2. state を special relative or authority state に設定する。

      7. そうでなく、url が 特別であるなら、state を special authority slashes state に設定する。

      8. そうでなく、remaining が U+002F (/) で始まるなら、 state を path or authority state に設定し、 pointer を 1 増やす。

      9. そうでなければ、url の パスを 空文字列に設定し、 state を opaque path state に設定する。

    3. そうでなく、state override が与えられていない場合、 buffer を空文字列に設定し、state を no scheme state に設定し、(input の最初の符号位置から) 最初からやり直す。

    4. そうでなければ、失敗を返す。

      この失敗の表示は、 Location オブジェクトの protocol セッターによってのみ使用される。さらに、この状態で先に行われる失敗ではない終了は、 そのセッターを定義するための意図的な相違である。

    no scheme state
    1. base が null であるか、または base が 不透明パスを持ち、 c が U+0023 (#) でないなら、 missing-scheme-non-relative-URL 検証エラー、 失敗を返す。

    2. そうでなく、base が 不透明パスを持ち、 c が U+0023 (#) であるなら、url の スキームを base の スキームに、 url の パスを base の パスに、 url の クエリを base の クエリに、 url の フラグメントを空文字列に設定し、 state を fragment state に設定する。

    3. そうでなく、base のスキームが "file" でないなら、 state を relative state に設定し、 pointer を 1 減らす。

    4. そうでなければ、state を file state に設定し、pointer を 1 減らす。

    special relative or authority state
    1. c が U+002F (/) であり、 remaining が U+002F (/) で始まるなら、state を special authority ignore slashes state に設定し、 pointer を 1 増やす。

    2. そうでなければ、special-scheme-missing-following-solidus 検証エラーとし、 state を relative state に設定し、 pointer を 1 減らす。

    path or authority state
    1. c が U+002F (/) であるなら、 state を authority state に設定する。

    2. そうでなければ、state を path state に設定し、pointer を 1 減らす。

    relative state
    1. Assert:base のスキームは "file" でない。

    2. url のスキームを base の スキームに設定する。

    3. c が U+002F (/) であるなら、 state を relative slash state に設定する。

    4. そうでなく、url が 特別であり、c が U+005C (\) であるなら、 invalid-reverse-solidus 検証エラーとし、state を relative slash state に設定する。

    5. そうでなければ:

      1. url のユーザー名を base のユーザー名に、 url のパスワードを base のパスワードに、 url のホストを base のホストに、 url のポートを base のポートに、 url のパスを base のパスの クローンに、 そして url のクエリを base のクエリに設定する。

      2. c が U+003F (?) であるなら、url の クエリ を空文字列に設定し、state を query state に設定する。

      3. そうでなく、c が U+0023 (#) であるなら、url の フラグメントを 空文字列に設定し、state を fragment state に設定する。

      4. そうでなく、c が EOF 符号位置でないなら:

        1. url のクエリを null に設定する。

        2. url のパスを 短縮する。

        3. state を path state に設定し、pointer を 1 減らす。

    relative slash state
    1. url が 特別であり、c が U+002F (/) または U+005C (\) であるなら:

      1. c が U+005C (\) であるなら、invalid-reverse-solidus 検証エラー。

      2. state を special authority ignore slashes state に設定する。

    2. そうでなく、c が U+002F (/) であるなら、state を authority state に設定する。

    3. そうでなければ、 url のユーザー名を base のユーザー名に、 url のパスワードを base のパスワードに、 url のホストを base のホストに、 url のポートを base のポートに、 state を path state に設定し、その後、 pointer を 1 減らす。

    special authority slashes state
    1. c が U+002F (/) であり、 remaining が U+002F (/) で始まるなら、state を special authority ignore slashes state に設定し、 pointer を 1 増やす。

    2. そうでなければ、special-scheme-missing-following-solidus 検証エラーとし、 state を special authority ignore slashes state に設定し、 pointer を 1 減らす。

    特殊 authority スラッシュ無視状態
    1. c が U+002F (/) でも U+005C (\) でもない場合、state を authority 状態に設定し、 pointer を 1 減少させる。

    2. そうでなければ、special-scheme-missing-following-solidus 検証エラーとする。

    authority 状態
    1. c が U+0040 (@) である場合:

      1. Invalid-credentials 検証エラーとする。

      2. atSignSeen が true である場合、"%40" を buffer の先頭に追加する。

      3. atSignSeen を true に設定する。

      4. buffer 内の各 codePoint について:

        1. codePoint が U+003A (:) であり、かつ passwordTokenSeen が false である場合、 passwordTokenSeen を true に設定し、継続する。

        2. encodedCodePoints を、 codePoint に対し userinfo percent-encode setを用いて UTF-8 パーセントエンコードを 実行した結果とする。

        3. passwordTokenSeen が true である場合、 encodedCodePoints を url の パスワードに付加する。

        4. そうでなければ、encodedCodePoints を url の ユーザー名に付加する。

      5. buffer を空文字列に設定する。

    2. そうでなく、次のいずれかが true である場合:

      その場合:

      1. atSignSeen が true であり、かつ buffer が空文字列である場合、 host-missing 検証 エラーとし、失敗を返す。

      2. pointer を buffer の コードポイント長 + 1 だけ減少させ、 buffer を空文字列に設定し、 state を host 状態に設定する。

    3. そうでなければ、c を buffer に付加する。

    host 状態
    hostname 状態
    1. state override が与えられており、かつ url の スキームが "file" である場合、pointer を 1 減少させ、state を file host 状態に設定する。

    2. そうでなく、c が U+003A (:) であり、かつ insideBrackets が false である場合:

      1. buffer が空文字列である場合、host-missing 検証エラーとし、 失敗を返す。

      2. state override が与えられており、かつ state override が hostname 状態である場合、失敗を返す。

      3. host を、buffer に対し url が特殊でないとして host 構文解析を行った結果とする。

      4. host が失敗である場合、失敗を返す。

      5. url のホストを host に、buffer を空文字列に設定し、 state を port 状態に設定する。

    3. そうでなく、次のいずれかが true である場合:

      その場合、pointer を 1 減少させ、その後:

      1. url が特殊であり、かつ buffer が 空文字列である場合、 host-missing 検証 エラーとし、失敗を返す。

      2. そうでなく、state override が与えられており、buffer が 空文字列であり、かつ url が資格情報を含む、または url の ポートが非 null である場合、失敗を返す。

      3. host を、buffer に対し url が特殊でないとして host 構文解析を行った結果とする。

      4. host が失敗である場合、失敗を返す。

      5. url のホストを host に、buffer を空文字列に設定し、 state を path start 状態に設定する。

      6. state override が与えられている場合、戻る。

    4. そうでなければ:

      1. c が U+005B ([) である場合、insideBrackets を true に設定する。

      2. c が U+005D (]) である場合、insideBrackets を false に設定する。

      3. c を buffer に付加する。

    port 状態
    1. c が ASCII 数字である場合、c を buffer に付加する。

    2. そうでなく、次のいずれかが true である場合:

      その場合:

      1. buffer が空文字列でない場合:

        1. port を、0 から 9 までの値を持つ数字に ASCII 数字を用いて、 buffer が基数 10 で表す数学的整数値とする。

        2. port が 16 ビット符号なし 整数でない場合、 port-out-of-range 検証エラーとし、失敗を返す。

        3. port が url のスキームの既定ポートである場合、 url のポートを null に設定し、 そうでなければ port に設定する。

        4. buffer を空文字列に設定する。

        5. state override が与えられている場合、戻る。

      2. state override が与えられている場合、失敗を返す。

      3. state を path start 状態に設定し、 pointer を 1 減少させる。

    3. そうでなければ、port-invalid 検証 エラーとし、失敗を返す。

    file 状態
    1. url のスキームを "file" に設定する。

    2. url のホストを空文字列に設定する。

    3. c が U+002F (/) または U+005C (\) である場合:

      1. c が U+005C (\) である場合、invalid-reverse-solidus 検証エラーとする。

      2. state を file slash 状態に設定する。

    4. そうでなく、base が非 null であり、かつ base のスキームが "file" である場合:

      1. url のホストを base のホストに、 url のパスを base の パスの複製に、そして url のクエリーを base の クエリーに設定する。

      2. c が U+003F (?) である場合、url のクエリーを 空文字列に設定し、state を query 状態に設定する。

      3. そうでなく、c が U+0023 (#) である場合、url のフラグメントを 空文字列に設定し、state を fragment 状態に設定する。

      4. そうでなく、c が EOF コードポイントでない場合:

        1. url のクエリーを null に設定する。

        2. pointer から input の末尾までの コード ポイント部分文字列が Windows ドライブ文字で始まらない場合、 url の パスを短縮する。

        3. そうでなければ:

          1. File-invalid-Windows-drive-letter 検証 エラーとする。

          2. url のパスを « » に設定する。

          これは(プラットフォーム非依存の)Windows ドライブ文字の癖である。

        4. state を path 状態に設定し、 pointer を 1 減少させる。

    5. そうでなければ、state を path 状態に設定し、pointer を 1 減少させる。

    file slash 状態
    1. c が U+002F (/) または U+005C (\) である場合:

      1. c が U+005C (\) である場合、invalid-reverse-solidus 検証エラーとする。

      2. state を file host 状態に設定する。

    2. そうでなければ:

      1. base が非 null であり、かつ base のスキームが "file" である場合:

        1. url のホストを base のホストに設定する。

        2. pointer から input の末尾までのコード ポイント部分文字列が Windows ドライブ文字で始まらず、かつ base のパス[0] が 正規化された Windows ドライブ文字である場合、base の パス[0] を url のパスに付加する。

          これは(プラットフォーム非依存の)Windows ドライブ文字の癖である。

      2. state を path 状態に設定し、 pointer を 1 減少させる。

    file host 状態
    1. c が EOF コードポイント、U+002F (/)、U+005C (\)、 U+003F (?)、または U+0023 (#) である場合、pointer を 1 減少させ、その後:

      1. state override が与えられておらず、かつ buffer が Windows ドライブ文字である場合、file-invalid-Windows-drive-letter-host 検証エラーとし、 state を path 状態に設定する。

        これは(プラットフォーム非依存の)Windows ドライブ 文字の癖である。ここでは buffer はリセットされず、代わりに path 状態で使用される。

      2. そうでなく、buffer が空文字列である場合:

        1. url のホストを空文字列に設定する。

        2. state override が与えられている場合、戻る。

        3. state を path start 状態に設定する。

      3. そうでなければ、次の手順を実行する:

        1. host を、buffer に対し url が特殊でないとして host 構文解析を行った 結果とする。

        2. host が失敗である場合、失敗を返す。

        3. host が "localhost" である場合、 host を 空文字列に設定する。

        4. url のホストを host に設定する。

        5. state override が与えられている場合、戻る。

        6. buffer を空文字列に設定し、state を path start 状態に設定する。

    2. そうでなければ、c を buffer に付加する。

    path start 状態
    1. url が特殊である場合:

      1. c が U+005C (\) である場合、invalid-reverse-solidus 検証エラーとする。

      2. state を path 状態に設定する。

      3. c が U+002F (/) でも U+005C (\) でもない場合、pointer を 1 減少させる。

    2. そうでなく、state override が与えられておらず、かつ c が U+003F (?) である場合、 url のクエリーを空文字列に設定し、 state を query 状態に設定する。

    3. そうでなく、state override が与えられておらず、かつ c が U+0023 (#) である場合、 url のフラグメントを空文字列に設定し、 state を fragment 状態に設定する。

    4. そうでなく、c が EOF コードポイントでない場合:

      1. state を path 状態に設定する。

      2. c が U+002F (/) でない場合、pointer を 1 減少させる。

    5. そうでなく、state override が与えられており、かつ url の ホストが null である場合、空文字列を url の パスに付加する。

    path 状態
    1. 次のいずれかが true である場合:

      • c が EOF コードポイントまたは U+002F (/) である

      • url が特殊であり、かつ c が U+005C (\) である

      • state override が与えられておらず、かつ c が U+003F (?) または U+0023 (#) である

      その場合:

      1. url が特殊であり、かつ c が U+005C (\) である場合、 invalid-reverse-solidus 検証エラーとする。

      2. buffer が 二重ドット URL パス セグメントである場合:

        1. url のパスを短縮する。

        2. c が U+002F (/) ではなく、かつ url が特殊であり、c が U+005C (\) である、ということもない場合、空文字列を url の パスに付加する。

          これは、入力 /usr/.. について、結果が / であり、パスがない状態ではないことを意味する。

      3. そうでなく、buffer が 単一ドット URL パス セグメントであり、かつ c が U+002F (/) ではなく、さらに url が特殊であり、c が U+005C (\) である、ということもない場合、 空文字列を url のパスに付加する。

      4. そうでなく、buffer が 単一ドット URL パス セグメントでない場合:

        1. url のスキームが "file" であり、url の パスが空であり、かつ buffer が Windows ドライブ文字である場合、 buffer 内の 2 番目のコードポイントを U+003A (:) に置き換える。

          これは(プラットフォーム非依存の)Windows ドライブ文字の癖である。

        2. buffer を url のパスに付加する。

      5. buffer を空文字列に設定する。

      6. c が U+003F (?) である場合、url のクエリーを 空文字列に設定し、state を query 状態に設定する。

      7. c が U+0023 (#) である場合、url のフラグメントを 空文字列に設定し、state を fragment 状態に設定する。

    2. そうでなければ、次の手順を実行する:

      1. c が URL コードポイントでなく、かつ U+0025 (%) でもない場合、 invalid-URL-unit 検証エラーとする。

      2. c が U+0025 (%) であり、かつ remaining が 2 つの ASCII 16 進数字で始まらない場合、invalid-URL-unit 検証エラーとする。

      3. c に対し、 path percent-encode setを用いて UTF-8 パーセントエンコードを行い、 その結果を buffer に付加する。

    opaque path 状態
    1. c が U+003F (?) である場合、 url のクエリーを空文字列に設定し、 state を query 状態に設定する。

    2. そうでなく、c が U+0023 (#) である場合、url のフラグメントを 空文字列に設定し、state を fragment 状態に設定する。

    3. そうでなく、c が U+0020 SPACE である場合:

      1. Invalid-URL-unit 検証エラーとする。

      2. remaining が U+003F (?) または U+0023 (#) で始まる場合、"%20" を url の パスに付加する。

      3. そうでなければ、U+0020 SPACE を url のパスに付加する。

    4. そうでなく、c が EOF コードポイントでない場合:

      1. c が URL コードポイントでなく、かつ U+0025 (%) でもない場合、 invalid-URL-unit 検証エラーとする。

      2. c が U+0025 (%) であり、かつ remaining が 2 つの ASCII 16 進数字で始まらない場合、invalid-URL-unit 検証エラーとする。

      3. c に対し、 C0 control percent-encode setを用いて UTF-8 パーセントエンコードを行い、 その結果を url の パスに付加する。

    query 状態
    1. encoding が UTF-8 ではなく、かつ次のいずれかが true である場合:

      その場合、encoding を UTF-8に設定する。

    2. 次のいずれかが true である場合:

      その場合:

      1. queryPercentEncodeSet を、 url が特殊である場合は special-query percent-encode set、そうでなければ query percent-encode setとする。

      2. encoding、buffer、および queryPercentEncodeSet を用いて エンコーディング後に パーセントエンコードし、その結果を url のクエリーに付加する。

        この操作は、状態を持つ ISO-2022-JP エンコーダーのため、 コードポイント単位では呼び出せない。

      3. buffer を空文字列に設定する。

      4. c が U+0023 (#) である場合、url のフラグメントを 空文字列に設定し、state を fragment 状態に設定する。

    3. そうでなく、c が EOF コードポイントでない場合:

      1. c が URL コードポイントでなく、かつ U+0025 (%) でもない場合、 invalid-URL-unit 検証エラーとする。

      2. c が U+0025 (%) であり、かつ remaining が 2 つの ASCII 16 進数字で始まらない場合、invalid-URL-unit 検証エラーとする。

      3. c を buffer に付加する。

    fragment 状態
    1. c が EOF コードポイントでない場合:

      1. c が URL コードポイントでなく、かつ U+0025 (%) でもない場合、 invalid-URL-unit 検証エラーとする。

      2. c が U+0025 (%) であり、かつ remaining が 2 つの ASCII 16 進数字で始まらない場合、invalid-URL-unit 検証エラーとする。

      3. c に対し、 fragment percent-encode setを用いて UTF-8 パーセントエンコードを行い、 その結果を url の フラグメントに付加する。

  10. url を返す。


あるurlとusernameでユーザー名をセットするには、urlのusernameにusernameをUTF-8 percent-encode(userinfo percent-encode set使用)した結果をセットする。

あるurlとpasswordでパスワードをセットするには、urlのpasswordにpasswordをUTF-8 percent-encode(userinfo percent-encode set使用)した結果をセットする。

4.5. URLの直列化

URL シリアライザーは、 URL urlを、省略可能なブール値 exclude fragment(既定値は false)とともに受け取り、 次の 手順を実行する。これらはASCII 文字列を返す。

  1. outputを、urlのスキームと U+003A (:) を連結したものとする。

  2. urlのホストが null でない場合:

    1. "//" をoutputに付加する。

    2. urlが資格情報を含む場合:

      1. urlのユーザー名を outputに付加する。

      2. urlのパスワードが空文字列でない 場合、U+003A (:) に続けてurlのパスワードをoutputに付加する。

      3. U+0040 (@) をoutputに付加する。

    3. urlのホストを、 シリアライズして、outputに付加する。

    4. urlのポートが null でない場合、U+003A (:) に続けて urlのポートをシリアライズして outputに付加する。

  3. urlのホストが null であり、urlが 不透明パスを持たず、 urlのパスのサイズが 1 より大きく、urlのパス[0] が空文字列である場合、U+002F (/) を付加し 続けて U+002E (.) をoutputに付加する。

    これにより、web+demo:/.//not-a-host/または web+demo:/path/..//not-a-host/が、構文解析され、その後 シリアライズされたときに、 web+demo://not-a-host/となることを防ぐ(これらは web+demo:/.//not-a-host/となる)。

  4. urlをURL パスシリアライズした結果を outputに付加する。

  5. urlのクエリが null でない場合、 U+003F (?) に続けてurlのクエリを outputに付加する。

  6. exclude fragmentが false であり、かつurlのフラグメントが null でない場合、U+0023 (#) に続けてurlのフラグメントを outputに付加する。

  7. outputを返す。

URL パス シリアライザーは、 URLまたはURL パス urlOrPathを受け取り、 次の手順を実行する。これらは ASCII 文字列を返す。

  1. urlOrPathがURLである場合、pathをurlOrPathの パスとし、それ以外の場合は urlOrPathとする。

  2. pathがURL パスセグメントである場合、pathを返す。

  3. outputを空文字列とする。

  4. pathの各segmentについて反復する:U+002F (/) に続けて segmentをoutputに付加する。

  5. outputを返す。

4.6. URLの同値性

URL Aが 等しい URL Bであるかを、省略可能な ブール値 exclude fragments(既定値は false)とともに判定するには、 次の手順を実行する:

  1. serializedAを、シリアライズした結果とする: Aを、exclude fragmentを exclude fragmentsに設定してシリアライズする。

  2. serializedBを、シリアライズした結果とする: Bを、exclude fragmentを exclude fragmentsに設定してシリアライズする。

  3. serializedAがserializedBである場合は true を返し、それ以外の場合は false を返す。

URL パス Aが 等しい URL パス Bであるかを判定するには、 AとBが等しい場合は true を返し、それ以外の場合は false を返す。

シリアライズではなくURL パスセグメントを比較することは重要になり得る。異なる URL パスが同一にシリアライズ され得るためである。例えば、 web+demo:のパスは空文字列である一方、 web+demo://hostのパスは « » であり、どちらも空文字列にシリアライズされる。

URL パス Aが で始まる URL パス Bであるかを判定するには、次の手順を実行する。これらはブール値を返す。

  1. AがURL パスセグメントであるか、Bが URL パス セグメントである場合、false を返す。

  2. BのサイズがAの サイズより大きい場合、false を返す。

  3. Bの各 index(Bのインデックス)について: A[index]がB[index]でない場合、false を返す。

  4. true を返す。

URL パスセグメントはリスト内で U+002F (/) を含まないため、 AがBで始まるのは、BがAのセグメント全体を包含する場合に限られる。 これにより、あるURL パスが別のものに「包含」されるかどうかを判断するのに適している。 シリアライズを単純に比較することはできない:« "foobar" » のシリアライズは « "foo" » のシリアライズで始まるが、 後者のパスを持つURLは、 前者のURLを 包含しない。

仕様は、セキュリティ上の 判断にはオリジン概念を優先すべきである。 URL パスが、それが包含する URL パスを包含すると扱うことは、 Web プラットフォームの他の部分と整合しない パスベースの権限の一形態である。これは Cookie などの レガシー機能に必要だが、その他の場所では避けることが最善である。

4.7. オリジン

必要な背景 情報については、HTML にある オリジンの定義を参照すること。 [HTML]

URL urlのオリジンは、 urlの スキームに応じて分岐し、次の手順を実行して返されるオリジンである:

"blob"
  1. urlのblob URL エントリが null でない場合、 urlのblob URL エントリの環境の オリジンを返す。

  2. pathURLを、urlをURL パスシリアライズした結果を 構文解析した 結果とする。

  3. pathURLが失敗である場合、新しい不透明オリジンを返す。

  4. pathURLのスキームが "http"、 "https"、または "file" である場合、pathURLの オリジンを返す。

  5. 新しい不透明オリジンを返す。

blob:https://whatwg.org/d0360e2f-caee-469f-9a2f-87d5b0456f6fのオリジンは、 タプルオリジン ("https", "whatwg.org", null, null) である。

"ftp"
"http"
"https"
"ws"
"wss"

タプルオリジン (urlのスキーム、 urlのホスト、urlのポート、null) を返す。

"file"

残念ながら、これは読者への演習として残されている。判断に迷う場合は、 新しい不透明オリジンを返す。

それ以外

新しい不透明オリジンを返す。

これは実際、これらのURLが自身と同一オリジンになることができないことを意味する。

4.8. URLのレンダリング

URLは、URL を表示する主な目的が、ユーザーに セキュリティまたは信頼に関する判断を行わせることである場合、以下に説明する変更を加えたシリアライズ 形式でレンダリングされるべきである。たとえば、ユーザーはブラウザーのアドレスバーにレンダリングされた URL に 基づいて信頼に関する判断を行うことが期待される。

4.8.1. 人が読めない/不要な構成要素の簡略化

なりすましの機会を与えたり、セキュリティ関連の 情報から注意をそらしたりする可能性のある構成要素を取り除く:

4.8.2. 省略表示

表示領域が限られている場合、URLの省略はユーザーに誤解を与えないよう慎重に行うべきです:

4.8.3. 国際化と特殊文字

国際化ドメイン名(IDN)、特殊文字、および双方向テキストは、スプーフィングを防ぐために 注意して扱うべきである:

5. application/x-www-form-urlencoded

application/x-www-form-urlencoded形式は、名前と値からなるリストのタプルをエンコードする方法を提供します。

application/x-www-form-urlencoded形式は、様々な実装上の事故や妥協の積み重ねによる異常な怪物であり、相互運用性のために必要な要件の集合となっていますが、良い設計とは言えません。特に、繰り返し(場合によってはネストされた)文字エンコーディングとバイト列の変換に関する複雑な詳細に注意してください。残念ながら、この形式はHTMLフォームの普及により広く使用されています。[HTML]

5.1. application/x-www-form-urlencoded のパース

レガシーなサーバ指向の実装では、UTF-8以外のエンコーディングや、名前が_charsetのタプルに特別なロジックが必要な場合があります。ここではそのようなロジックは説明されていません。準拠すべきはUTF-8のみです。

application/x-www-form-urlencodedパーサは、バイト列inputを受け取り、以下の手順を実行します:

  1. sequencesをinputを0x26(&)で分割した結果とする。

  2. outputを、名前と値が文字列を保持するname-valueタプルの空のリストとする。

  3. sequences内の各バイト列bytesについて:

    1. bytesが空のバイト列なら、continue。

    2. bytesが0x3D(=)を含むなら、nameをbytesの先頭から最初の0x3D(=)直前までのバイト列、valueを最初の0x3D(=)の直後から末尾までのバイト列(存在すれば)とする。0x3D(=)が最初のバイトならnameは空、最後ならvalueは空になる。

    3. それ以外はnameにbytes、valueに空のバイト列をセットする。

    4. nameとvalue内の全ての0x2B(+)を0x20(SP)に置換する。

    5. nameStringとvalueStringを、それぞれnameとvalueをUTF-8 BOM無しデコード(パーセントデコードの結果)で得たものとする。

    6. appendで(nameString, valueString)をoutputに追加。

  4. outputを返す。

5.2. application/x-www-form-urlencoded の直列化

application/x-www-form-urlencoded直列化器は、name-valueタプルのリストtuplesと、省略可能なencoding encoding(デフォルトはUTF-8)を受け取り、以下の手順を実行します。返り値はASCII文字列です。

  1. encoding に、出力エンコーディングを取得を encoding に対して実行した結果を設定する。

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

  3. 各 tuple in tuples について:

    1. アサート:tuple の name および tuple の value は スカラ値文字列である。

    2. name に、 エンコード後パーセントエンコード を encoding・tuple の name・application/x-www-form-urlencoded パーセントエンコード集合で実行した結果を設定する。

    3. value に、 エンコード後パーセントエンコード を encoding・tuple の value・application/x-www-form-urlencoded パーセントエンコード集合で実行した結果を設定する。

    4. output が空文字列でなければ、U+0026 (&) を output に追加する。

    5. name、U+003D (=)、value の順に output に追加する。

  4. output を返す。

5.3. フック

application/x-www-form-urlencoded文字列パーサは、スカラー値文字列inputをUTF-8エンコードし、その結果をapplication/x-www-form-urlencodedパースに渡します。

6. API

この節ではWeb IDLの用語を使用します。ブラウザのユーザーエージェントはこのAPIをサポートしなければなりません。JavaScriptの実装もこのAPIをサポートするべきです。他のユーザーエージェントやプログラミング言語は、自身のニーズに合わせたAPIを利用することが推奨されますが、それが必ずしもこのAPIである必要はありません。[WEBIDL]

6.1. URLクラス

[Exposed=*,
 LegacyWindowAlias=webkitURL]
interface URL {
  constructor(USVString url, optional USVString base);

  static URL? parse(USVString url, optional USVString base);
  static boolean canParse(USVString url, optional USVString base);

  stringifier attribute USVString href;
  readonly attribute USVString origin;
           attribute USVString protocol;
           attribute USVString username;
           attribute USVString password;
           attribute USVString host;
           attribute USVString hostname;
           attribute USVString port;
           attribute USVString pathname;
           attribute USVString search;
  [SameObject] readonly attribute URLSearchParams searchParams;
           attribute USVString hash;

  USVString toJSON();
};

URLオブジェクトには、以下が関連付けられています:

API URLパーサは、スカラー値文字列urlと、オプションでnullまたはスカラー値文字列base(デフォルトはnull)を受け取り、以下の手順を実行します:

  1. parsedBaseをnullにする。

  2. baseがnullでなければ:

    1. parsedBaseに基本URLパーサでbaseをパースした結果をセット。

    2. parsedBaseが失敗なら失敗を返す。

  3. 基本URLパーサでurlとparsedBaseをパースした結果を返す。

initializeで、URLオブジェクト urlをURL urlRecordで初期化する場合:

  1. queryをurlRecordのquery(nullでなければ)または空文字列とする。

  2. urlのURLにurlRecordをセット。

  3. urlのquery objectに新しいURLSearchParams オブジェクトをセットする。

  4. Initializeでurlのquery objectにqueryを渡す。

  5. urlのquery objectのURL objectにurlをセット。

URLインターフェースを実装するオブジェクトのextract an origin手順は、 thisのURLのoriginを返すことである。[HTML]


new URL(url, base) コンストラクタの手順:

  1. parsedURLをAPI URLパーサでurlとbase(もし指定されていれば)をパースした結果とする。

  2. parsedURLが失敗なら、TypeError 例外をスローする。

  3. Initializeでthis をparsedURLで初期化する。

基底 URLを使わずに、 文字列をURLとして 構文解析するには、単一の引数で URL コンストラクターを 呼び出す:

var input = "https://example.org/💩",
    url = new URL(input)
url.pathname // "/%F0%9F%92%A9"

入力が相対 URL 文字列である場合、これは例外を投げる:

try {
  var url = new URL("/🍣🍺")
} catch(e) {
  // that happened
}

そのような場合には基底 URLが必要である:

var input = "/🍣🍺",
    url = new URL(input, document.baseURI)
url.href // "https://url.spec.whatwg.org/%F0%9F%8D%A3%F0%9F%8D%BA"

URL オブジェクトは 基底 URLとして 使用できる(IDL は引数として文字列を要求するため、 URL オブジェクトは その href 取得子の返り値に文字列化される):

var url = new URL("🏳️‍🌈", new URL("https://pride.example/hello-world"))
url.pathname // "/%F0%9F%8F%B3%EF%B8%8F%E2%80%8D%F0%9F%8C%88"

static parse(url, base) メソッドの手順:

  1. parsedURLをAPI URLパーサでurlとbase(もし指定されていれば)をパースした結果とする。

  2. parsedURLが失敗ならnullを返す。

  3. urlを新しいURLオブジェクトとして作成。

  4. InitializeでurlをparsedURLで初期化。

  5. urlを返す。

静的なcanParse(url, base) メソッドの手順は以下の通り:

  1. parsedURLを、API URL パーサーをurlとbase(指定されていれば)で実行した結果とする。

  2. parsedURLが失敗の場合、falseを返す。

  3. trueを返す。


hrefゲッターの手順および toJSON()メソッドの手順は、シリアライズされたthisのURLを返すことである。

href セッターの手順は以下の通り:

  1. parsedURLを、与えられた値で基本URLパーサーを実行した結果とする。

  2. parsedURLが失敗の場合、throwでTypeErrorを投げる。

  3. thisのURLをparsedURLに設定する。

  4. thisのquery objectのlistを空にする。

  5. queryをthisのURLのqueryとする。

  6. queryがnullでなければ、thisの query objectのlistを パースされたqueryで設定する。

originゲッターの手順は、シリアライズされたthisのURLの originを返すことである。[HTML]

protocolゲッターの手順は、thisの URLのschemeの後ろにU+003A (:)を付けて返すことである。

protocol セッターの手順は、与えられた値の後ろにU+003A (:)を付けて 基本URLパースを行い、 thisのURLを urlとし、 scheme start stateを state overrideとして指定することである。

usernameゲッターの手順は、thisの URLのusernameを返すことである。

username セッターの手順は以下の通り:

  1. thisのURLがユーザー名/パスワード/ポートをもてない場合は、returnする。

  2. Set the usernameに、thisのURLと与えられた値を渡す。

passwordゲッターの手順は、thisの URLのpasswordを返すことである。

password セッターの手順は以下の通り:

  1. thisのURLがユーザー名/パスワード/ポートをもてない場合は、returnする。

  2. Set the passwordに、thisのURLと与えられた値を渡す。

host getter 手順は次のとおり:

  1. url を、this の URL とする。

  2. url の ホストが null であるなら、空文字列を返す。

  3. url の ポートが null であるなら、url の ホストを 直列化したものを返す。

  4. url の ホストを 直列化したものに、 U+003A (:) と url の ポートを 直列化したものを続けて返す。

host setter 手順は次のとおり:

  1. this の URL が 不透明パスを持つなら、return する。

  2. 与えられた値を 基本 URL 構文解析する。その際、this の URLを url とし、host state を state override とする。

host setter に与えられた値に ポートがない場合、this の URL の ポートは 変化しない。これは、host getter が URL ポート文字列を返すため、 setter が常にその両方を「リセット」すると想定していた場合には予想外であり得る。

hostname getter 手順は次のとおり:

  1. this の URL の ホストが null であるなら、空 文字列を返す。

  2. this の URL の ホストを 直列化したものを返す。

hostname セッター手順は次のとおりである:

  1. this のURLが不透明パスを持つなら、返す。

  2. 与えられた値を、this の URLをurlとして、またホスト名状態を state overrideとして、 基本 URL 構文解析する。

port 取得子手順は次のとおりである:

  1. this のURLのポートが null なら、空文字列を返す。

  2. this のURLのポートを 直列化して返す。

port セッター手順は次のとおりである:

  1. this のURLがユーザー名/パスワード/ポートを持てないなら、 返す。

  2. 与えられた値が空文字列なら、this のURLの ポートを null に設定する。

  3. そうでなければ、与えられた値を、 this のURLをurlとして、 ポート状態をstate overrideとして 基本 URL 構文解析する。

pathname 取得子手順は、this のURLを URL パス 直列化した結果を返すことである。

pathname セッター手順は次のとおりである:

  1. this のURLが不透明パスを持つなら、返す。

  2. this のURLのパスを 空にする。

  3. 与えられた値を、this の URLをurlとして、またパス開始状態を state overrideとして 基本 URL 構文解析する。

search 取得子手順は次のとおりである:

  1. this のURLのクエリーが null または空文字列のいずれかなら、空文字列を返す。

  2. U+003F (?) の後に、this のURLのクエリーが続くものを返す。

search セッター手順は次のとおりである:

  1. url をthis のURLとする。

  2. 与えられた値が空文字列なら、url のクエリーを null に設定し、this のクエリーオブジェクトの リストを空にし、返す。

  3. input を、与えられた値から先頭の U+003F (?) を 1 つ削除したもの(もしあれば)とする。

  4. url のクエリーを空文字列に設定する。

  5. input を、url を urlとして、またクエリー状態を state overrideとして 基本 URL 構文解析する。

  6. 設定する: thisのクエリオブジェクトのリストを 次の 構文解析の結果にする。urlのクエリ。

searchParams 取得子手順は、this のクエリー オブジェクトを返すことである。

hash 取得子手順は次のとおりである:

  1. this のURLのフラグメントが null または空文字列のいずれかなら、空文字列を返す。

  2. U+0023 (#) の後に、this のURLのフラグメントが続くものを返す。

hash セッター手順は次のとおりである:

  1. 与えられた値が空文字列なら、this のURLの フラグメントを null に設定して返す。

  2. input を、与えられた値から先頭の U+0023 (#) を 1 つ削除したもの(もしあれば)とする。

  3. this のURLのフラグメントを空文字列に設定する。

  4. input を、this の URLをurlとして、またフラグメント状態を state overrideとして 基本 URL 構文解析する。

6.2. URLSearchParamsクラス

[Exposed=*]
interface URLSearchParams {
  constructor(optional (sequence<sequence<USVString>> or record<USVString, USVString> or USVString) init = "");

  readonly attribute unsigned long size;

  undefined append(USVString name, USVString value);
  undefined delete(USVString name, optional USVString value);
  USVString? get(USVString name);
  sequence<USVString> getAll(USVString name);
  boolean has(USVString name, optional USVString value);
  undefined set(USVString name, USVString value);

  undefined sort();

  iterable<USVString, USVString>;
  stringifier;
};

URLSearchParams オブジェクトの構築と文字列化は非常に簡単です:

let params = new URLSearchParams({key: "730d67"})
params.toString() // "key=730d67"

URLSearchParams オブジェクトはapplication/x-www-form-urlencoded 形式を内部で利用するため、URLオブジェクト (hrefやsearchを含む)と比較して、一部のコードポイントのエンコード方法が異なる場合があります。 特にsearchParamsでURLのqueryを操作する場合、驚くことがあります。

const url = new URL('https://example.com/?a=b ~');
console.log(url.href);   // "https://example.com/?a=b%20~"
url.searchParams.sort();
console.log(url.href);   // "https://example.com/?a=b+%7E"
const url = new URL('https://example.com/?a=~&b=%7E');
console.log(url.search);                // "?a=~&b=%7E"
console.log(url.searchParams.get('a')); // "~"
console.log(url.searchParams.get('b')); // "~"

URLSearchParams オブジェクトは application/x-www-form-urlencoded パーセントエンコード集合 に含まれるものをパーセントエンコードし、U+0020 SPACE は U+002B (+) としてエンコードされる。

エンコーディングを無視する場合(UTF-8 を使う)、 search は クエリ パーセントエンコード集合 または スペシャルクエリ パーセントエンコード集合( URLがspecial かどうかによって異なる) のいずれかに含まれるものをパーセントエンコードする。

URLSearchParams オブジェクトには以下が関連付けられています:

URLSearchParams オブジェクトqueryをinitで初期化するには:

  1. initがシーケンスである場合、 initの各 innerSequence について:

    1. innerSequenceのサイズが 2でない場合、投げる TypeErrorを。

    2. 追加する (innerSequence[0], innerSequence[1])を queryのリストに。

  2. それ以外の場合、initがレコードである場合、 initの各 name → valueについて、(name, value) をqueryのリストに付加する。

  3. それ以外の場合:

    1. 表明:initは文字列である。

    2. queryのリストを、initを 構文解析した結果に設定する。

URLSearchParams オブジェクトqueryをupdateするには:

  1. queryのURL objectがnullならreturn。

  2. serializedQueryをqueryのlistの直列化結果とする。

  3. serializedQueryが空文字列ならserializedQueryをnullにする。

  4. queryのURL objectのURLのqueryにserializedQueryをセットする。

new URLSearchParams(init) コンストラクタの手順:

  1. initが文字列かつU+003F(?)で始まる場合、最初のコードポイントをinitから削除する。

  2. Initializeでthisをinitで初期化する。

sizeゲッターはthisのlistのsizeを返します。

append(name, value) メソッドの手順:

  1. Append(name, value)をthisのlistに追加する。

  2. Updateでthisを更新する。

delete(name, value) メソッドの手順:

  1. もし value が指定されていれば、this の list から、名前が name かつ値が value の tuple をすべて 削除する。

  2. それ以外の場合、名前が name である tuple を this の list からすべて 削除する。

  3. 更新 this を行う。

get(name) メソッドの手順は、 this の list の中で名前が name である最初の tuple の値を返す。もしそのような tuple がなければ null を返す。

getAll(name) メソッドの手順は、 this の list の中で名前が name であるすべての tuple の値をリスト順で返す。なければ空の配列を返す。

has(name, value) メソッドの手順は以下の通り:

  1. もし value が指定されていて this の list に名前が name かつ値が value である tuple があれば true を返す。

  2. もし value が指定されていなくて this の list に名前が name の tuple があれば true を返す。

  3. false を返す。

set(name, value) メソッドの手順は以下の通り:

  1. もし this の list が name を持つ tuple を含む場合、最初のその tuple の値を value に設定し、その他を 削除する。

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

  3. 更新 this を行う。


URLSearchParams オブジェクトの中の name-value tuple をソートすることは、特にキャッシュヒットを増やす目的で有用な場合がある。これは sort() メソッドを呼び出すことで達成できる。

const url = new URL("https://example.org/?q=🏳️‍🌈&key=e1f7bc78");
url.searchParams.sort();
url.search; // "?key=e1f7bc78&q=%F0%9F%8F%B3%EF%B8%8F%E2%80%8D%F0%9F%8C%88"

元の入力を変更せず比較したい場合などは、新しく URLSearchParams オブジェクトを作成する:

const sorted = new URLSearchParams(url.search)
sorted.sort()

sort() メソッドの手順は以下の通り:

  1. this の list を、a の名前が code unit less than で b の名前より小さい場合 a が先になるように、昇順にソートしたthisのlistに設定する。

  2. 更新 this を行う。


value pair to iterate over は this の list の tuple で、key が name、value が value となる。

stringification behavior の手順は、シリアライズされた this の list を返す。

6.3. 他の場所のURL API

URLを公開する標準は、 URLを文字列として公開すべきである (内部のURLを シリアライズすることにより)。 標準は、 URLをURLオブジェクトを使用して公開すべきではない。URLオブジェクトは、 URL を操作するためのものである。IDL では USVString 型を使用すべきである。

ここでのより高次の概念は、値を不変なデータ構造として公開することです。

標準が自身で定義する機能名に「URL」のバリエーションを使う場合、その機能名は「url」(小文字かつ末尾が「l」)とするべきです。「URL」「URI」「IRI」といった名前は使うべきではありません。ただし、複合語の場合は「URL」(大文字)が推奨されます。例: "newURL", "oldURL"。

EventSourceやHashChangeEventインターフェース(HTML)は適切な命名例です。[HTML]

謝辞

長年にわたりURLの相互運用性向上に貢献し、この標準の目標達成に寄与してきた多くの方々に感謝します。同様に、この標準が現在の形になったのにも多くの方々が貢献しています。

改めて、感謝を述べます: 100の人, Adam Barth, Addison Phillips, Adrián Chaves, Adrien Ricciardi, Albert Wiersch, Alex Christensen, Alexandre Morgaut, Alexis Hunt, Alwin Blok, Andrew Sullivan, Arkadiusz Michalski, Behnam Esfahbod, Bobby Holley, Boris Zbarsky, Brad Hill, Brandon Ross, Cailyn Hansen, Chris Dumez, Chris Rebert, Corey Farwell, Dan Appelquist, Daniel Bratell, Daniel Stenberg, David Burns, David Håsäther, David Sheets, David Singer, David Walp, Domenic Denicola, Emily Schechter, Emily Stark, Eric Lawrence, Erik Arvidsson, Gavin Carothers, Geoff Richards, Glenn Maynard, Gordon P. Hemsley, hemanth, Henri Sivonen, Ian Hickson, Ilya Grigorik, Italo A. Casas, Jakub Gieryluk, James C. Wise, James Graham, James Manger, James Ross, Jeff Hodges, Jeffrey Posnick, Jeffrey Yasskin, Joe Duarte, Joshua Bell, Jxck, Karl Wagner, Kemal Zebari, 田村健人 (Kent TAMURA), Kevin Grandon, Kornel Lesiński, Larry Masinter, Leif Halvard Silli, Mark Amery, Mark Davis, Marcos Cáceres, Marijn Kruisselbrink, Martin Dürst, Mathias Bynens, Matt Falkenhagen, Matt Giuca, Michael Peick, Michael™ Smith, Michal Bukovský, Michel Suignard, Mikaël Geljić, Nikita Skovoroda, Noah Levitt, Peter Occil, Philip Jägenstedt, Philippe Ombredanne, Prayag Verma, Rimas Misevičius, Robert Kieffer, Rodney Rehm, Roy Fielding, Ryan Sleevi, Sam Ruby, Sam Sneddon, Santiago M. Mola, Sebastian Mayr, Shannon Booth, Simon Pieters, Simon Sapin, Steven Vachon, Stuart Cook, Sven Uhlig, Tab Atkins, 吉野剛史 (Takeshi Yoshino), Tantek Çelik, Tiancheng "Timothy" Gu, Tim Berners-Lee, 簡冠庭 (Tim Guan-tin Chien), Titi_Alone, Tomek Wytrębowicz, Trevor Rowbotham, Tristan Seligmann, Valentin Gosu, Vyacheslav Matva, Wei Wang, Wolf Lammen, 山岸和利 (Yamagishi Kazutoshi), Yongsheng Zhang, 成瀬ゆい (Yui Naruse), and zealousidealroll 皆様ありがとうございます!

この標準はAnne van Kesteren(Apple, annevk@annevk.nl)によって執筆されています。

知的財産権

Copyright © WHATWG (Apple, Google, Mozilla, Microsoft)。この作品は クリエイティブ・コモンズ 表示 4.0 国際ライセンス の下で提供されています。ソースコードに組み込まれている部分については、BSD 3-Clause ライセンス の下で提供されます。

これは現行標準です。 特許レビュー版に関心がある方は現行標準レビュー草案をご覧ください。

索引

本仕様で定義されている用語

参照によって定義される用語

参考文献

規定参考文献

[BIDI]
Manish Goregaokar मनीष गोरेगांवकर; Robin Leroy. Unicode 双方向アルゴリズム. 2026 年 9 月 1 日. Unicode 標準付属書 #9. URL: https://www.unicode.org/reports/tr9/tr9-52.html
[ENCODING]
Anne van Kesteren. エンコーディング標準. 現行 標準. URL: https://encoding.spec.whatwg.org/
[FILEAPI]
Marijn Kruisselbrink. File API. URL: https://w3c.github.io/FileAPI/
[HTML]
Anne van Kesteren; et al. HTML 標準. 現行標準. URL: https://html.spec.whatwg.org/multipage/
[IANA-URI-SCHEMES]
統一資源識別子 (URI) スキーム. URL: https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 標準. 現行標準. URL: https://infra.spec.whatwg.org/
[PSL]
Public Suffix List. URL: https://publicsuffix.org/
[UTS46]
Mark Davis; Markus Scherer. Unicode IDNA 互換性処理. 2026 年 8 月 31 日. Unicode 技術標準 #46. URL: https://www.unicode.org/reports/tr46/tr46-36.html
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 標準. 現行 標準. URL: https://webidl.spec.whatwg.org/

参考情報文献

[ECMA-262]
ECMAScript 言語仕様. URL: https://tc39.es/ecma262/multipage/
[IDNFAQ]
国際化ドメイン名 (IDN) FAQ. URL: https://unicode.org/faq/idn.html
[RFC1034]
P. Mockapetris. ドメイン名 - 概念と 機能. 1987年11月. インターネット標準. URL: https://www.rfc-editor.org/info/rfc1034/
[RFC3986]
T. Berners-Lee; R. Fielding; L. Masinter. 統一 資源識別子 (URI): 汎用構文. 2005年1月. インターネット標準. URL: https://www.rfc-editor.org/info/rfc3986/
[RFC3987]
M. Duerst; M. Suignard. 国際化資源 識別子 (IRI). 2005年1月. 提案標準. URL: https://www.rfc-editor.org/info/rfc3987/
[RFC4291]
R. Hinden; S. Deering. IP バージョン 6 アドレッシング アーキテクチャ. 2006年2月. 標準案. URL: https://www.rfc-editor.org/info/rfc4291/
[RFC5890]
J. Klensin. アプリケーション向け国際化ドメイン名 (IDNA): 定義および文書フレームワーク. 2010年8月. 提案標準. URL: https://www.rfc-editor.org/info/rfc5890/
[RFC5952]
S. Kawamura; M. Kawashima. IPv6 アドレスのテキスト表現に関する推奨事項. 2010年8月. 提案標準. URL: https://www.rfc-editor.org/info/rfc5952/
[RFC6454]
A. Barth. Web オリジンの概念. 2011年12月. 提案標準. URL: https://www.rfc-editor.org/info/rfc6454/
[RFC7595]
D. Thaler, 編; T. Hansen; T. Hardie. URI スキームのガイドライン および登録手順. 2015年6月. 現行最良慣行. URL: https://www.rfc-editor.org/info/rfc7595/
[RFC791]
J. Postel. インターネットプロトコル. 1981年9月 . インターネット標準. URL: https://www.rfc-editor.org/info/rfc791/
[URLPATTERN]
Ben Kelly; Jeremy Roman; 宍戸俊哉 (Shunya Shishido). URL Pattern 標準. 現行標準. URL: https://urlpattern.spec.whatwg.org/
[UTR36]
Mark Davis; Michel Suignard. Unicode セキュリティ上の考慮事項. 2014年9月19日. Unicode 技術報告 #36. URL: https://www.unicode.org/reports/tr36/tr36-15.html
[UTS39]
Josh Hadley; Roozbeh Pournader. Unicode セキュリティメカニズム. 2026年8月27日. Unicode 技術標準 #39. URL: https://www.unicode.org/reports/tr39/tr39-34.html

IDL索引

[Exposed=*,
 LegacyWindowAlias=webkitURL]
interface URL {
  constructor(USVString url, optional USVString base);

  static URL? parse(USVString url, optional USVString base);
  static boolean canParse(USVString url, optional USVString base);

  stringifier attribute USVString href;
  readonly attribute USVString origin;
           attribute USVString protocol;
           attribute USVString username;
           attribute USVString password;
           attribute USVString host;
           attribute USVString hostname;
           attribute USVString port;
           attribute USVString pathname;
           attribute USVString search;
  [SameObject] readonly attribute URLSearchParams searchParams;
           attribute USVString hash;

  USVString toJSON();
};

[Exposed=*]
interface URLSearchParams {
  constructor(optional (sequence<sequence<USVString>> or record<USVString, USVString> or USVString) init = "");

  readonly attribute unsigned long size;

  undefined append(USVString name, USVString value);
  undefined delete(USVString name, optional USVString value);
  USVString? get(USVString name);
  sequence<USVString> getAll(USVString name);
  boolean has(USVString name, optional USVString value);
  undefined set(USVString name, USVString value);

  undefined sort();

  iterable<USVString, USVString>;
  stringifier;
};

✔MDN

URL/URL

In all current engines.

Firefox26+Safari14.1+Chrome19+
Opera?Edge79+
Edge (Legacy)12+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js10.0.0+
MDN

URL/canParse_static

Firefox115+Safari17+ChromeNone
Opera?EdgeNone
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js20.0.0+
✔MDN

URL/hash

In all current engines.

Firefox22+Safari7+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
✔MDN

URL/host

In all current engines.

Firefox22+Safari7+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
✔MDN

URL/hostname

In all current engines.

Firefox22+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
✔MDN

URL/href

In all current engines.

Firefox22+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
✔MDN

URL/origin

In all current engines.

Firefox26+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)12+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet6.0+Opera Mobile?
Node.js7.0.0+
✔MDN

URL/password

In all current engines.

Firefox26+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)12+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet6.0+Opera Mobile?
Node.js7.0.0+
✔MDN

URL/pathname

In all current engines.

Firefox22+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
✔MDN

URL/port

In all current engines.

Firefox22+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
✔MDN

URL/protocol

In all current engines.

Firefox22+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
✔MDN

URL/search

In all current engines.

Firefox22+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
✔MDN

URL/searchParams

In all current engines.

Firefox29+Safari10.1+Chrome51+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
✔MDN

URL/toJSON

In all current engines.

Firefox54+Safari11+Chrome71+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.7.0+
✔MDN

URL/toString

In all current engines.

Firefox54+Safari7+Chrome19+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet6.0+Opera Mobile?
Node.js7.0.0+
✔MDN

URL/username

In all current engines.

Firefox26+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)12+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet6.0+Opera Mobile?
Node.js7.0.0+
✔MDN

URL

In all current engines.

Firefox19+Safari7+Chrome32+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView4.4+Samsung Internet?Opera Mobile?
Node.js10.0.0+
✔MDN

URLSearchParams/URLSearchParams

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+

URLSearchParams/entries

In all current engines.

Firefox44+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+

URLSearchParams/forEach

In all current engines.

Firefox44+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+

URLSearchParams/keys

In all current engines.

Firefox44+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+

URLSearchParams/values

In all current engines.

Firefox44+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
✔MDN

URLSearchParams/append

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
✔MDN

URLSearchParams/delete

In all current engines.

Firefox29+Safari14+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
✔MDN

URLSearchParams/get

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
✔MDN

URLSearchParams/getAll

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
✔MDN

URLSearchParams/has

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
✔MDN

URLSearchParams/set

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari ? Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
✔MDN

URLSearchParams/size

In all current engines.

Firefox112+Safari17+Chrome113+
Opera?Edge113+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js19.0.0+
✔MDN

URLSearchParams/sort

In all current engines.

Firefox54+Safari11+Chrome61+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.7.0+
✔MDN

URLSearchParams/toString

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
✔MDN

URLSearchParams

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js10.0.0+