目標
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がエラーを記録するか空文字列を返します。 [UTS46] もしUnicode ToASCIIのエラー詳細が記録されている場合は、ユーザーエージェントはそれを伝達することが推奨されます。 | はい |
domain-invalid-code-point |
入力のホストに禁止ドメインコードポイントが含まれています。 | はい |
domain-to-Unicode |
Unicode ToUnicodeがエラーを記録します。[UTS46] domain-to-ASCIIの場合と同様の考慮事項が適用されます。 | · |
ホスト解析 | ||
host-invalid-code-point |
不透明ホスト(特別ではないURLの場合)に禁止ホストコードポイントが含まれています。 | はい |
IPv4-empty-part |
IPv4アドレスがU+002E(.)で終わっています。 | · |
IPv4-too-many-parts |
IPv4アドレスが4つの部分で構成されていません。 | はい |
IPv4-non-numeric-part |
IPv4アドレスの一部が数値ではありません。 | はい |
IPv4-non-decimal-part |
IPv4アドレスに、16進数または8進数で表現された数字が含まれています。 | · |
IPv4-out-of-range-part |
IPv4アドレスの一部が255を超えています。 | はい (最後の部分に該当する場合のみ) |
IPv6-unclosed |
IPv6アドレスの終端にU+005D(])がありません。 | はい |
IPv6-invalid-compression |
IPv6アドレスの圧縮開始が不正です。 | はい |
IPv6-too-many-pieces |
IPv6アドレスの部分が8つを超えています。 | はい |
IPv6-multiple-compression |
IPv6アドレスが2箇所以上で圧縮されています。 | はい |
IPv6-invalid-code-point |
IPv6アドレスに、ASCII 16進数字でもU+003A(:)でもないコードポイントが含まれているか、予期せぬ終了があります。 | はい |
IPv6-too-few-pieces |
圧縮されていないIPv6アドレスの部分が8つ未満です。 | はい |
IPv4-in-IPv6-too-many-pieces | はい | |
IPv4-in-IPv6-invalid-code-point |
| はい |
IPv4-in-IPv6-out-of-range-part | はい | |
IPv4-in-IPv6-too-few-parts | はい | |
URL解析 | ||
invalid-URL-unit |
URL単位でないコードポイントが見つかりました。 | · |
special-scheme-missing-following-solidus |
入力のスキームの後に「 | · |
missing-scheme-non-relative-URL |
入力にスキームがありません。ASCII英字で始まっておらず、基本URLが与えられていないか、基本URLが不透明パスを持つため、基本URLとして利用できません。 | はい |
invalid-reverse-solidus |
URLが特別なスキームを持ち、U+005C(\)をU+002F(/)の代わりに使っています。 | · |
invalid-credentials |
入力が認証情報を含みます。 | · |
host-missing | はい | |
port-out-of-range |
入力のポートが大きすぎます。 | はい |
port-invalid |
入力のポートが無効です。 | はい |
file-invalid-Windows-drive-letter |
入力が相対URL文字列で、Windowsドライブレターで始まり、基本URLのスキームが「
| · |
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つのASCII16進数字が続くものです。
パーセントエンコードされたバイト列をパーセントデコードし、BOMなしのUTF-8デコード(failあり)に渡したとき、失敗しないようなものにするのが一般的に良い考えです。どこで使われるかによって重要度は異なります。例えば、ホストパーサーの場合、この注意に従わないと致命的ですが、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(~)より大きい全てのコードポイントです。
fragmentパーセントエンコードセットは、C0コントロールパーセントエンコードセット及び U+0020(スペース)、U+0022(")、U+003C(<)、U+003E(>)、U+0060(`)です。
queryパーセントエンコードセットは、C0コントロールパーセントエンコードセット及び U+0020(スペース)、U+0022(")、U+0023(#)、U+003C(<)、U+003E(>)です。
queryパーセントエンコードセットは、U+0060(`)が省かれているため、fragmentパーセントエンコードセットの定義を流用できません。
special-queryパーセントエンコードセットは、queryパーセントエンコードセット及び U+0027(')です。
pathパーセントエンコードセットは、queryパーセントエンコードセット及びU+003F(?)、U+005E(^)、U+0060(`)、U+007B({)、U+007D(})です。
userinfoパーセントエンコードセットは、pathパーセントエンコードセット及びU+002F(/)、U+003A(:)、U+003B(;)、U+003D(=)、U+0040(@)、U+005B([)からU+005D(])(両端含む)、U+007C(|)です。
componentパーセントエンコードセットは、userinfoパーセントエンコードセット及び U+0024($)からU+0026(&)(両端含む)、U+002B(+)、U+002C(,)です。
これはHTMLのregisterProtocolHandler()
で使われており、他の標準でも
URLのpath、query、fragment、またはopaque hostに埋め込むデータのパーセントエンコードにも利用できます。UTF-8パーセントエンコードと組み合わせると、JavaScriptのencodeURIComponent()
[sic]と同じ結果になります。[HTML] [ECMA-262]
application/x-www-form-urlencoded
パーセントエンコードセットは、componentパーセントエンコードセット及びU+0021(!)、U+0027(')からU+0029(右括弧)(両端含む)、U+007E(~)です。
application/x-www-form-urlencoded
パーセントエンコードセットは、
ASCII英数字、U+002A(*)、U+002D(-)、U+002E(.)、U+005F(_)以外の全てのコードポイントを含みます。
encoding encoding、スカラー値文字列 input、percentEncodeSet、省略可能な真偽値spaceAsPlus(デフォルトfalse)を与えて、エンコード後パーセントエンコードするには:
-
encoderをencodingからエンコーダーを取得した結果とする。
-
inputQueueをinputをI/Oキューに変換したものとする。
-
outputを空文字列とする。
-
potentialErrorを0とする。
これは次のwhileループを開始するために非null値が必要です。
-
potentialErrorが非nullの間:
-
encodeOutputを空のI/Oキューとする。
-
potentialErrorにエンコードまたは失敗をinputQueue、encoder、encodeOutputで実行した結果をセットする。
-
encodeOutputをバイト列に変換した各byteについて:
-
spaceAsPlusがtrueでbyteが0x20(SP)なら、U+002B(+)をoutputに追加し、continueする。
-
アサート:percentEncodeSetは全ての非ASCIIコードポイントを含む。
-
isomorphがpercentEncodeSetに含まれていなければ、そのままoutputに追加する。
-
それ以外の場合はbyteをパーセントエンコードし、結果をoutputに追加する。
-
-
potentialErrorが非nullなら、"
%26%23
"とpotentialErrorの10進ASCII数字による最短列、さらに"%3B
"をoutputに追加する。encodingがUTF-8でない場合に起こり得ます。
-
-
outputを返す。
percentEncodeSet引数の値のうち、U+0025(%)をエンコードして「ラウンドトリップ可能なデータ」を与えるのは、コンポーネントパーセントエンコードセットとapplication/x-www-form-urlencoded
パーセントエンコードセットだけです。他の値(URLパーサーが使うもの)はU+0025(%)をそのまま残すため、正しく表現するにはまずパーセントエンコードする必要があります。
スカラー値 scalarValueをpercentEncodeSetでUTF-8パーセントエンコードするには、エンコード後パーセントエンコードをUTF-8、scalarValue(文字列として)、percentEncodeSetで実行した結果を返します。
スカラー値文字列 inputをpercentEncodeSetでUTF-8パーセントエンコードするには、エンコード後パーセントエンコードを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、ユーザー情報パーセントエンコードセット、true) | "1+1 ≡ 2%20‽ "
| "1+1+%81%DF+2%20%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またはPublic Suffix Listに含まれるhostの一部を表すドメインを返します。[PSL]
-
hostがドメインでなければ、nullを返す。
-
hostが「
.
」で終わるならtrailingDotを「.
」、そうでなければ空文字列とする。 -
publicSuffixをPublic Suffix Listアルゴリズムでhostをドメインとして実行した結果とする。[PSL]
-
アサート:publicSuffixは「
.
」で終わらないASCII文字列。 -
publicSuffixとtrailingDotを連結して返す。
ホスト hostの登録可能ドメインを取得するには、以下の手順を実行します。これはnullまたはhostのパブリックサフィックスとその直前のドメインラベルから構成されるドメインを返します。
-
hostのパブリックサフィックスがnull、またはhostのパブリックサフィックスがhostと等価なら、nullを返す。
-
hostが「
.
」で終わるならtrailingDotを「.
」、そうでなければ空文字列とする。 -
registrableDomainをPublic Suffix Listアルゴリズムでhostをドメインとして実行した結果とする。[PSL]
-
アサート:registrableDomainは「
.
」で終わらないASCII文字列。 -
registrableDomainとtrailingDotを連結して返す。
ホスト入力 | パブリックサフィックス | 登録可能ドメイン |
---|---|---|
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 to ASCIIアルゴリズムは、文字列 domainと真偽値beStrictを受け取り、以下の手順を実行します:
-
resultを、domain_nameにdomain、CheckHyphensにbeStrict、CheckBidiにtrue、CheckJoinersにtrue、UseSTD3ASCIIRulesにbeStrict、Transitional_Processingにfalse、VerifyDnsLengthにbeStrict、IgnoreInvalidPunycodeにfalseをセットしてUnicode ToASCIIを実行した結果とする。[UTS46]
beStrictがfalseで、domainがASCII文字列かつ、domainをU+002E(.)で厳密分割して得られる各要素が、ASCII大文字小文字区別せずに"
xn--
"で始まらない場合、このステップはdomainのASCII小文字化と同等です。 -
resultが失敗値なら、domain-to-ASCII バリデーションエラーとして失敗を返す。
-
beStrictがfalseの場合:
-
resultが空文字列なら、domain-to-ASCII バリデーションエラーとして失敗を返す。
-
resultに禁止ドメインコードポイントが含まれていれば、domain-invalid-code-point バリデーションエラーとして失敗を返す。
Web互換性やDNS以外のシステムとの互換性のため、禁止ドメインコードポイントはUseSTD3ASCIIRulesがtrueの場合の不許可セットの部分集合です。issue #397も参照。
-
-
アサート:resultは空文字列ではなく、禁止ドメインコードポイントを含まない。
Unicode IDNA Compatibility ProcessingはbeStrictがtrueの場合、これを保証します。[UTS46]
-
resultを返す。
この文書とWebプラットフォーム全体ではUnicode IDNA Compatibility
Processingを使用しており、IDNA2008は使用しません。例えば、☕.example
はxn--53h.example
となり、失敗にはなりません。[UTS46] [RFC5890]
domain to Unicodeアルゴリズムは、ドメイン domainと真偽値beStrictを受け取り、以下の手順を実行します:
-
resultを、domain_nameにdomain、CheckHyphensにbeStrict、CheckBidiにtrue、CheckJoinersにtrue、UseSTD3ASCIIRulesにbeStrict、Transitional_Processingにfalse、IgnoreInvalidPunycodeにfalseをセットしてUnicode ToUnicodeを実行した結果とする。[UTS46]
-
返されたエラーに対してdomain-to-Unicode バリデーションエラーを示し、その後resultを返す。
3.4. ホストの記述
有効なホスト文字列は、有効なドメイン文字列、有効なIPv4アドレス文字列、またはU+005B([)、有効なIPv6アドレス文字列、U+005D(])のいずれかでなければなりません。
文字列 inputは、次の手順でtrueを返す場合、有効なドメインです:
-
domainをinputとtrueでdomain to ASCIIした結果とする。
-
domainが失敗ならfalse、そうでなければtrueを返す。
理想的には、有効なドメインを構成するコードポイント列で定義したいが、現状は個別対応になっている:issue 245参照。
有効なドメイン文字列は、有効なドメインである文字列でなければなりません。
有効なIPv4アドレス文字列は、0~255の範囲の10進数を表すASCII数字による最短文字列4つをU+002E(.)で区切ったものです。
有効なIPv6アドレス文字列は、IP Version 6 Addressing Architectureの「Text Representation of Addresses」章で定義されています。[RFC4291]
有効な不透明ホスト文字列は、以下のいずれかでなければなりません:
-
禁止ホストコードポイントを除く1つ以上のURL単位
-
U+005B([)、有効なIPv6アドレス文字列、U+005D(])
これは有効なホスト文字列の定義には含まれません。区別には文脈が必要なためです。
3.5. ホストの解析
ホストパーサーは、スカラー値文字列 inputと省略可能な真偽値isOpaque(デフォルトfalse)を受け取り、以下の手順を実行します。失敗またはホストを返します。
-
inputがU+005B([)で始まる場合:
-
inputがU+005D(])で終わらなければ、IPv6-unclosed バリデーションエラーとして失敗を返す。
-
先頭のU+005B([)と末尾のU+005D(])を除いたinputをIPv6解析した結果を返す。
-
-
isOpaqueがtrueなら、inputを不透明ホスト解析した結果を返す。
-
アサート:inputは空文字列ではない。
-
domainをinputのパーセントデコードにBOMなしUTF-8デコードした結果とする。
あるいはBOMなしUTF-8デコード(failあり)を使い、失敗なら早期リターンも可。domain to ASCIIはU+FFFD(�)で失敗します。
-
asciiDomainをdomainとfalseでdomain to ASCIIした結果とする。
-
asciiDomainが失敗なら失敗を返す。
-
asciiDomainを返す。
数字で終わるか判定は、ASCII文字列 inputを受け取り、以下の手順を実行します。真偽値を返します。
IPv4パーサーは、ASCII文字列 inputを受け取り、以下の手順を実行します。失敗またはIPv4アドレスを返します。
IPv4パーサーは直接呼び出さず、ホストパーサーの返値がIPv4アドレスかどうかで判断すること。
-
partsをinputをU+002E(.)で厳密分割した結果とする。
-
partsの最後の要素が空文字列なら:
-
partsのサイズが4を超えるなら、IPv4-too-many-parts バリデーションエラーとして失敗を返す。
-
numbersを空のリストとする。
-
各 partに対して:
-
resultをpartをIPv4数値解析した結果とする。
-
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とする。
-
各 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の先頭1文字を削除する。
-
Rを8にする。
-
-
inputが空文字列なら(0, true)を返す。
-
inputに基数Rの数字でないコードポイントが含まれていれば失敗を返す。
-
outputをinputを基数Rとし、0~15はASCII16進数字として表した整数値とする。
-
(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をセットし、continueする。
-
-
valueとlengthを0とする。
-
lengthが4未満かつcがASCII16進数字である間、valueをvalue×0x10 + c(16進数)として、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をcを10進数とした値とする。
-
ipv4Pieceがnullなら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 バリデーションエラーとして失敗を返す。
-
breakする。
-
-
そうでなければcがU+003A(:)なら:
-
pointerを1増やす。
-
cがEOFコードポイントなら、IPv6-invalid-code-point バリデーションエラーとして失敗を返す。
-
-
そうでなくcがEOFコードポイントでなければ、IPv6-invalid-code-point バリデーションエラーとして失敗を返す。
-
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を返す。
不透明ホストパーサーは、スカラー値文字列 inputを受け取り、以下の手順を実行します。失敗または不透明ホストを返します。
-
inputに禁止ホストコードポイントが含まれていれば、host-invalid-code-point バリデーションエラーとして失敗を返す。
-
inputにコードポイントでURLコードポイントでないもの、かつU+0025(%)でないものが含まれていれば、invalid-URL-unit バリデーションエラー。
-
inputにU+0025(%)が含まれていて、直後の2つのコードポイントがASCII16進数字でなければ、invalid-URL-unit バリデーションエラー。
-
inputをUTF-8パーセントエンコード(C0制御パーセントエンコードセット使用)した結果を返す。
3.6. ホストの直列化
ホストシリアライザーは、ホスト hostを受け取り、以下の手順を実行します。ASCII文字列を返します。
-
hostがIPv4アドレスなら、hostにIPv4シリアライザーを実行した結果を返す。
-
そうでなくhostがIPv6アドレスなら、U+005B([)、hostにIPv6シリアライザーを実行した結果、U+005D(])の順で返す。
IPv4シリアライザーは、IPv4アドレス addressを受け取り、以下の手順を実行します。ASCII文字列を返します。
IPv6シリアライザーは、IPv6アドレス addressを受け取り、以下の手順を実行します。ASCII文字列を返します。
-
outputを空文字列とする。
-
compressをaddressにIPv6アドレス圧縮ピースインデックス探索を実行した結果とする。
-
ignore0をfalseとする。
-
outputを返す。
このアルゴリズムは「A Recommendation for IPv6 Address Text Representation」の推奨に従う必要があります。[RFC5952]
IPv6アドレス圧縮ピースインデックス探索は、IPv6アドレス addressを受け取り:
-
longestIndexをnullとする。
-
longestSizeを1とする。
-
foundIndexをnullとする。
-
foundSizeを0とする。
-
-
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://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/
| ❌ | 失敗 | |
example
| ❌(基準不足) | 失敗 | |
https://example.com:demo
| ❌ | 失敗 | |
http://[www.example.com]/
| ❌ | 失敗 | |
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のユーザー名は、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 entry)を持ちます。初期値は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 | null | « "ada ", "Analytical%20Engine ", "README.md " »
| null | null |
URLパスは、URLパスセグメントまたは0個以上のリスト(URLパスセグメントのリスト)です。
URLパスセグメントはASCII文字列です。一般的にはディレクトリやファイルを指しますが、固定の意味はありません。
単一ドットURLパスセグメントは、URLパスセグメントで".
"または"%2e
"(ASCII大文字小文字区別せず一致)です。
二重ドットURLパスセグメントは、URLパスセグメントで"..
"または".%2e
"、"%2e.
"、"%2e%2e
"(ASCII大文字小文字区別せず一致)です。
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文字列は、以下のいずれかでなければなりません:
-
URLスキーム文字列がASCII大文字小文字区別せず特別なスキームに一致し、"
file
"には一致しないもの、U+003A(:)、スキーム相対特別URL文字列が続くもの -
URLスキーム文字列がASCII大文字小文字区別せず特別なスキームでないもの、U+003A(:)、相対URL文字列が続くもの
-
URLスキーム文字列がASCII大文字小文字区別せず"
file
"に一致するもの、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文字列は、基準URLのスキームによって次のいずれかになります:
- 特別なスキーム("
file
"を除く) -
- "
file
" -
パス絶対URL文字列(基準URLのホストが空ホストの場合)
Windows以外パス絶対file-URL文字列(基準URLのホストが空ホストでない場合)
- その他
-
いずれも任意でU+003F(?)、URLクエリ文字列が続く場合があります。
基準URLが非nullであることは、相対URL文字列の解析時に必要です。
スキーム相対特別URL文字列は、"//
"、有効なホスト文字列、任意でU+003A(:)、URLポート文字列、任意でパス絶対URL文字列が続くものです。
URLポート文字列は、次のいずれかでなければなりません:
-
空文字列
-
1つ以上のASCII数字(0〜65535の範囲)
スキーム相対URL文字列は、"//
"、不透明ホスト+ポート文字列、任意でパス絶対URL文字列が続くものです。
不透明ホスト+ポート文字列は、空文字列または有効な不透明ホスト文字列、任意でU+003A(:)、URLポート文字列です。
スキーム相対file-URL文字列は、"//
"、次のいずれか:
パス絶対URL文字列は、U+002F(/)、パス相対URL文字列が続くものです。
Windows以外パス絶対file-URL文字列は、パス絶対URL文字列で、U+002F(/)とWindowsドライブレター、U+002F(/)の並びで始まらないものです。
パス相対URL文字列は、0個以上のURLパスセグメント文字列をU+002F(/)で区切ったもの(先頭はU+002F(/)で始まらない)です。
スキームレスパス相対URL文字列は、パス相対URL文字列で、URLスキーム文字列、U+003A(:)で始まらないものです。
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((), U+0029()), 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では、文書エンコーディングがレガシーエンコーディングの場合、URLクエリ文字列内でU+007F(DELETE)より大きいコードポイントは文書のエンコーディングでパーセントエンコードされたバイトに変換されます。異なるエンコーディングの文書間で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、base、encodingで基本URLパーサーした結果とする。
-
urlが失敗なら失敗を返す。
-
urlのスキームが"
blob
"でなければurlを返す。 -
urlのblob URLエントリをblob 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があればそれを、なければスキーム開始状態とする。
-
encodingをencodingから出力エンコーディング取得した結果にセットする。
-
bufferを空文字列とする。
-
atSignSeen、insideBrackets、passwordTokenSeenをfalseとする。
-
pointerをinput用のポインターとする。
-
以下の状態機械をstateに応じて切り替えながら実行し続ける。もし実行後にpointerがEOFコードポイントを指していたら次のステップに進む。そうでなければpointerを1増やして状態機械を続ける。
- スキーム開始状態
- スキーム状態
-
-
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状態にセットする。
-
-
それ以外でurlが特別でbaseがnullでなく、baseのスキームがurlのスキームなら:
-
アサート:baseは特別(不透明パスを持たない)。
-
stateをspecial relative or authority状態にセットする。
-
-
それ以外でurlが特別なら、stateをspecial authority slashes状態にセットする。
-
それ以外でremainingがU+002F(/)で始まるなら、stateをpath or authority状態にし、pointerを1増やす。
-
-
それ以外でstate overrideが指定されていなければ、bufferを空文字列、stateを非スキーム状態にし、inputの最初からやり直す。
-
それ以外なら失敗を返す。
この失敗は
Location
オブジェクトのprotocol
セッター専用です。また前段の非失敗returnはこのセッター定義のための意図的な差異です。
-
- 非スキーム状態
-
-
baseがnull、またはbaseが不透明パスを持ち、cがU+0023(#)でなければ、missing-scheme-non-relative-URL バリデーションエラー、失敗を返す。
-
それ以外でbaseが不透明パスを持ち、cがU+0023(#)なら、urlのschemeにbaseのschemeを、urlのpathにbaseのpathを、urlのqueryにbaseのqueryを、urlのfragmentに空文字列をセットし、stateをfragment状態にする。
-
それ以外でbaseのschemeが"
file
"でなければ、stateをrelative状態にし、pointerを1減らす。 -
それ以外はstateをfile状態にし、pointerを1減らす。
-
- special relative or authority状態
-
-
cがU+002F(/)で、remainingがU+002F(/)で始まるなら、stateをspecial authority ignore slashes状態にし、pointerを1増やす。
-
それ以外はspecial-scheme-missing-following-solidus バリデーションエラー、stateをrelative状態にし、pointerを1減らす。
-
- path or authority状態
-
-
cがU+002F(/)なら、stateをauthority状態にする。
-
それ以外はstateをpath状態にし、pointerを1減らす。
-
- relative状態
-
-
アサート:baseのschemeは"
file
"でない。 -
cがU+002F(/)なら、stateをrelative slash状態にする。
-
それ以外でurlが特別でcがU+005C(\)なら、invalid-reverse-solidus バリデーションエラー、stateをrelative slash状態にする。
-
それ以外:
-
- relative slash状態
-
-
urlが特別でcがU+002F(/)またはU+005C(\)なら:
-
cがU+005C(\)なら、invalid-reverse-solidus バリデーションエラー。
-
stateをspecial authority ignore slashes状態にする。
-
-
それ以外でcがU+002F(/)なら、stateをauthority状態にする。
-
それ以外はurlのusernameにbaseのusernameを、urlのpasswordにbaseのpasswordを、urlのhostにbaseのhostを、urlのportにbaseのportをセットし、stateをpath状態にし、pointerを1減らす。
-
- special authority slashes状態
-
-
cがU+002F(/)で、remainingがU+002F(/)で始まるなら、stateをspecial authority ignore slashes状態にし、pointerを1増やす。
-
それ以外はspecial-scheme-missing-following-solidus バリデーションエラー、stateをspecial authority ignore slashes状態にし、pointerを1減らす。
-
- special authority ignore slashes状態
-
-
cがU+002F(/)でもU+005C(\)でもなければ、stateをauthority状態にし、pointerを1減らす。
-
- authority状態
-
-
cがU+0040(@)なら:
-
atSignSeenがtrueなら、"
%40
"をbufferの先頭に追加。 -
atSignSeenをtrueにセット。
-
bufferの各codePointについて:
-
codePointがU+003A(:)でpasswordTokenSeenがfalseなら、passwordTokenSeenをtrueにし、continue。
-
encodedCodePointsをUTF-8 percent-encodeでcodePointをuserinfo percent-encode setで変換した結果とする。
-
passwordTokenSeenがtrueならencodedCodePointsをurlのpasswordに追加。
-
それ以外はencodedCodePointsをurlのusernameに追加。
-
-
bufferを空文字列にセット。
-
それ以外で以下のいずれかが真なら:
-
cがEOFコードポイント、U+002F(/)、U+003F(?)、U+0023(#)
なら:
-
atSignSeenがtrueかつbufferが空文字列なら、host-missing バリデーションエラー、失敗を返す。
-
-
それ以外はcをbufferに追加。
-
- host状態
- hostname状態
-
-
state overrideが指定されていて、urlのschemeが"
file
"なら、pointerを1減らし、stateをfile host状態にする。 -
それ以外でcがU+003A(:)かつinsideBracketsがfalseなら:
-
bufferが空文字列なら、host-missing バリデーションエラー、失敗を返す。
-
state overrideが指定されていて、state overrideがhostname状態なら、失敗を返す。
-
hostをhost parsingでbufferをurlが特別でないとして解析した結果とする。
-
hostが失敗なら失敗を返す。
-
-
それ以外で以下のいずれかが真なら:
-
cがEOFコードポイント、U+002F(/)、U+003F(?)、U+0023(#)
なら、pointerを1減らし:
-
urlが特別かつbufferが空文字列なら、host-missing バリデーションエラー、失敗を返す。
-
それ以外でstate overrideが指定され、bufferが空文字列かつurlが認証情報を含むまたはurlのportがnullでないなら、失敗を返す。
-
hostをhost parsingでbufferをurlが特別でないとして解析した結果とする。
-
hostが失敗なら失敗を返す。
-
urlのhostにhost、bufferを空文字列、stateをpath start状態に。
-
state overrideが指定されていればreturn。
-
-
それ以外:
-
- port状態
-
-
それ以外で以下のいずれかが真なら:
-
cがEOFコードポイント、U+002F(/)、U+003F(?)、U+0023(#)
-
state overrideが指定されている
なら:
-
bufferが空文字列でなければ:
-
portをbufferを基数10としてASCII数字で表した整数値とする。
-
portが16ビット符号なし整数でなければ、port-out-of-range バリデーションエラー、失敗を返す。
-
bufferを空文字列にセット。
-
state overrideが指定されていればreturn。
-
-
state overrideが指定されていれば失敗を返す。
-
stateをpath start状態にし、pointerを1減らす。
-
-
それ以外はport-invalid バリデーションエラー、失敗を返す。
- file状態
-
-
urlのschemeに"
file
"をセットする。 -
urlのhostを空文字列にセットする。
-
cがU+002F(/)またはU+005C(\)なら:
-
cがU+005C(\)なら、invalid-reverse-solidus バリデーションエラー。
-
stateをfile slash状態にする。
-
-
それ以外でbaseがnullでなく、baseのschemeが"
file
"なら:-
urlのhostにbaseのhost、urlのpathにbaseのcloneしたpath、urlのqueryにbaseのqueryをセット。
-
それ以外でcがU+0023(#)なら、urlのfragmentを空文字列、stateをfragment状態にする。
-
それ以外でcがEOFコードポイントでなければ:
-
-
それ以外はstateをpath状態にし、pointerを1減らす。
-
- file slash状態
-
-
cがU+002F(/)またはU+005C(\)なら:
-
cがU+005C(\)なら、invalid-reverse-solidus バリデーションエラー。
-
stateをfile host状態にする。
-
-
それ以外:
-
baseがnullでなく、baseのschemeが"
file
"なら:-
pointerからinput末尾までのコードポイント部分文字列がWindowsドライブレターで始まるでなく、かつbaseのpath[0]が正規化Windowsドライブレターなら、appendでbaseのpath[0]をurlのpathに追加。
これは(プラットフォーム非依存の)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のhostを空文字列に。
-
state overrideが指定されていればreturn。
-
stateをpath start状態に。
-
-
それ以外は以下の手順を実行:
-
hostをhost parsingでbufferをurlが特別でないとして解析した結果とする。
-
hostが失敗なら失敗を返す。
-
hostが"
localhost
"なら、hostを空文字列に。 -
urlのhostにhostをセット。
-
state overrideが指定されていればreturn。
-
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のqueryを空文字列にし、stateをquery状態に。
-
それ以外でstate overrideが指定されていなくて、cがU+0023(#)なら、urlのfragmentを空文字列にし、stateをfragment状態に。
-
それ以外でcがEOFコードポイントでなければ:
-
それ以外でstate overrideが指定されていて、urlのhostがnullなら、appendで空文字列をurlのpathに追加。
-
- path状態
-
-
以下のいずれかが真なら:
-
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(\)でないなら、appendで空文字列をurlのpathに追加。
-
それ以外でbufferが単一ドットURLパスセグメントでなければ:
-
urlのschemeが"
file
"かつurlのpathが空で、bufferがWindowsドライブレターなら、bufferの2番目のコードポイントをU+003A(:)に置換。これは(プラットフォーム非依存の)Windowsドライブレターの特殊挙動です。
-
-
bufferを空文字列にセット。
-
cがU+0023(#)なら、urlのfragmentを空文字列にし、stateをfragment状態に。
-
-
それ以外は以下の手順を実行:
-
cがURLコードポイントでもU+0025(%)でもなければ、invalid-URL-unit バリデーションエラー。
-
cがU+0025(%)かつremainingがASCII16進数字2つで始まらなければ、invalid-URL-unit バリデーションエラー。
-
UTF-8 percent-encodeでcをpath percent-encode setで変換し、その結果をbufferに追加。
-
-
- 不透明パス状態
-
-
それ以外でcがU+0023(#)なら、urlのfragmentを空文字列にし、stateをfragment状態に。
-
それ以外でcがU+0020(スペース)なら:
-
それ以外でcがEOFコードポイントでなければ:
-
cがURLコードポイントでもU+0025(%)でもなければ、invalid-URL-unit バリデーションエラー。
-
cがU+0025(%)かつremainingがASCII16進数字2つで始まらなければ、invalid-URL-unit バリデーションエラー。
-
UTF-8 percent-encodeでcをC0 control percent-encode setで変換し、その結果をurlのpathに追加。
-
- query状態
-
-
encodingがUTF-8でなく、以下いずれかが真なら:
ならencodingをUTF-8にセット。
-
以下いずれかが真なら:
-
state overrideが指定されていなくて、cがU+0023(#)
なら:
-
queryPercentEncodeSetをurlが特別ならspecial-query percent-encode set、それ以外はquery percent-encode setとする。
-
Percent-encode after encodingでencoding、buffer、queryPercentEncodeSetを使い、その結果をurlのqueryに追加。
この操作は状態を持つISO-2022-JP encoderのためコードポイントごとの呼び出しは不可。
-
bufferを空文字列にセット。
-
cがU+0023(#)なら、urlのfragmentを空文字列にし、stateをfragment状態に。
-
-
それ以外でcがEOFコードポイントでなければ:
-
cがURLコードポイントでもU+0025(%)でもなければ、invalid-URL-unit バリデーションエラー。
-
cがU+0025(%)かつremainingがASCII16進数字2つで始まらなければ、invalid-URL-unit バリデーションエラー。
-
cをbufferに追加。
-
-
- fragment状態
-
-
cがEOFコードポイントでなければ:
-
cがURLコードポイントでもU+0025(%)でもなければ、invalid-URL-unit バリデーションエラー。
-
cがU+0025(%)かつremainingがASCII16進数字2つで始まらなければ、invalid-URL-unit バリデーションエラー。
-
UTF-8 percent-encodeでcをfragment percent-encode setで変換し、その結果をurlのfragmentに追加。
-
-
-
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のschemeとU+003A(:)を連結したものにする。
-
urlのhostがnullでなければ:
-
urlのhostがnullで、urlが不透明パスを持たず、urlのpathのサイズが1より大きく、urlのpath[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に追加。
-
exclude fragmentがfalseで、urlのfragmentがnullでなければ、U+0023(#)とurlのfragmentを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のusernameやpasswordをレンダリングすべきではありません。これらはホストと誤認されやすいためです(例:
https://examplecorp.com@attacker.example/
)。 -
表示領域が常に単一のスキームのみを許可する場合(例えば、セキュアなオリジンのみ有効なブラウザ機能で
https://
を省略する等)、ブラウザはURLのschemeを省略しても構いません。それ以外の場合は、schemeを人が読める文字列(例:"安全ではありません")、セキュリティアイコン、またはその両方で補足・置換しても良いです。
4.8.2. 省略表示
表示領域が限られている場合、URLの省略はユーザーに誤解を与えないよう慎重に行うべきです:
-
ブラウザはURLを表示する際、最低限登録可能ドメインが表示されるようにしてください(例:
...examplecorp.com
ではなく、https://not-really-examplecorp.com/
の内容が分かるように)。 -
ホスト全体を表示できない場合、ブラウザは低レベルのドメインラベルから省略してください。例として
examplecorp.com.evil.com
は...com.evil.com
と省略されるべきであり、examplecorp.com...
とはしないでください(双方向テキストでは最下位ドメインラベルが左端に来るとは限りません)。
4.8.3. 国際化と特殊文字
国際化ドメイン名(IDN)、特殊文字、双方向テキストはなりすまし防止のため慎重に扱うべきです:
-
ブラウザは、URLのhostを、domain to Unicode(対象のhostとfalse)でレンダリングしてください。
様々な文字はホモグラフなりすまし攻撃に利用される可能性があります。紛らわしい文字を検出し、利用時には警告することを検討してください。[IDNFAQ] [UTS39]
-
URLは特にホストとパスの間で混乱を招きやすく、双方向テキストが含まれる場合は特にホストのみをレンダリングすることが推奨されます。その他のURL部分を表示する場合は、パーセントエンコードバイトの並びをUTF-8 BOM無しデコード(パーセントデコードの結果)で得られるコードポイントに置換してください。ただし、その結果が不可視になってしまう場合は除外します。なりすましリスクのある並び(例: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をget an output encodingから得た結果にセットする。
-
outputを空文字列にセットする。
-
-
nameをpercent-encode after encoding(encoding, tupleのname,
application/x-www-form-urlencoded
percent-encode set, true)で得たものとする。 -
valueをpercent-encode after encoding(encoding, tupleのvalue,
application/x-www-form-urlencoded
percent-encode set, true)で得たものとする。 -
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に文字列を変換する際、base URLなしでURL
コンストラクタを1つの引数で呼び出せます:
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
}
この場合はbase 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
オブジェクトはbase
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を返す。
static canParse(url, base)
メソッドの手順:
-
parsedURLをAPI URLパーサでurlとbase(もし指定されていれば)をパースした結果とする。
-
parsedURLが失敗ならfalseを返す。
-
trueを返す。
href
ゲッターおよびtoJSON()
メソッドは、thisのURLの直列化結果を返します。
href
セッターの手順:
origin
ゲッターは、thisのURLのoriginの直列化結果を返します。[HTML]
protocol
セッターは、与えられた値にU+003A(:)を連結し、基本URLパースを実行し、thisのURLをurl、scheme start stateをstate
overrideとして使う。
username
セッターは以下の手順を実行します:
-
thisのURLがusername/password/portを持てない場合はreturn。
-
Set the usernameで、thisのURLと与えられた値を使う。
password
セッターの手順:
-
thisのURLがusername/password/portを持てないならreturn。
-
Set the passwordで、thisのURLと与えられた値を使う。
host
ゲッターの手順:
host
セッターの手順:
-
Basic URL parseで、与えられた値をthisのURL(url)とhost state(state override)でパースする。
この
host
セッターに与えられた値にportがなければ、
thisのURLのportは変更されません。getterではURL-port
stringで返るため、setterが両方を常に「リセット」すると思うかもしれませんが、そうではありません。
hostname
セッターの手順:
-
Basic URL parseで、与えられた値をthisのURL(url)とhostname state(state override)でパースする。
port
セッターの手順:
-
thisのURLがusername/password/portを持てないならreturn。
-
それ以外の場合、Basic URL parseで、与えられた値をthisのURL(url)とport state(state override)でパースする。
pathname
セッターの手順:
search
セッターの手順:
-
与えられた値が空文字列なら、urlのqueryをnullにし、Emptyでthisのquery objectのlistを空にし、return。
-
inputを与えられた値から先頭のU+003F(?)を1つ除いたものとする(もしあれば)。
-
urlのqueryを空文字列にセットする。
-
Basic URL parseでinputをurl(url)とquery state(state override)でパースする。
-
thisのquery objectのlistにinputをパースした結果をセットする。
searchParams
ゲッターの手順:thisのquery objectを返す。
hash
セッターの手順:
-
inputを与えられた値から先頭のU+0023(#)を1つ除いたものとする(もしあれば)。
-
Basic URL parseでinputをthisのURL(url)とfragment state(state override)でパースする。
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
percent-encode setに含まれるものをパーセントエンコードし、U+0020(スペース)はU+002B(+)としてエンコードします。
エンコーディングを無視する場合(UTF-8を使用)、search
は、query
percent-encode setまたはspecial-query percent-encode set(URLが特殊かどうかによる)に含まれるものをパーセントエンコードします。
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タプルをソートするのは便利で、特にキャッシュヒット率向上に役立ちます。これは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 pairsは、thisのlistのtuples(keyがname、valueがvalue)です。
文字列化挙動の手順:thisのlistを直列化した結果を返す。
6.3. 他の場所のURL API
標準が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, Alexis Hunt, 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 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ć, 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 ライセンス の下で提供されます。
これは現行標準です。 特許レビュー版に関心がある方は現行標準レビュー草案をご覧ください。