目標
URL標準は、URLの完全な相互運用性を実現するため、以下のアプローチを取ります:
-
RFC 3986およびRFC 3987を現代の実装に合わせて調整し、同時にそれらを廃止します。(例:スペース、その他の「不正」なコードポイント、クエリのエンコーディング、等価性、正規化などは必ずしも共通・定義されていません。)URLの解析はHTMLの解析と同じくらい堅牢である必要があります。[RFC3986] [RFC3987]
-
用語として「URL」に統一します。URIやIRIは混乱の元です。実際には両者に同じアルゴリズムが使われているため、区別しても意味がありません。また、URLは検索人気でも圧倒的です。
-
URLの既存JavaScript APIを完全に定義し、より使いやすくするための拡張を追加します。また、HTML要素を使わずにURLを操作できる新たな
URLオブジェクトも追加します。(JavaScriptのWorker環境などで有用です。) -
パーサー・シリアライザー・APIの組み合わせが冪等性を保証することを目指します。例えば、解析→直列化の操作で失敗しなかった場合、さらに解析→直列化を重ねても結果は変わりません。APIを通じて操作した非失敗結果も、何度直列化→解析しても変化しません。
編集者が本件について知識を深めるにつれ、目標の範囲が広がる可能性があります。
1. 基盤
本仕様はInfraに依存します。[INFRA]
本仕様で使われるいくつかの用語は、以下の標準・仕様書で定義されています:
- Encoding [ENCODING]
- File API [FILEAPI]
- HTML [HTML]
- Unicode IDNA Compatibility Processing [UTS46]
- Web IDL [WEBIDL]
整数を直列化するには、可能な限り短い10進数で表現します。
1.1. 記述
バリデーションエラーは、入力が有効な入力と一致しないことを示します。ユーザーエージェント、特に適合性チェッカーは、これをどこかに報告することが推奨されます。
バリデーションエラーが発生しても、パーサーが終了するわけではありません。パーサーの終了は、常に明示的に(例えばreturn文によって)記述されます。
バリデーションエラーを通知することは有用です。なぜなら、エラー処理は直感的でない場合があり、古いユーザーエージェントが正しいエラー処理を実装していないこともあり、記述の意図が他の開発者にとって不明瞭である可能性があるためです。
| エラーの種類 | エラーの説明 | 失敗 |
|---|---|---|
| IDNA | ||
| domain-to-ASCII |
Unicode ToASCII は、CheckHyphens、 UseSTD3ASCIIRules、および VerifyDnsLength がすべて true に設定されている場合にエラーを記録する。[UTS46] Unicode ToASCII エラーの詳細が 記録されている場合、ユーザーエージェントにはそれらを渡すことが推奨される。 | Yes (beStrict が true の場合、または domain が ASCII 文字列ではなく、緩和された パラメーターでの Unicode ToASCII も失敗した場合) |
| ホストの構文解析 | ||
| domain-percent-encoded |
ドメインとして処理される入力の host に、 パーセントエンコードされたバイトが含まれる。 | · |
| host-invalid-code-point |
(特殊でない URL 内の)opaque host に、 禁止されたホストコードポイントが含まれる。 | Yes |
| IPv4-empty-part |
IPv4 アドレスが U+002E (.) で終わる。 | · |
| IPv4-too-few-parts |
IPv4 アドレスの 部分が 4 個未満である。 | · |
| IPv4-too-many-parts |
IPv4 アドレスの 部分が 4 個を超えている。 | Yes |
| IPv4-non-numeric-part |
IPv4 アドレスの 部分が数値ではない。 | Yes |
| IPv4-non-decimal-part |
IPv4 アドレスに、 16 進または 8 進の数字で表された数値が含まれる。 | · |
| IPv4-out-of-range-part |
IPv4 アドレスの 部分が 255 を超えている。 | Yes (最後の部分に適用される場合のみ) |
| IPv4-non-ASCII-input | · | |
| IPv6-unclosed |
IPv6 アドレスに、 閉じる U+005D (]) がない。 | Yes |
| IPv6-invalid-compression |
IPv6 アドレスが 不適切な圧縮で始まっている。 | Yes |
| IPv6-too-many-pieces |
IPv6 アドレスに 8 個を超える piece が含まれる。 | Yes |
| IPv6-multiple-compression |
IPv6 アドレスが 複数の箇所で圧縮されている。 | Yes |
| IPv6-invalid-code-point |
IPv6 アドレスに、 ASCII 16 進数字 でも U+003A (:) でもないコードポイントが含まれる。または、予期せず終了している。 | Yes |
| IPv6-too-few-pieces |
圧縮されていない IPv6 アドレスに含まれる piece が 8 個未満である。 | Yes |
| IPv6-piece-leading-zero | · | |
| IPv4-in-IPv6-too-many-pieces | Yes | |
| IPv4-in-IPv6-invalid-code-point |
| Yes |
| IPv4-in-IPv6-out-of-range-part | Yes | |
| IPv4-in-IPv6-too-few-parts | Yes | |
| URL の構文解析 | ||
| invalid-URL-unit |
URL unit ではないコードポイントが見つかった。 | · |
| special-scheme-missing-following-solidus |
入力の scheme の後に " | · |
| missing-scheme-non-relative-URL |
入力に scheme がない。これは、入力が ASCII alpha で始まらず、かつ base URL が提供されていない、 または base URL に opaque path があるため base URL として 使用できない場合である。 入力の scheme がなく、base URL が与えられていない:
入力の scheme はないが、base URL に opaque path がある。
| Yes |
| invalid-reverse-solidus |
URL が special scheme を持ち、U+002F (/) の代わりに U+005C (\) を使用している。 | · |
| invalid-credentials |
入力が 資格情報を含んでいる。 | · |
| host-missing |
入力が special scheme を持つが、host を含まない。 | Yes |
| port-out-of-range |
入力の port が大きすぎる。 | Yes |
| port-invalid |
入力の port が無効である。 | Yes |
| file-invalid-Windows-drive-letter |
入力は relative-URL string であり、Windows ドライブ文字で始まり、
かつ base
URL の scheme が "
| · |
| file-invalid-Windows-drive-letter-host |
| · |
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デコード以外を使うのはセキュリティ的に推奨されません。
-
outputを空のバイト列とする。
-
inputの各バイトbyteについて:
-
byteが0x25(%)でなければ、byteをoutputに追加する。
-
そうでなく、byteが0x25(%)かつinputの次の2バイトが0x30(0)~0x39(9)、0x41(A)~0x46(F)、0x61(a)~0x66(f)のいずれにも該当しない場合、byteをoutputに追加する。
-
それ以外の場合:
-
bytePointをinputのbyteの次の2バイトを等価デコードし、16進数として解釈した値とする。
-
bytePointの値のバイトをoutputに追加する。
-
inputの次の2バイトをスキップする。
-
-
-
outputを返す。
スカラー値文字列 inputをパーセントデコードするには:
-
inputのUTF-8エンコーディングをbytesとする。
-
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 が与えられたとき:
-
アサート:encoding は UTF-8 であるか、 percentEncodeSet は スペシャルクエリ パーセントエンコード集合 または
application/x-www-form-urlencodedパーセントエンコード集合である。 -
percentEncodeSet が
application/x-www-form-urlencodedパーセントエンコード集合なら spaceAsPlus を true とし、そうでなければ false とする。 -
encoder を、エンコーダ取得を encoding に対して実行した結果とする。
-
inputQueue を、input を I/O キュー に変換したものとする。
-
output を空文字列とする。
-
potentialError を 0 とする。
これは後続の while ループを開始するために非 null 値である必要がある。
-
potentialError が non-null である間、次を繰り返す:
-
encodeOutput を空の I/O キューとする。
-
potentialError を エンコードまたは失敗を inputQueue, encoder, encodeOutput で実行した結果とする。
-
encodeOutput をバイト列に変換した各 byte について次を行う:
-
potentialError が non-null なら、"
%26%23"、続いて ASCII 数字 による potentialError の 10 進表現の最短列、"%3B" を output に追加する。これは encoding が UTF-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アドレス)
概略として、ホスト、有効なホスト文字列、ホストパーサー、ホストシリアライザーの関係は以下の通りです:
-
ホストはメモリ上の表現とみなせます。
-
有効なホスト文字列は、ホストパーサーに渡したときにバリデーションエラーや失敗を起こさない入力(すなわち適合・有効と見なされる)を定義します。
-
ホストシリアライザーはホストを受け取り、ASCII文字列を返します(その文字列を再度パースした場合、等価なホストが得られます)。
パースとシリアライズのラウンドトリップの結果は、ホストパーサーの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.というドメインは等価ではなく、通常区別されます。
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またはhostのパブリックサフィックスとその直前のドメインラベルから構成されるドメインを返します。
-
hostのパブリックサフィックスがnull、またはhostのパブリックサフィックスがhostと等価なら、nullを返す。
-
hostが「
.」で終わるならtrailingDotを「.」、そうでなければ空文字列とする。 -
registrableDomainをPublic Suffix Listアルゴリズムでhostをドメインとして実行した結果とする。[PSL]
-
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 またはドメインを返す。
-
strictResult を、domain および true で domain parser ToASCII を実行した結果とする。
-
strictResult が failure 値である場合、domain-to-ASCII 検証 エラーとする。この手順は return しない。
-
beStrict が true の場合:
-
strictResult が failure 値である場合、failure を返す。
-
strictResult を返す。
-
-
result を null とする。
-
domain が ASCII 文字列である場合、result を domain を小文字化したものに設定する。
beStrict が false で、domain が ASCII 文字列である場合、 このアルゴリズムはウェブ互換性のため、 Unicode ToASCII の結果にかかわらず、 domain を小文字化して返す。 IgnoreInvalidPunycode だけでは十分ではない。Punycode は正常に復号できても、 なお妥当性基準に失敗することがあるためである。例えば、
xn--8i7caaはwwwに復号されるが、 その符号位置のステータスは "mapped" である。[UTS46] -
そうでない場合:
-
result を、domain および false で domain parser ToASCII を実行した結果に設定する。
-
result が failure 値である場合、failure を返す。
-
-
result が空文字列である場合、failure を返す。
-
result が禁止されたドメイン符号位置を含む場合、failure を返す。
ウェブ互換性、および DNS ベースではないシステムとの互換性のため、 禁止されたドメイン符号位置は、 UseSTD3ASCIIRules が true のときに許可されないものの部分集合である。issue #397 も参照。
-
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 が与えられたとき、次の手順を実行する:
-
result を、 domain_name を domain に設定し、 CheckHyphens を false に、CheckBidi を true に、CheckJoiners を true に、 UseSTD3ASCIIRules を false に、Transitional_Processing を false に、 IgnoreInvalidPunycode を false に設定して Unicode ToUnicode を実行した結果とする。[UTS46]
-
エラーが記録された場合、domain を返す。
domain はホスト パーサーからしか生じないため、記録された どのエラーもすでに検証エラーとして示されている。 domain を返すことで、 ドメインパーサーとdomain to Unicode が、
xn--8i7caaのような入力で往復変換できることを保証する。 -
result を返す。
3.4. ホストの記述
妥当なホスト文字列は、妥当なドメイン文字列、 妥当な IPv4 アドレス文字列、または、U+005B ([) に続けて 妥当な IPv6 アドレス文字列、さらに U+005D (]) が続くものでなければならない。
文字列 input は、次の手順が true を返す場合、妥当な ドメインである:
-
domain を、input と true を用いて ドメインパーサーを実行した結果とする。
-
domain が失敗なら、false を返す。
-
domain に対して 数値で終わるかを検査するものを実行した結果が true を返すなら、 false を返す。
-
true を返す。
理想的には、もぐら叩き式ではなく、 妥当なドメインを構成する 符号位置の列としてこれを定義する: issue 245。
妥当なドメイン文字列は、 妥当なドメインである文字列でなければならない。
妥当な IPv4 アドレス文字列は、0 から 255 までの 範囲(両端を含む)の 10 進数を表す、可能な限り最短の ASCII 数字の文字列 4 つであり、 それらが U+002E (.) によって互いに区切られていなければならない。
妥当な IPv6 アドレス文字列は、次のいずれかでなければならない:
-
妥当な IPv6 ピース文字列であり、実効ピース長が 8 のもの。
-
妥当な IPv6 ピースおよび IPv4 文字列であり、実効ピース長が 8 のもの。
-
U+003A U+003A (::)。その前に任意で 妥当な IPv6 ピース文字列があり、 その後に任意で 妥当な IPv6 ピース文字列または 妥当な IPv6 ピースおよび IPv4 文字列が続き、 前後の文字列の実効ピース長の合計が 7 以下であるもの。
妥当な 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]
妥当な不透明ホスト 文字列は、次のいずれかでなければならない:
-
禁止されたホスト符号位置を除く、 1 つ以上の URL 単位
-
U+005B ([) の後に 妥当な IPv6 アドレス文字列が続き、その後に U+005D (]) が続くもの。
これは妥当なホスト文字列の定義の一部ではない。 区別するには文脈が必要だからである。
3.5. ホストの解析
ホストパーサーは、 スカラー値文字列 input と、省略可能なブール値 isOpaque(既定値は false)を取り、次の手順を実行する。これらは失敗、または ホストを返す。
-
input が U+005B ([) で始まる場合:
-
input が U+005D (]) で終わらない場合、IPv6-unclosed 検証エラーとし、失敗を返す。
-
input から先頭の U+005B ([) と末尾の U+005D (]) を取り除いたものに対して IPv6 構文解析を行った結果を返す。
-
-
isOpaque が true の場合、 opaque-host 構文解析を input に 対して行った結果を返す。
-
アサート:input は空文字列ではない。
-
input に パーセントエンコードされたバイトが含まれる場合、 domain-percent-encoded 検証エラーとする。
-
domain を、input の パーセントデコードに対して BOM なし UTF-8 デコードを実行した結果とする。
別の方法として、失敗時に早期リターンすることと組み合わせて BOM なし UTF-8 デコードまたは失敗を 使用できる。これは、ドメインパーサーが U+FFFD (�) で失敗するためである。
-
asciiDomain を、 domain と false で ドメインパーサーを 実行した結果とする。
-
asciiDomain が失敗である場合、失敗を返す。
-
asciiDomain が数値で終わる場合:
-
domain が ASCII 文字列でない場合、IPv4-non-ASCII-input 検証エラーとする。
-
IPv4 構文解析を asciiDomain に 対して行った結果を返す。
-
-
asciiDomain を返す。
数値で終わるかの チェッカーは、ASCII 文字列 input を取り、 次の手順を実行する。これらはブール値を返す。
IPv4 パーサーは、 ASCII 文字列 input を取り、次の手順を実行する。これらは失敗、または IPv4 アドレスを返す。
IPv4 パーサーを直接呼び出してはならない。代わりに、 ホストパーサーの返値が IPv4 アドレスであることを確認すること。
-
parts を、input を U+002E (.) で 厳密に 分割した結果とする。
-
parts の最後の項目が空文字列である場合:
-
IPv4-empty-part 検証エラーとする。
-
-
parts のサイズが 4 未満である場合、IPv4-too-few-parts 検証 エラーとする。
-
parts のサイズが 4 より大きい場合、IPv4-too-many-parts 検証 エラーとし、失敗を返す。
-
numbers を空のリストとする。
-
parts の各 part について反復する:
-
result を、part を構文解析した結果とする。
-
result が失敗である場合、IPv4-non-numeric-part 検証エラーとし、 失敗を返す。
-
result[1] が true である場合、IPv4-non-decimal-part 検証エラーとする。
-
result[0] を numbers に付加する。
-
-
numbers 内のいずれかの項目が 255 より大きい場合、IPv4-out-of-range-part 検証 エラーとする。
-
numbers 内の最後以外のいずれかの項目が 255 より大きい場合、失敗を返す。
-
ipv4 を、numbers 内の最後の項目とする。
-
counter を 0 とする。
-
numbers の各 n について反復する:
-
ipv4 を n × 256(3 − counter) だけ増加させる。
-
counter を 1 増加させる。
-
-
ipv4 を返す。
IPv4 数値 パーサーは、ASCII 文字列 input を取り、 次の手順を実行する。これらは失敗、または数値とブール値のタプルを返す。
-
input が空文字列である場合、失敗を返す。
-
validationError を false とする。
-
R を 10 とする。
-
input が少なくとも 2 つのコードポイントを含み、最初の 2 つのコードポイントが "
0X" または "0x" のいずれかである場合:-
validationError を true に設定する。
-
input から最初の 2 つのコードポイントを削除する。
-
R を 16 に設定する。
-
-
そうでなく、input が少なくとも 2 つのコードポイントを含み、最初のコードポイントが U+0030 (0) である場合:
-
validationError を true に設定する。
-
input から最初のコードポイントを削除する。
-
R を 8 に設定する。
-
-
input が空文字列である場合、(0, true) を返す。
-
input に基数 R の数字ではないコードポイントが含まれる場合、 失敗を返す。
-
output を、input が基数 R 表記で表す数学的整数値とする。 値 0 から 15 までの数字には ASCII 16 進数字を用いる。
-
(output, validationError) を返す。
IPv6 パーサーは、 スカラー値文字列 input を取り、次の手順を実行する。これらは失敗、または IPv6 アドレスを返す。
IPv6 パーサーは理論上は直接呼び出すことができるが、 実際にそうする場合は、まずこの文書の編集者と相談してほしい。
-
pieceIndex を 0 とする。
-
compress を null とする。
-
pointer を、input に対するポインターとする。
-
c が U+003A (:) である場合:
-
remaining が U+003A (:) で始まらない場合、IPv6-invalid-compression 検証エラーとし、失敗を返す。
-
pointer を 2 増加させる。
-
pieceIndex を 1 増加させ、その後 compress を pieceIndex に設定する。
-
-
c が EOF コードポイントでない間:
-
pieceIndex が 8 である場合、IPv6-too-many-pieces 検証エラーとし、 失敗を返す。
-
c が U+003A (:) である場合:
-
compress が非 null である場合、IPv6-multiple-compression 検証エラーとし、失敗を返す。
- pointer と pieceIndex を 1 増加させ、compress を pieceIndex に設定し、その後継続する。
-
-
value と length を 0 とする。
-
length が 4 未満であり、かつ c が ASCII 16 進数字である間、 value を value × 0x10 + 16 進数として解釈した c に設定し、 pointer と length を 1 増加させる。
-
c が U+002E (.) である場合:
-
length が 0 である場合、IPv4-in-IPv6-invalid-code-point 検証エラーとし、失敗を返す。
-
pointer を length だけ減少させる。
-
pieceIndex が 6 より大きい場合、IPv4-in-IPv6-too-many-pieces 検証エラーとし、失敗を返す。
-
numbersSeen を 0 とする。
-
c が EOF コードポイントでない間:
-
ipv4Piece を null とする。
-
numbersSeen が 0 より大きい場合:
-
c が U+002E (.) であり、かつ numbersSeen が 4 未満である場合、 pointer を 1 増加させる。
- そうでなければ、IPv4-in-IPv6-invalid-code-point 検証エラーとし、 失敗を返す。
-
-
c が ASCII 数字でない場合、IPv4-in-IPv6-invalid-code-point 検証エラーとし、 失敗を返す。
-
-
number を、10 進数として解釈した c とする。
-
ipv4Piece が null である場合、ipv4Piece を number に設定する。
-
そうでなく、ipv4Piece が 0 である場合、IPv4-in-IPv6-invalid-code-point 検証エラーとし、 失敗を返す。
-
そうでなければ、ipv4Piece を ipv4Piece × 10 + number に設定する。
-
ipv4Piece が 255 より大きい場合、IPv4-in-IPv6-out-of-range-part 検証エラーとし、 失敗を返す。
-
pointer を 1 増加させる。
-
-
address[pieceIndex] を address[pieceIndex] × 0x100 + ipv4Piece に設定する。
-
numbersSeen を 1 増加させる。
-
numbersSeen が 2 または 4 である場合、pieceIndex を 1 増加させる。
-
-
numbersSeen が 4 でない場合、IPv4-in-IPv6-too-few-parts 検証エラーとし、失敗を返す。
-
中断する。
-
-
そうでなく、c が U+003A (:) である場合:
-
pointer を 1 増加させる。
-
c が EOF コードポイントである場合、IPv6-invalid-code-point 検証エラーとし、失敗を返す。
-
-
そうでなく、c が EOF コードポイントでない場合、IPv6-invalid-code-point 検証エラーとし、失敗を返す。
-
length が 1 より大きく、かつ value が 0x10length − 1 未満である場合、IPv6-piece-leading-zero 検証 エラーとする。
-
address[pieceIndex] を value に設定する。
-
pieceIndex を 1 増加させる。
-
-
compress が非 null である場合:
-
swaps を pieceIndex − compress とする。
-
pieceIndex を 7 に設定する。
-
pieceIndex が 0 でなく、かつ swaps が 0 より大きい間、 address[pieceIndex] と address[compress + swaps − 1] を入れ替え、その後 pieceIndex と swaps の両方を 1 減少させる。
-
-
そうでなく、compress が null であり、かつ pieceIndex が 8 でない場合、 IPv6-too-few-pieces 検証エラーとし、失敗を返す。
-
address を返す。
opaque-host パーサーは、 スカラー値文字列 input を取り、次の手順を 実行する。これらは失敗、または opaque hostを返す。
-
input に 禁止されたホストコードポイントが含まれる場合、 host-invalid-code-point 検証エラーとし、失敗を返す。
-
input に、コードポイントであって URL コードポイントでも U+0025 (%) でもないものが含まれる場合、invalid-URL-unit 検証エラーとする。
-
input に U+0025 (%) が含まれ、その後に続く 2 つのコードポイントが ASCII 16 進数字でない場合、invalid-URL-unit 検証 エラーとする。
-
input に対し、C0 control percent-encode setを用いて UTF-8 パーセントエンコードを実行した結果を返す。
3.6. ホストの直列化
ホスト シリアライザーは、 ホスト host を取り、 次の手順を実行する。これらは ASCII 文字列を返す。
-
host が IPv4 アドレスである場合、host に対して IPv4 シリアライザーを実行した結果を返す。
-
そうでなく、host が IPv6 アドレスである場合、U+005B ([)、続いて host に対して IPv6 シリアライザーを実行した結果、続いて U+005D (]) を返す。
-
そうでなければ、host は ドメイン、opaque host、または empty hostであり、 host を返す。
IPv6 シリアライザーは、IPv6 アドレス address を取り、次の手順を実行する。これらは ASCII 文字列を返す。
-
output を空文字列とする。
-
compress を、address が与えられたときの IPv6 アドレスの圧縮される piece インデックスを見つける結果とする。
-
ignore0 を false とする。
-
address の pieces の インデックスの各 pieceIndex について反復する:
-
ignore0 が true であり、かつ address[pieceIndex] が 0 である場合、 継続する。
-
そうでなく、ignore0 が true である場合、ignore0 を false に設定する。
-
compress が pieceIndex である場合:
-
separator を、pieceIndex が 0 である場合は "
::"、 そうでなければ U+003A (:) とする。 -
separator を output に付加する。
-
ignore0 を true に設定し、継続する。
-
-
address[pieceIndex] を、可能な限り短い 小文字の 16 進数として表して、output に付加する。
-
pieceIndex が 7 でない場合、U+003A (:) を output に付加する。
-
-
output を返す。
このアルゴリズムには、 A Recommendation for IPv6 Address Text Representation からの推奨が必要である。 [RFC5952]
IPv6 アドレス address が与えられたときに、 IPv6 アドレスの圧縮ピースインデックスを見つけるには:
-
longestIndex を null とする。
-
longestSize を 1 とする。
-
foundIndex を null とする。
-
foundSize を 0 とする。
-
address の ピースの インデックスの各 pieceIndex について 反復する:
-
address のピース[pieceIndex] が 0 でないなら:
-
foundSize が longestSize より大きいなら、 longestIndex を foundIndex に設定し、longestSize を foundSize に設定する。
- foundIndex を null に設定する。
- foundSize を 0 に設定する。
-
-
そうでなければ:
-
foundIndex が null なら、foundIndex を pieceIndex に設定する。
-
foundSize を 1 増加させる。
-
-
-
foundSize が longestSize より大きいなら、 foundIndex を返す。
-
longestIndex を返す。
3.7. ホストの同値性
証明書比較では、ドメインの末尾のドット(あれば)を無視した同値性判定が必要です。ただし、証明書ホストはDNS長なども強制されますが、URLではここで強制されません。両者をより近づける方法や統一モデルの良案があれば、issueをファイルしてください。
4. URL
高水準では、URL、妥当な URL 文字列、URL パーサー、および URL シリアライザーは、次のように関係する:
-
URL パーサーは、任意のスカラー値文字列を取り、 失敗、または URLを返す。 さらに、0 個以上の検証エラーを記録することもある。
-
URLは、 メモリ内表現と見なすことができる。
-
妥当な URL 文字列は、URL パーサーに与えられたときに 検証エラーや 失敗を発生させない入力を定義する。すなわち、適合している、または 妥当であると見なされる入力である。
-
URL シリアライザーは、URLを取り、ASCII 文字列を返す。 (その文字列がその後構文解析された場合、その結果は、シリアライズされた 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
|
4.1. URLの表現
URL は、汎用識別子を表す構造体である。妥当な URL 文字列と区別するために、 URL レコードとも呼ばれる。
URL の スキームは、 ASCII 文字列であり、URL の種類を識別し、構文解析後にさらに処理するために URL を振り分けるために使用できる。 初期値は空文字列である。
URL の ユーザー名は、 ユーザー名を識別する ASCII 文字列である。初期値は空文字列である。
URL の パスワードは、 パスワードを識別する ASCII 文字列である。初期値は空文字列である。
URL の ホストは null または ホストである。初期値は null である。
次の表は、許可される URL の スキーム / ホストの組み合わせを示す。
| スキーム | ホスト | |||||
|---|---|---|---|---|---|---|
| ドメイン | IPv4 アドレス | IPv6 アドレス | opaque host | empty host | 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 store から削除される可能性がある一方で、フェッチは依然として
成功する必要があるためである。
次の表は、妥当な 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 パスセグメントは ASCII 文字列である。これは一般に ディレクトリーまたはファイルを指すが、事前定義された意味はない。
単一ドット 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ドライブレターで始まるといいます:
- その長さが2以上
- 最初の2コードポイントがWindowsドライブレター
- 長さが2か、3番目のコードポイントがU+002F(/)、U+005C(\)、U+003F(?)、U+0023(#)のいずれか
urlのパスを短縮するには:
4.3. URLの記述
有効なURL文字列は、相対URL(フラグメント付き)文字列または絶対URL(フラグメント付き)文字列のいずれかでなければなりません。
絶対URL(フラグメント付き)文字列は、絶対URL文字列、任意でU+0023(#)とURLフラグメント文字列が続くものです。
絶対URL文字列は、以下のいずれかでなければなりません:
-
特別スキームに ASCII 大文字・小文字無視で一致し、かつ "
file" には ASCII 大文字・小文字無視で一致しない URL スキーム 文字列で、その後に U+003A (:) と スキーム相対特別 URL 文字列が続くもの -
特別スキームに ASCII 大文字・小文字無視で一致しない URL スキーム 文字列で、その後に U+003A (:) と、次のいずれかが続くもの: スキーム相対 URL 文字列、 パス絶対非オーソリティ URL 文字列、 または 不透明パス URL 文字列
-
"
file" に ASCII 大文字・小文字無視で一致する URL スキーム 文字列で、その後に U+003A (:) と スキーム相対 file 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 文字列は、次のいずれかでなければならない:
-
- "
file" ではない 特別スキーム - "
file" - その他
- "
いずれも、任意で U+003F (?) と URL クエリ文字列が続いてもよい。
フラグメント付き相対 URL 文字列を 構文解析する場合、 null でない 基底 URLが必要である。
スキーム相対特別 URL
文字列は、
"//" で、その後に
妥当なホスト文字列、
任意で U+003A (:) と URL
ポート文字列、
任意で パス絶対 URL
文字列が続くものでなければならない。
URL ポート文字列は、次のいずれかでなければならない:
-
空文字列
-
10 進数を表す 1 個以上の ASCII 数字で、その数が 16 ビット符号なし整数であるもの。
スキーム相対 URL 文字列は、
"//" で、その後に
不透明ホストおよびポート文字列、任意で
パス絶対 URL
文字列が続くものでなければならない。
不透明ホストおよびポート文字列は、空文字列、または次のいずれかでなければならない: 妥当な 不透明ホスト文字列で、任意で U+003A (:) と URL ポート文字列が続くもの。
スキーム相対 file URL 文字列は、
"//" で、その後に任意で次のいずれかが続くものでなければならない:
-
妥当なホスト 文字列で、任意で パス絶対 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 パス区分文字列は、次のいずれかでなければならない:
-
U+002F (/) および U+003F (?) を除く 0 個以上の URL 単位で、それらを合わせたものが 単一ドット URL パス区分でも 二重ドット 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örgåsbord" > Test</ 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 描画要件が含まれる。
-
url を、input に対して 基本 URL パーサーを base および encoding とともに実行した結果とする。
-
url が失敗であるなら、失敗を返す。
-
url のスキームが "
blob" でないなら、url を返す。 -
url のblob URL エントリーを、 blob URL を解決する url の結果に設定する。 それが失敗を返さなかった場合はその結果に、そうでなければ null に設定する。
-
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 を変更し、何も返さずに終了することがある。
-
url が与えられていない場合:
-
url を新しい URL に設定する。
-
input に先頭または末尾の C0 制御文字または空白が含まれているなら、 invalid-URL-unit 検証エラー。
-
input から、先頭および末尾の C0 制御文字または空白を除去する。
-
-
input に ASCII タブまたは改行が含まれているなら、 invalid-URL-unit 検証 エラー。
-
input からすべての ASCII タブまたは改行を除去する。
-
state を、state override が与えられている場合はそれ、 そうでなければ scheme start state とする。
-
encoding を、encoding から 出力エンコーディングを取得する結果に設定する。
-
buffer を空文字列とする。
-
atSignSeen、insideBrackets、および passwordTokenSeen を false とする。
-
pointer を input の ポインターとする。
-
state で分岐して、次の状態機械を実行し続ける。実行後に pointer が EOF 符号位置を指している場合は、次の手順へ進む。 そうでなければ、pointer を 1 増やし、状態機械を継続する。
- scheme start state
-
-
c が ASCII 英字であるなら、 c を 小文字化したものを buffer に付加し、 state を scheme state に設定する。
-
そうでなく、state override が与えられていない場合、 state を no scheme state に設定し、pointer を 1 減らす。
-
そうでなければ、失敗を返す。
-
- scheme state
-
-
c が ASCII 英数字、U+002B (+)、U+002D (-)、または U+002E (.) であるなら、 c を 小文字化したものを buffer に付加する。
-
そうでなく、c が U+003A (:) であるなら、次を行う:
-
state override が与えられている場合、次を行う:
-
url のスキームを buffer に設定する。
-
state override が与えられている場合、次を行う:
-
buffer を空文字列に設定する。
-
url のスキームが "
file" であるなら、 次を行う:-
remaining が "
//" で始まらないなら、 special-scheme-missing-following-solidus 検証エラー。 -
state を file state に設定する。
-
-
そうでなく、url が 特別であり、base が 非 null であり、 base のスキームが url の スキームであるなら:
-
state を special relative or authority state に設定する。
-
そうでなく、url が 特別であるなら、state を special authority slashes state に設定する。
-
そうでなく、remaining が U+002F (/) で始まるなら、 state を path or authority state に設定し、 pointer を 1 増やす。
-
そうでなければ、url の パスを 空文字列に設定し、 state を opaque path state に設定する。
-
-
そうでなく、state override が与えられていない場合、 buffer を空文字列に設定し、state を no scheme state に設定し、(input の最初の符号位置から) 最初からやり直す。
-
そうでなければ、失敗を返す。
この失敗の通知は、
Locationオブジェクトのprotocolセッターによってのみ使用される。さらに、この状態における前述の非失敗終了は、 そのセッターを定義するための意図的な差異である。
-
- no scheme state
-
-
base が null であるか、または base が 不透明パスを持ち、 c が U+0023 (#) でないなら、 missing-scheme-non-relative-URL 検証エラー、 失敗を返す。
-
そうでなく、base が 不透明パスを持ち、 c が U+0023 (#) であるなら、url の スキームを base の スキームに、 url の パスを base の パスに、 url の クエリを base の クエリに、 url の フラグメントを空文字列に設定し、 state を fragment state に設定する。
-
そうでなく、base のスキームが "
file" でないなら、 state を relative state に設定し、 pointer を 1 減らす。 -
そうでなければ、state を file state に設定し、pointer を 1 減らす。
-
- special relative or authority state
-
-
c が U+002F (/) であり、 remaining が U+002F (/) で始まるなら、state を special authority ignore slashes state に設定し、 pointer を 1 増やす。
-
そうでなければ、special-scheme-missing-following-solidus 検証エラーとし、 state を relative state に設定し、 pointer を 1 減らす。
-
- path or authority state
-
-
c が U+002F (/) であるなら、 state を authority state に設定する。
-
そうでなければ、state を path state に設定し、pointer を 1 減らす。
-
- relative state
-
-
Assert:base のスキームは "
file" でない。 -
c が U+002F (/) であるなら、 state を relative slash state に設定する。
-
そうでなく、url が 特別であり、c が U+005C (\) であるなら、 invalid-reverse-solidus 検証エラーとし、state を relative slash state に設定する。
-
そうでなければ:
-
url のユーザー名を base のユーザー名に、 url のパスワードを base のパスワードに、 url のホストを base のホストに、 url のポートを base のポートに、 url のパスを base のパスの クローンに、 そして url のクエリを base のクエリに設定する。
-
c が U+003F (?) であるなら、url の クエリ を空文字列に設定し、state を query state に設定する。
-
そうでなく、c が U+0023 (#) であるなら、url の フラグメントを 空文字列に設定し、state を fragment state に設定する。
-
-
url のクエリを null に設定する。
-
state を path state に設定し、pointer を 1 減らす。
-
-
-
- relative slash state
-
-
url が 特別であり、c が U+002F (/) または U+005C (\) であるなら:
-
c が U+005C (\) であるなら、invalid-reverse-solidus 検証エラー。
-
state を special authority ignore slashes state に設定する。
-
-
そうでなく、c が U+002F (/) であるなら、state を authority state に設定する。
-
そうでなければ、 url のユーザー名を base のユーザー名に、 url のパスワードを base のパスワードに、 url のホストを base のホストに、 url のポートを base のポートに、 state を path state に設定し、その後、 pointer を 1 減らす。
-
- special authority slashes state
-
-
c が U+002F (/) であり、 remaining が U+002F (/) で始まるなら、state を special authority ignore slashes state に設定し、 pointer を 1 増やす。
-
そうでなければ、special-scheme-missing-following-solidus 検証エラーとし、 state を special authority ignore slashes state に設定し、 pointer を 1 減らす。
-
- 特殊 authority スラッシュ無視状態
-
-
c が U+002F (/) でも U+005C (\) でもない場合、state を authority 状態に設定し、 pointer を 1 減少させる。
-
そうでなければ、special-scheme-missing-following-solidus 検証エラーとする。
-
- authority 状態
-
-
c が U+0040 (@) である場合:
-
atSignSeen が true である場合、"
%40" を buffer の先頭に追加する。 -
atSignSeen を true に設定する。
-
buffer 内の各 codePoint について:
-
codePoint が U+003A (:) であり、かつ passwordTokenSeen が false である場合、 passwordTokenSeen を true に設定し、継続する。
-
encodedCodePoints を、 codePoint に対し userinfo percent-encode setを用いて UTF-8 パーセントエンコードを 実行した結果とする。
-
passwordTokenSeen が true である場合、 encodedCodePoints を url の パスワードに付加する。
-
そうでなければ、encodedCodePoints を url の ユーザー名に付加する。
-
-
buffer を空文字列に設定する。
-
そうでなく、次のいずれかが true である場合:
-
c が EOF コードポイント、U+002F (/)、U+003F (?)、または U+0023 (#) である
その場合:
-
atSignSeen が true であり、かつ buffer が空文字列である場合、 host-missing 検証 エラーとし、失敗を返す。
-
pointer を buffer の コードポイント長 + 1 だけ減少させ、 buffer を空文字列に設定し、 state を host 状態に設定する。
-
-
そうでなければ、c を buffer に付加する。
-
- host 状態
- hostname 状態
-
-
state override が与えられており、かつ url の スキームが "
file" である場合、pointer を 1 減少させ、state を file host 状態に設定する。 -
そうでなく、c が U+003A (:) であり、かつ insideBrackets が false である場合:
-
buffer が空文字列である場合、host-missing 検証エラーとし、 失敗を返す。
-
state override が与えられており、かつ state override が hostname 状態である場合、失敗を返す。
-
host が失敗である場合、失敗を返す。
-
-
そうでなく、次のいずれかが true である場合:
-
c が EOF コードポイント、U+002F (/)、U+003F (?)、または U+0023 (#) である
その場合、pointer を 1 減少させ、その後:
-
url が特殊であり、かつ buffer が 空文字列である場合、 host-missing 検証 エラーとし、失敗を返す。
-
そうでなく、state override が与えられており、buffer が 空文字列であり、かつ url が資格情報を含む、または url の ポートが非 null である場合、失敗を返す。
-
host が失敗である場合、失敗を返す。
-
url のホストを host に、buffer を空文字列に設定し、 state を path start 状態に設定する。
-
state override が与えられている場合、戻る。
-
-
そうでなければ:
-
- port 状態
-
-
そうでなく、次のいずれかが true である場合:
-
c が EOF コードポイント、U+002F (/)、U+003F (?)、または U+0023 (#) である;
-
state override が与えられている、
その場合:
-
buffer が空文字列でない場合:
-
port を、0 から 9 までの値を持つ数字に ASCII 数字を用いて、 buffer が基数 10 で表す数学的整数値とする。
-
port が 16 ビット符号なし 整数でない場合、 port-out-of-range 検証エラーとし、失敗を返す。
-
port が url のスキームの既定ポートである場合、 url のポートを null に設定し、 そうでなければ port に設定する。
-
buffer を空文字列に設定する。
-
state override が与えられている場合、戻る。
-
-
state override が与えられている場合、失敗を返す。
-
state を path start 状態に設定し、 pointer を 1 減少させる。
-
-
そうでなければ、port-invalid 検証 エラーとし、失敗を返す。
- file 状態
-
-
url のスキームを "
file" に設定する。 -
url のホストを空文字列に設定する。
-
c が U+002F (/) または U+005C (\) である場合:
-
c が U+005C (\) である場合、invalid-reverse-solidus 検証エラーとする。
-
state を file slash 状態に設定する。
-
-
そうでなく、base が非 null であり、かつ base のスキームが "
file" である場合:-
url のホストを base のホストに、 url のパスを base の パスの複製に、そして url のクエリーを base の クエリーに設定する。
-
c が U+003F (?) である場合、url のクエリーを 空文字列に設定し、state を query 状態に設定する。
-
そうでなく、c が U+0023 (#) である場合、url のフラグメントを 空文字列に設定し、state を fragment 状態に設定する。
-
そうでなく、c が EOF コードポイントでない場合:
-
url のクエリーを null に設定する。
-
pointer から input の末尾までの コード ポイント部分文字列が Windows ドライブ文字で始まらない場合、 url の パスを短縮する。
-
そうでなければ:
-
url のパスを « » に設定する。
これは(プラットフォーム非依存の)Windows ドライブ文字の癖である。
-
state を path 状態に設定し、 pointer を 1 減少させる。
-
-
-
そうでなければ、state を path 状態に設定し、pointer を 1 減少させる。
-
- file slash 状態
-
-
c が U+002F (/) または U+005C (\) である場合:
-
c が U+005C (\) である場合、invalid-reverse-solidus 検証エラーとする。
-
state を file host 状態に設定する。
-
-
そうでなければ:
-
base が非 null であり、かつ base のスキームが "
file" である場合:-
pointer から input の末尾までのコード ポイント部分文字列が Windows ドライブ文字で始まらず、かつ base のパス[0] が 正規化された Windows ドライブ文字である場合、base の パス[0] を url のパスに付加する。
これは(プラットフォーム非依存の)Windows ドライブ文字の癖である。
-
state を path 状態に設定し、 pointer を 1 減少させる。
-
-
- file host 状態
-
-
c が EOF コードポイント、U+002F (/)、U+005C (\)、 U+003F (?)、または U+0023 (#) である場合、pointer を 1 減少させ、その後:
-
state override が与えられておらず、かつ buffer が Windows ドライブ文字である場合、file-invalid-Windows-drive-letter-host 検証エラーとし、 state を path 状態に設定する。
これは(プラットフォーム非依存の)Windows ドライブ 文字の癖である。ここでは buffer はリセットされず、代わりに path 状態で使用される。
-
そうでなく、buffer が空文字列である場合:
-
url のホストを空文字列に設定する。
-
state override が与えられている場合、戻る。
-
state を path start 状態に設定する。
-
-
そうでなければ、次の手順を実行する:
-
host が失敗である場合、失敗を返す。
-
host が "
localhost" である場合、 host を 空文字列に設定する。 -
url のホストを host に設定する。
-
state override が与えられている場合、戻る。
-
buffer を空文字列に設定し、state を path start 状態に設定する。
-
-
そうでなければ、c を buffer に付加する。
-
- path start 状態
-
-
url が特殊である場合:
-
c が U+005C (\) である場合、invalid-reverse-solidus 検証エラーとする。
-
state を path 状態に設定する。
-
c が U+002F (/) でも U+005C (\) でもない場合、pointer を 1 減少させる。
-
-
そうでなく、state override が与えられておらず、かつ c が U+003F (?) である場合、 url のクエリーを空文字列に設定し、 state を query 状態に設定する。
-
そうでなく、state override が与えられておらず、かつ c が U+0023 (#) である場合、 url のフラグメントを空文字列に設定し、 state を fragment 状態に設定する。
-
そうでなく、c が EOF コードポイントでない場合:
-
そうでなく、state override が与えられており、かつ url の ホストが null である場合、空文字列を url の パスに付加する。
-
- path 状態
-
-
次のいずれかが true である場合:
-
c が EOF コードポイントまたは U+002F (/) である
-
state override が与えられておらず、かつ c が U+003F (?) または U+0023 (#) である
その場合:
-
url が特殊であり、かつ c が U+005C (\) である場合、 invalid-reverse-solidus 検証エラーとする。
-
buffer が 二重ドット URL パス セグメントである場合:
-
そうでなく、buffer が 単一ドット URL パス セグメントであり、かつ c が U+002F (/) ではなく、さらに url が特殊であり、c が U+005C (\) である、ということもない場合、 空文字列を url のパスに付加する。
-
そうでなく、buffer が 単一ドット URL パス セグメントでない場合:
-
buffer を空文字列に設定する。
-
c が U+003F (?) である場合、url のクエリーを 空文字列に設定し、state を query 状態に設定する。
-
c が U+0023 (#) である場合、url のフラグメントを 空文字列に設定し、state を fragment 状態に設定する。
-
-
そうでなければ、次の手順を実行する:
-
c が URL コードポイントでなく、かつ U+0025 (%) でもない場合、 invalid-URL-unit 検証エラーとする。
-
c が U+0025 (%) であり、かつ remaining が 2 つの ASCII 16 進数字で始まらない場合、invalid-URL-unit 検証エラーとする。
-
c に対し、 path percent-encode setを用いて UTF-8 パーセントエンコードを行い、 その結果を buffer に付加する。
-
-
- opaque path 状態
-
-
c が U+003F (?) である場合、 url のクエリーを空文字列に設定し、 state を query 状態に設定する。
-
そうでなく、c が U+0023 (#) である場合、url のフラグメントを 空文字列に設定し、state を fragment 状態に設定する。
-
そうでなく、c が U+0020 SPACE である場合:
-
そうでなく、c が EOF コードポイントでない場合:
-
c が URL コードポイントでなく、かつ U+0025 (%) でもない場合、 invalid-URL-unit 検証エラーとする。
-
c が U+0025 (%) であり、かつ remaining が 2 つの ASCII 16 進数字で始まらない場合、invalid-URL-unit 検証エラーとする。
-
c に対し、 C0 control percent-encode setを用いて UTF-8 パーセントエンコードを行い、 その結果を url の パスに付加する。
-
-
- query 状態
-
-
encoding が UTF-8 ではなく、かつ次のいずれかが true である場合:
その場合、encoding を UTF-8に設定する。
-
次のいずれかが true である場合:
-
state override が与えられておらず、かつ c が U+0023 (#) である
-
c が EOF コードポイントである
その場合:
-
queryPercentEncodeSet を、 url が特殊である場合は special-query percent-encode set、そうでなければ query percent-encode setとする。
-
encoding、buffer、および queryPercentEncodeSet を用いて エンコーディング後に パーセントエンコードし、その結果を url のクエリーに付加する。
この操作は、状態を持つ ISO-2022-JP エンコーダーのため、 コードポイント単位では呼び出せない。
-
buffer を空文字列に設定する。
-
c が U+0023 (#) である場合、url のフラグメントを 空文字列に設定し、state を fragment 状態に設定する。
-
-
そうでなく、c が EOF コードポイントでない場合:
-
c が URL コードポイントでなく、かつ U+0025 (%) でもない場合、 invalid-URL-unit 検証エラーとする。
-
c が U+0025 (%) であり、かつ remaining が 2 つの ASCII 16 進数字で始まらない場合、invalid-URL-unit 検証エラーとする。
-
c を buffer に付加する。
-
-
- fragment 状態
-
-
c が EOF コードポイントでない場合:
-
c が URL コードポイントでなく、かつ U+0025 (%) でもない場合、 invalid-URL-unit 検証エラーとする。
-
c が U+0025 (%) であり、かつ remaining が 2 つの ASCII 16 進数字で始まらない場合、invalid-URL-unit 検証エラーとする。
-
c に対し、 fragment percent-encode setを用いて UTF-8 パーセントエンコードを行い、 その結果を url の フラグメントに付加する。
-
-
-
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 文字列を返す。
-
output を、url のスキームと U+003A (:) を連結したものとする。
-
url のホストが非 null である場合:
-
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/になる)。 -
URL パス直列化 url の結果を output に付加する。
-
url のクエリが非 null であるなら、 U+003F (?) に続けて url のクエリを output に付加する。
-
exclude fragment が false であり、かつ url のフラグメントが 非 null であるなら、U+0023 (#) に続けて url のフラグメントを output に付加する。
-
output を返す。
4.6. URLの同値性
URL Aが等しいかどうかを、URL Bに対して、オプションの真偽値exclude fragments(デフォルトfalse)で判定するには、以下の手順を実行します:
-
serializedAをAを直列化した結果(exclude fragmentをexclude fragmentsに設定)とする。
-
serializedBをBを直列化した結果(exclude fragmentをexclude fragmentsに設定)とする。
-
serializedAがserializedBならtrue、そうでなければfalseを返す。
4.7. オリジン
オリジンの定義はHTMLを参照してください。必要な背景情報が記載されています。[HTML]
オリジンは、URL urlについて、urlのschemeで分岐し、以下の手順で得られるオリジンです:
- "
blob" -
-
urlのblob URLエントリがnullでなければ、urlのblob URLエントリのenvironmentのオリジンを返す。
-
pathURLが失敗なら新しい不透明オリジンを返す。
-
新しい不透明オリジンを返す。
blob:https://whatwg.org/d0360e2f-caee-469f-9a2f-87d5b0456f6fのオリジンは、タプルオリジン("https", "whatwg.org", null, null)です。 -
- "
ftp"- "
http"- "
https"- "
ws"- "
wss" - "
- "
file" -
残念ながらこれは読者への課題です。判断に迷った場合は、新しい不透明オリジンを返してください。
- その他
-
新しい不透明オリジンを返す。
4.8. URLのレンダリング
URLは、ユーザーがセキュリティや信頼に関する判断を行うために表示する場合、以下に記載する修正を加えた直列化済みの形でレンダリングされるべきです。例えば、ブラウザのアドレスバーではユーザーがURLを見て信頼判断をすることが期待されています。
4.8.1. 人が読めない/不要な構成要素の簡略化
なりすましやセキュリティに無関係な情報で混乱を招く構成要素を削除してください:
-
ブラウザは、ユーザーがホストと他のURL要素(pathなど)を区別する必要がある場面で、URLのhostのみをレンダリングしても構いません。また、ホストをさらに簡略化して登録可能ドメインに注目させることも可能です。例として、先頭の
wwwやmのドメインラベルを省略したり、登録可能ドメインだけを表示して、サブドメインによるなりすましの機会を減らすことができます(例:https://examplecorp.attacker.com/)。 -
ブラウザーは、URL の ユーザー名および パスワードを描画するべきではない。 それらは URL の ホストと 誤認される可能性があるためである(例:
https://examplecorp.com@attacker.example/)。 -
表示領域が常に単一のスキームのみを許可する場合(例えば、セキュアなオリジンのみ有効なブラウザ機能で
https://を省略する等)、ブラウザはURLのschemeを省略しても構いません。それ以外の場合は、schemeを人が読める文字列(例:"安全ではありません")、セキュリティアイコン、またはその両方で補足・置換しても良いです。
4.8.2. 省略表示
表示領域が限られている場合、URLの省略はユーザーに誤解を与えないよう慎重に行うべきです:
-
ブラウザーは、URL が描画されるときに、少なくとも登録可能ドメインが表示され得るようにするべきである (たとえば、
https://not-really-examplecorp.com/を読み込むときに...examplecorp.comと表示することを避けるため)。 -
完全なホストを描画できない場合、ブラウザーは 最下位レベルのドメインラベルから始めて ドメインラベルを省略するべきである。 たとえば、
examplecorp.com.evil.comはexamplecorp.com...ではなく...com.evil.comと省略されるべきである。(双方向テキストでは、最下位レベルのドメイン ラベルが左側に現れない場合があることに注意。)
4.8.3. 国際化と特殊文字
国際化ドメイン名(IDN)、特殊文字、および双方向テキストは、スプーフィングを防ぐために 注意して扱うべきである:
-
URL の ホストが ドメインである場合、ブラウザーは ドメインから Unicode へを、URL の ホストに対して実行して、 それを描画するべきである。
ホモグラフ・スプーフィング攻撃では、さまざまな文字を使用できる。 紛らわしい文字を検出し、それらが使用されているときに警告することを検討すること。 [IDNFAQ] [UTS39]
-
URL に双方向テキストが含まれる場合、ホストとパスの混同が特に起こりやすい。そのため、この場合は特に URL の ホストだけを 描画することが推奨される。読みやすさのため、URL の他の部分を描画する場合は、 パーセントエンコードされたバイトのシーケンスを、 それらのシーケンスの パーセントデコードに対して BOM なしで UTF-8 デコードを実行した結果の符号位置に 置き換えるべきである。ただし、それによってそれらのシーケンスが不可視になる場合は除く。ブラウザーは、 スプーフィングのリスクをもたらす特定のシーケンス(例:U+1F512 (🔒))をデコードしないことを選択してもよい。
-
ブラウザーは、双方向テキストを左から右への埋め込み内にあるかのように描画するべきである。[BIDI]
残念ながら、描画された URL は文字列であり、どこにでも現れ得るため、 描画された URL のための特定の双方向アルゴリズムは広く採用されないだろう。 双方向テキストは URL の各部分と相互作用し、 描画がモデルとは異なるものになる場合がある。双方向言語のユーザーは、 特にプレーンテキスト環境において、これを予期するようになることがある。
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を受け取り、以下の手順を実行します:
-
sequencesをinputを0x26(&)で分割した結果とする。
-
outputを、名前と値が文字列を保持するname-valueタプルの空のリストとする。
-
sequences内の各バイト列bytesについて:
-
bytesが空のバイト列なら、continue。
-
bytesが0x3D(=)を含むなら、nameをbytesの先頭から最初の0x3D(=)直前までのバイト列、valueを最初の0x3D(=)の直後から末尾までのバイト列(存在すれば)とする。0x3D(=)が最初のバイトならnameは空、最後ならvalueは空になる。
-
それ以外はnameにbytes、valueに空のバイト列をセットする。
-
nameとvalue内の全ての0x2B(+)を0x20(SP)に置換する。
-
nameStringとvalueStringを、それぞれnameとvalueをUTF-8 BOM無しデコード(パーセントデコードの結果)で得たものとする。
-
appendで(nameString, valueString)をoutputに追加。
-
-
outputを返す。
5.2. application/x-www-form-urlencoded の直列化
application/x-www-form-urlencoded直列化器は、name-valueタプルのリストtuplesと、省略可能なencoding encoding(デフォルトはUTF-8)を受け取り、以下の手順を実行します。返り値はASCII文字列です。
-
encoding に、出力エンコーディングを取得を encoding に対して実行した結果を設定する。
-
output を空文字列とする。
-
各 tuple in tuples について:
-
name に、 エンコード後パーセントエンコード を encoding・tuple の name・
application/x-www-form-urlencodedパーセントエンコード集合で実行した結果を設定する。 -
value に、 エンコード後パーセントエンコード を encoding・tuple の value・
application/x-www-form-urlencodedパーセントエンコード集合で実行した結果を設定する。 -
output が空文字列でなければ、U+0026 (&) を output に追加する。
-
name、U+003D (=)、value の順に output に追加する。
- 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オブジェクトには、以下が関連付けられています:
- URL: URL
- query object:
URLSearchParamsオブジェクト
initializeで、URLオブジェクト
urlをURL
urlRecordで初期化する場合:
-
queryをurlRecordのquery(nullでなければ)または空文字列とする。
-
urlのURLにurlRecordをセット。
-
urlのquery objectに新しい
URLSearchParamsオブジェクトをセットする。 -
Initializeでurlのquery objectにqueryを渡す。
-
urlのquery objectのURL objectにurlをセット。
new URL(url, base) コンストラクタの手順:
-
parsedURLをAPI URLパーサでurlとbase(もし指定されていれば)をパースした結果とする。
-
parsedURLが失敗なら、TypeError例外をスローする。
-
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) メソッドの手順:
-
parsedURLをAPI URLパーサでurlとbase(もし指定されていれば)をパースした結果とする。
-
parsedURLが失敗ならnullを返す。
-
urlを新しい
URLオブジェクトとして作成。 -
InitializeでurlをparsedURLで初期化。
-
urlを返す。
静的なcanParse(url, base)
メソッドの手順は以下の通り:
-
parsedURLを、API URL パーサーをurlとbase(指定されていれば)で実行した結果とする。
-
parsedURLが失敗の場合、falseを返す。
-
trueを返す。
href
セッターの手順は以下の通り:
protocol
セッターの手順は、与えられた値の後ろにU+003A (:)を付けて
基本URLパースを行い、
thisのURLを
urlとし、
scheme start
stateを
state overrideとして指定することである。
username
セッターの手順は以下の通り:
-
thisのURLがユーザー名/パスワード/ポートをもてない場合は、returnする。
-
Set the usernameに、thisのURLと与えられた値を渡す。
password
セッターの手順は以下の通り:
-
thisのURLがユーザー名/パスワード/ポートをもてない場合は、returnする。
-
Set the passwordに、thisのURLと与えられた値を渡す。
host getter 手順は次のとおり:
host
setter 手順は次のとおり:
-
与えられた値を 基本 URL 構文解析する。その際、this の URLを url とし、host state を state override とする。
host
setter に与えられた値に
ポートがない場合、this の URL の ポートは
変化しない。これは、host getter が URL ポート文字列を返すため、
setter が常にその両方を「リセット」すると想定していた場合には予想外であり得る。
hostname
セッター手順は次のとおりである:
-
与えられた値を、this の URLをurlとして、またホスト名状態を state overrideとして、 基本 URL 構文解析する。
port
セッター手順は次のとおりである:
-
this のURLがユーザー名/パスワード/ポートを持てないなら、 返す。
-
そうでなければ、与えられた値を、 this のURLをurlとして、 ポート状態をstate overrideとして 基本 URL 構文解析する。
pathname 取得子手順は、this のURLを
URL パス
直列化した結果を返すことである。
pathname
セッター手順は次のとおりである:
search 取得子手順は次のとおりである:
search
セッター手順は次のとおりである:
-
与えられた値が空文字列なら、url のクエリーを null に設定し、this のクエリーオブジェクトの リストを空にし、返す。
-
input を、与えられた値から先頭の U+003F (?) を 1 つ削除したもの(もしあれば)とする。
-
url のクエリーを空文字列に設定する。
-
input を、url を urlとして、またクエリー状態を state overrideとして 基本 URL 構文解析する。
-
this のクエリーオブジェクトのリストを、 input を構文解析した結果に設定する。
searchParams 取得子手順は、this のクエリー
オブジェクトを返すことである。
hash 取得子手順は次のとおりである:
hash
セッター手順は次のとおりである:
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で初期化するには:
URLSearchParams
オブジェクトqueryをupdateするには:
-
queryのURL objectがnullならreturn。
-
serializedQueryが空文字列ならserializedQueryをnullにする。
-
queryのURL objectのURLのqueryにserializedQueryをセットする。
new URLSearchParams(init)
コンストラクタの手順:
-
initが文字列かつU+003F(?)で始まる場合、最初のコードポイントをinitから削除する。
-
Initializeでthisをinitで初期化する。
delete(name, value)
メソッドの手順:
has(name, value)
メソッドの手順は以下の通り:
set(name, value)
メソッドの手順は以下の通り:
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() メソッドの手順は以下の通り:
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 ライセンス の下で提供されます。
これは現行標準です。 特許レビュー版に関心がある方は現行標準レビュー草案をご覧ください。