목표
URL 표준은 URL의 완전한 상호 운용성을 달성하기 위해 다음과 같은 접근 방식을 취합니다:
-
RFC 3986 및 RFC 3987을 최신 구현과 일치시키고, 이 과정에서 해당 RFC를 폐기합니다. (예: 공백, 기타 "불법" 코드 포인트, 쿼리 인코딩, 동등성, 정준화는 모두 완전히 공유되거나 정의된 개념이 아닙니다.) URL 파싱은 HTML 파싱만큼 견고해져야 합니다. [RFC3986] [RFC3987]
-
URL 용어를 표준화합니다. URI와 IRI는 혼란을 야기합니다. 실제로 두 가지 모두에 단일 알고리즘이 사용되므로 구분하는 것은 도움이 되지 않습니다. URL은 또한 검색 결과 인기 경쟁에서도 쉽게 우승합니다.
-
URI의 Origin [sic]을 대체합니다. [RFC6454]
-
URL의 기존 JavaScript API를 완전하게 정의하고, 더 쉽게 사용할 수 있도록 개선 사항을 추가합니다. HTML 요소를 사용하지 않고 URL을 조작할 수 있도록 새로운
URL객체도 추가합니다. (JavaScript 워커 환경에서 유용합니다.) -
파서, 직렬화기, API의 조합이 멱등성을 보장하도록 합니다. 예를 들어, 파싱 후 직렬화 작업의 실패하지 않는 결과는 추가적인 파싱-직렬화 작업을 적용해도 변경되지 않습니다. 마찬가지로, API를 통해 실패하지 않는 결과를 조작해도, 직렬화-파싱 작업을 여러 번 적용해도 변경되지 않습니다.
편집자가 주제를 더 깊이 학습함에 따라 목표의 범위가 다소 증가할 수 있습니다.
1. 인프라스트럭처
이 명세는 Infra에 의존합니다. [INFRA]
이 명세에서 사용되는 일부 용어들은 다음 표준 및 명세에서 정의됩니다:
- Encoding [ENCODING]
- File API [FILEAPI]
- HTML [HTML]
- Unicode IDNA Compatibility Processing [UTS46]
- Web IDL [WEBIDL]
정수를 직렬화하다는, 가능한 가장 짧은 십진수로 표현하는 것을 의미합니다.
1.1. 작성
검증 오류는 입력과 유효한 입력이 일치하지 않음을 나타냅니다. 사용자 에이전트, 특히 적합성 검사기는 이러한 오류를 어딘가에 보고하는 것이 권장됩니다.
검증 오류가 발생해도 파서가 종료된다는 의미는 아닙니다. 파서의 종료는 항상 명시적으로, 예를 들어 return 문을 통해 나타납니다.
검증 오류를 알리는 것은 오류 처리 방식이 직관적이지 않을 수 있고, 레거시 사용자 에이전트가 올바른 오류 처리를 구현하지 않을 수 있으며, 작성된 의도가 다른 개발자에게 명확하지 않을 수 있으므로 유용합니다.
| 오류 유형 | 오류 설명 | 실패 여부 |
|---|---|---|
| IDNA | ||
| domain-to-ASCII |
Unicode ToASCII는 CheckHyphens, UseSTD3ASCIIRules, 그리고 VerifyDnsLength가 모두 true로 설정되었을 때 오류를 기록한다. [UTS46] Unicode ToASCII 오류에 관한 세부 정보가 기록된 경우, 사용자 에이전트는 이를 전달하는 것이 권장된다. | 예 (beStrict가 true이거나, domain이 ASCII 문자열이 아니며 완화된 매개변수를 사용한 Unicode ToASCII도 실패하는 경우) |
| 호스트 구문 분석 | ||
| domain-percent-encoded |
도메인으로 처리될 입력의 호스트에 퍼센트 인코딩된 바이트가 포함되어 있다. " | · |
| host-invalid-code-point |
(특수하지 않은 URL 안의) 불투명 호스트에 금지된 호스트 코드 포인트가 포함되어 있다. | 예 |
| IPv4-empty-part |
IPv4 주소가 U+002E (.)로 끝난다. " | · |
| IPv4-too-few-parts |
IPv4 주소가 4개보다 적은 부분을 가진다. " | · |
| 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를 초과한다. " | 예 (마지막 부분에 적용되는 경우에 한함) |
| IPv4-non-ASCII-input |
IPv4 주소가 IDNA 처리 과정을 통해 비-ASCII 문자열로부터 파생된다. " | · |
| IPv6-unclosed |
IPv6 주소에 닫는 U+005D (])가 없다. " | 예 |
| IPv6-invalid-compression |
IPv6 주소가 부적절한 압축으로 시작한다. " | 예 |
| IPv6-too-many-pieces |
IPv6 주소에 8개보다 많은 조각이 포함되어 있다. " | 예 |
| IPv6-multiple-compression |
IPv6 주소가 둘 이상의 위치에서 압축되어 있다. " | 예 |
| IPv6-invalid-code-point |
IPv6 주소에 ASCII 16진 숫자 도 아니고 U+003A (:)도 아닌 코드 포인트가 포함되어 있다. 또는 예상치 못하게 끝난다. | 예 |
| IPv6-too-few-pieces |
압축되지 않은 IPv6 주소에 8개보다 적은 조각이 포함되어 있다. " | 예 |
| IPv6-piece-leading-zero |
IPv6 주소 조각에 선행 U+0030 (0)이 포함되어 있다. " | · |
| IPv4-in-IPv6-too-many-pieces |
IPv6 주소가 IPv4 주소 문법을 사용하는 경우: IPv6 주소가 6개보다 많은 조각을 가진다. " | 예 |
| IPv4-in-IPv6-invalid-code-point |
" " " " " | 예 |
| IPv4-in-IPv6-out-of-range-part |
IPv6 주소가 IPv4 주소 문법을 사용하는 경우: IPv4 부분이 255를 초과한다. " | 예 |
| IPv4-in-IPv6-too-few-parts |
IPv6 주소가 IPv4 주소 문법을 사용하는 경우: IPv4 주소에 너무 적은 부분이 포함되어 있다. " | 예 |
| URL 구문 분석 | ||
| invalid-URL-unit |
URL 단위가 아닌 코드 포인트가 발견된다. | · |
| special-scheme-missing-following-solidus |
입력의 스킴 뒤에 " | · |
| missing-scheme-non-relative-URL |
입력에 스킴이 없다. 이는 입력이 ASCII 알파로 시작하지 않으며, 기반 URL이 제공되지 않았거나 기반 URL에 불투명 경로가 있어 기반 URL로 사용할 수 없기 때문이다. | 예 |
| invalid-reverse-solidus |
URL이 특수 스킴을 가지고 있으며, U+002F (/) 대신 U+005C (\)를 사용한다. " | · |
| 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 (%) 뒤에 두 개의 ASCII 16진수 숫자가 오는 문자열이다.
일반적으로 퍼센트 인코딩된 바이트의 시퀀스는 퍼센트 디코딩된 다음 BOM 없이 UTF-8 디코딩 또는 실패에 전달되었을 때, 최종적으로 실패가 되지 않는 것이 좋다. 이것이 얼마나 중요한지는 퍼센트 인코딩된 바이트가 사용되는 위치에 따라 다르다. 예를 들어, 호스트 파서의 경우 이 조언을 따르지 않으면 치명적이지만, URL 렌더링의 경우 퍼센트 인코딩된 바이트는 퍼센트 디코딩되어 렌더링되지 않는다.
byte byte를 퍼센트 인코딩하려면, U+0025 (%) 뒤에 byte를 나타내는 두 개의 ASCII 대문자 16진수가 오는 문자열을 반환합니다.
byte sequence input을 퍼센트 디코딩하려면, 다음 절차를 수행합니다:
input에 ASCII 바이트가 아닌 바이트가 포함되어 있을 때 BOM 없이 UTF-8 디코드 외의 것을 사용하는 것은 안전하지 않으며 권장되지 않습니다.
-
output을 빈 byte sequence로 둡니다.
-
input의 각 byte에 대해:
-
byte가 0x25 (%)가 아니면 output에 byte를 추가합니다.
-
그렇지 않고, byte가 0x25 (%)이며 input의 byte 다음 두 바이트가 0x30(0)~0x39(9), 0x41(A)~0x46(F), 0x61(a)~0x66(f) 범위에 속하지 않으면 output에 byte를 추가합니다.
-
그 외의 경우:
-
bytePoint를 input의 byte 뒤의 두 바이트를 디코딩 후 16진수 숫자로 해석한 값으로 둡니다.
-
bytePoint 값을 가지는 바이트를 output에 추가합니다.
-
input의 다음 두 바이트를 건너뜁니다.
-
-
-
output을 반환합니다.
string input을 퍼센트 디코딩하려면:
일반적으로 퍼센트 인코딩 결과는 입력보다 U+0025 (%) 코드 포인트가 더 많고, 퍼센트 디코딩 결과는 입력보다 0x25 (%) 바이트가 더 적습니다.
percent-encode set은 집합이며, 코드 포인트의 집합이다.
C0 control percent-encode set은 percent-encode set이며, C0 제어 문자와 U+007E (~)보다 큰 모든 코드 포인트로 구성된다.
fragment percent-encode set은 percent-encode set이며, C0 control percent-encode set과 U+0020 SPACE, U+0022 ("), U+003C (<), U+003E (>), U+0060 (`)으로 이루어진다.
query percent-encode set은 percent-encode set이며, C0 control percent-encode set과 U+0020 SPACE, U+0022 ("), U+0023 (#), U+003C (<), U+003E (>)로 이루어진다.
query percent-encode set은 fragment percent-encode set에서 U+0060 (`)이 빠져있으므로 그와 같은 관점에서 정의할 수 없다.
special-query percent-encode set은 percent-encode set이며, query percent-encode set과 U+0027 (')으로 이루어진다.
path percent-encode set은 percent-encode set이며, query percent-encode set과 U+003F (?), U+005E (^), U+0060 (`), U+007B ({), U+007D (})로 이루어진다.
userinfo percent-encode set은 percent-encode set이며, path percent-encode set과 U+002F (/), U+003A (:), U+003B (;), U+003D (=), U+0040 (@), U+005B ([)부터 U+005D (])까지 포함하여, U+007C (|)도 포함한다.
component percent-encode set은 percent-encode set이며, userinfo percent-encode set과 U+0024 ($)부터 U+0026 (&)까지, U+002B (+), U+002C (,)을 포함한다.
이것은 HTML의
registerProtocolHandler()에서
사용되고,
다른 표준에서 데이터를 percent-encode 하여
URL의
경로(path),
쿼리(query),
프래그먼트(fragment)
혹은 불투명 호스트(opaque host)에
삽입하는 데에도 사용될 수 있다.
UTF-8
percent-encode와
함께 사용하면 JavaScript의
encodeURIComponent()와
동일한 결과를 준다. [HTML]
[ECMA-262]
application/x-www-form-urlencoded
percent-encode set은
percent-encode
set이며,
component percent-encode set과
U+0021 (!), U+0027 (')부터 U+0029 오른쪽 괄호, 그리고 U+007E (~)를 포함한다.
application/x-www-form-urlencoded
percent-encode set은
ASCII 영숫자,
U+002A (*), U+002D (-), U+002E (.), U+005F (_)를 제외한
모든 코드 포인트를 포함한다.
percent-encode after encoding 은 다음과 같이 주어진 인코딩(encoding) encoding, 스칼라 값 문자열(scalar value string) input, 그리고 percent-encode set percentEncodeSet을 사용한다:
-
단언: encoding은 UTF-8이거나 percentEncodeSet이 special-query percent-encode set 또는
application/x-www-form-urlencodedpercent-encode set이어야 한다. -
spaceAsPlus를 percentEncodeSet이
application/x-www-form-urlencodedpercent-encode set이면 true로, 그렇지 않으면 false로 한다. -
encoder를 인코더 가져오기를 encoding에 대해 실행한 결과로 한다.
-
inputQueue를 input을 I/O 큐로 변환한 값으로 한다.
-
output을 빈 문자열로 한다.
-
potentialError를 0으로 한다.
while 루프를 시작하려면 이 값이 null이 아니어야 한다.
-
potentialError가 null이 아닐 동안:
-
encodeOutput을 비어 있는 I/O 큐로 한다.
-
potentialError를 encode or fail을 inputQueue, encoder, encodeOutput으로 실행한 결과로 한다.
-
encodeOutput을 바이트 시퀀스로 변환한 각 byte에 대해:
-
spaceAsPlus가 true이고 byte가 0x20 (SP)이면, output에 U+002B (+)를 추가하고 계속한다.
-
단언: percentEncodeSet은 ASCII 코드 포인트가 아닌 모든 값을 포함한다.
-
isomorph가 percentEncodeSet에 없다면 output에 isomorph를 추가한다.
-
그렇지 않으면, percent-encode byte를 해서 결과를 output에 추가한다.
-
-
만약 potentialError가 null이 아니라면, output에 “
%26%23”, 그리고 ASCII 숫자로 potentialError를 10진수로 가장 짧은 시퀀스로 나타낸 뒤, “%3B”를 덧붙인다.이것은 encoding이 UTF-8이 아닐 때 발생할 수 있다.
-
-
output을 반환한다.
percentEncodeSet 인자 값 중 U+0025 (%)를 인코딩하여
“왕복 가능한 데이터(roundtripable data)”를 제공하는 것은
component percent-encode set과
application/x-www-form-urlencoded
percent-encode set
두 가지 뿐이다. percentEncodeSet 인자의 다른 값들
(즉, URL 파서에서
사용되는 값)은 U+0025 (%)를 변환하지 않고 넘겨서
적절하게 표현하려면 먼저
percent-encode 해야 한다.
UTF-8 percent-encode는 스칼라 값 scalarValue와 percentEncodeSet에 대해 percent-encode after encoding을 UTF-8, scalarValue(문자열), percentEncodeSet에 대해 수행한 결과를 반환한다.
UTF-8 percent-encode는 스칼라 값 문자열 input과 percentEncodeSet을 사용해 percent-encode after encoding을 UTF-8, input, percentEncodeSet으로 수행한 결과를 반환한다.
아래는 위에서 정의된 연산들의 예시 요약이다:
| Operation | Input | Output |
|---|---|---|
| Percent-encode input | 0x23 | "%23"
|
| 0x7F | "%7F"
| |
| Percent-decode input | `%25%s%1G`
| `%%s%1G`
|
| Percent-decode input | "‽%25%2E"
| 0xE2 0x80 0xBD 0x25 0x2E |
| Percent-encode after encoding with Shift_JIS, input, and the special-query percent-encode set | " "
| "%20"
|
"≡"
| "%81%DF"
| |
"‽"
| "%26%238253%3B"
| |
| Percent-encode after encoding with ISO-2022-JP, input, and the special-query percent-encode set | "¥"
| "%1B(J\%1B(B"
|
Percent-encode after encoding
with Shift_JIS, input, and
the application/x-www-form-urlencoded
percent-encode set
| "1+1 ≡ 2%20‽"
| "1%2B1+%81%DF+2%2520%26%238253%3B"
|
| UTF-8 percent-encode input using the userinfo percent-encode set | U+2261 (≡) | "%E2%89%A1"
|
| U+203D (‽) | "%E2%80%BD"
| |
| UTF-8 percent-encode input using the userinfo percent-encode set | "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에서 host가 불투명 호스트인 예시는
git://github.com/whatwg/url.git입니다.
아래 문단에서 참조된 RFC는 정보 제공용입니다. 특별히 명시하지 않는 한 호스트 작성, 파싱, 직렬화에 영향을 주지 않습니다.
도메인은 네트워크 내 영역을 식별하는 비어 있지 않은 ASCII 문자열입니다. [RFC1034]
도메인 레이블은 도메인 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)입니다.
호스트의 public suffix를 얻으려면 host host에 대해 다음 절차를 실행합니다. 결과는 null 또는 Public Suffix List에 포함된 host의 일부를 나타내는 도메인입니다. [PSL]
-
host가 도메인이 아니면 null을 반환합니다.
-
trailingDot을 host가 "."로 끝나면 "
.", 아니면 빈 문자열로 둡니다. -
publicSuffix를 host를 도메인으로 하여 Public Suffix List 알고리즘을 실행한 결과로 둡니다. [PSL]
-
단언(Assert): publicSuffix는 ASCII 문자열이며, 끝이 trailingDot으로 끝납니다.
-
publicSuffix를 반환합니다.
호스트의 등록 가능 도메인을 얻으려면 host host에 대해 다음 절차를 실행합니다. 결과는 null 또는 host의 public suffix와 그 앞의 도메인 레이블(있다면)로 구성된 도메인입니다.
-
host의 public suffix가 null이거나 host의 public suffix가 host와 동등하다면 null을 반환합니다.
-
trailingDot을 host가 "."로 끝나면 "
.", 아니면 빈 문자열로 둡니다. -
registrableDomain을 host를 도메인으로 하여 Public Suffix List 알고리즘을 실행한 결과로 둡니다. [PSL]
-
단언(Assert): registrableDomain은 ASCII 문자열이며, 끝이 trailingDot으로 끝납니다.
-
registrableDomain을 반환합니다.
| 호스트 입력 | Public suffix | 등록 가능 도메인 |
|---|---|---|
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 |
명세에서는 보안 결정을 위해 origin 개념을 우선적으로 사용해야 합니다. "public suffix"와 "등록 가능 도메인" 개념은 확실한 보안 경계를 제공하지 않으므로 신뢰할 수 없습니다. public suffix list는 클라이언트마다 다를 수 있습니다. 이 권고를 무시하는 명세는 URL의 scheme을 결정에 포함해야 할지 신중하게 고려해야 하며, 즉 same site 또는 schemelessly same site 개념을 사용할지 고려해야 합니다.
3.3. IDNA
도메인 파서 알고리즘은 스칼라 값 문자열 domain과 불리언 beStrict가 주어졌을 때, 다음 단계를 실행한다. 이 단계들은 실패 또는 도메인을 반환한다.
-
strictResult를 domain과 true로 도메인 파서 ToASCII를 실행한 결과로 둔다.
-
strictResult가 실패 값이면, domain-to-ASCII 검증 오류이다. 이 단계는 반환하지 않는다.
-
beStrict가 true이면:
-
strictResult가 실패 값이면, 실패를 반환한다.
-
strictResult를 반환한다.
-
-
result를 null로 둔다.
-
domain이 ASCII 문자열이면, result를 domain을 소문자화한 값으로 설정한다.
beStrict가 false이고 domain이 ASCII 문자열이면, 웹 호환성 때문에 알고리즘은 Unicode ToASCII의 결과와 관계없이 domain을 소문자화한 값을 반환한다. IgnoreInvalidPunycode만으로는 충분하지 않다. Punycode가 성공적으로 디코딩될 수 있어도 여전히 유효성 기준에는 실패할 수 있기 때문이다. 예를 들어,
xn--8i7caa는www로 디코딩되며, 그 코드 포인트들의 상태는 "mapped"이다. [UTS46] -
그렇지 않으면:
-
result를 domain과 false로 도메인 파서 ToASCII를 실행한 결과로 설정한다.
-
result가 실패 값이면, 실패를 반환한다.
-
-
result가 빈 문자열이면, 실패를 반환한다.
-
result가 금지된 도메인 코드 포인트를 포함하면, 실패를 반환한다.
웹 호환성과 DNS 기반이 아닌 시스템과의 호환성 때문에 금지된 도메인 코드 포인트는 UseSTD3ASCIIRules가 true일 때 허용되지 않는 것들의 부분집합이다. 이슈 #397도 참조하라.
-
result를 반환한다.
이 문서와 웹 플랫폼 전반은 IDNA2008이 아니라
Unicode IDNA Compatibility Processing을 사용한다. 예를 들어,
☕.example은 실패가 아니라 xn--53h.example이 된다. [UTS46] [RFC5890]
도메인 파서 ToASCII 알고리즘은 스칼라 값 문자열 domain과 불리언 beStrict가 주어졌을 때, domain_name을 domain으로, CheckHyphens를 beStrict로, CheckBidi를 true로, CheckJoiners를 true로, UseSTD3ASCIIRules를 beStrict로, Transitional_Processing을 false로, VerifyDnsLength를 beStrict로, 그리고 IgnoreInvalidPunycode를 false로 설정하여 Unicode ToASCII를 실행한 결과를 반환한다. [UTS46]
도메인을 Unicode로 변환 알고리즘은 도메인 domain이 주어졌을 때, 다음 단계를 실행한다:
-
result를 domain_name을 domain으로 설정하고 Unicode ToUnicode를 실행한 결과로 둔다. CheckHyphens는 false, CheckBidi는 true, CheckJoiners는 true, UseSTD3ASCIIRules는 false, Transitional_Processing은 false, 그리고 IgnoreInvalidPunycode는 false로 설정한다. [UTS46]
-
오류가 기록되었으면, domain을 반환한다.
domain은 호스트 파서의 결과로만 나올 수 있으므로, 기록된 모든 오류는 이미 검증 오류로 표시되었을 것이다. domain을 반환하면 도메인 파서와 도메인을 Unicode로 변환이
xn--8i7caa와 같은 입력에서 왕복되도록 보장한다. -
result를 반환한다.
3.4. 호스트 작성
유효한 호스트 문자열은 유효한 도메인 문자열, 유효한 IPv4 주소 문자열, 또는 다음이어야 한다: U+005B ([), 뒤이어 유효한 IPv6 주소 문자열, 뒤이어 U+005D (]).
문자열 input은 다음 단계들이 true를 반환하면 유효한 도메인이다:
-
domain을 input과 true로 도메인 파서를 실행한 결과로 둔다.
-
domain이 실패이면 false를 반환한다.
-
domain에 대해 숫자로 끝나는지 검사기를 실행한 결과가 true이면, false를 반환한다.
-
true를 반환한다.
이상적으로는 이를 두더지 잡기식 방식이 아니라, 유효한 도메인을 구성하는 코드 포인트 시퀀스의 관점에서 정의한다: 이슈 245.
유효한 도메인 문자열은 유효한 도메인인 문자열이어야 한다.
유효한 IPv4 주소 문자열은 0 이상 255 이하의 범위에 있는 10진수를 나타내는, 가능한 가장 짧은 ASCII 숫자 문자열 네 개가 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 조각 문자열은 하나 이상의 유효한 IPv6 조각 문자열이 U+003A (:)로 서로 구분된 것이다.
유효한 IPv6 조각 문자열은 0 이상 0xFFFF 이하의 범위에 있는 16진수를 나타내는, 가능한 가장 짧은 ASCII 16진수 숫자 문자열이다.
유효한 IPv6 조각 문자열의 유효 조각 길이는 그것이 포함하는 유효한 IPv6 조각 문자열의 수이다. 유효 조각 길이 유효한 IPv6 조각 및 IPv4 문자열의 경우에는 그것이 포함하는 유효한 IPv6 조각 문자열의 수에 2를 더한 값이다.
이는 A Recommendation for IPv6 Address Text Representation에서 파생되었다. IPv4와의 일관성을 위해 선행 0은 허용되지 않는다. [RFC5952]
유효한 불투명 호스트 문자열은 다음 중 하나여야 한다:
-
금지된 호스트 코드 포인트를 제외한 하나 이상의 URL 단위
-
U+005B ([), 그 뒤에 유효한 IPv6 주소 문자열, 그 뒤에 U+005D (]).
이는 유효한 호스트 문자열의 정의 일부가 아니다. 구별하기 위해 문맥이 필요하기 때문이다.
3.5. 호스트 파싱
호스트 파서는 스칼라 값 문자열 input과 선택적 boolean isOpaque(기본값 false)를 받아 다음 단계를 실행한다. 이 단계들은 failure 또는 호스트를 반환한다.
-
input이 U+005B ([)로 시작하면:
-
input이 U+005D (])로 끝나지 않으면, IPv6-unclosed 검증 오류, failure를 반환한다.
-
input에서 앞의 U+005B ([)와 뒤의 U+005D (])를 제거한 값으로 IPv6 구문 분석을 수행한 결과를 반환한다.
-
-
isOpaque가 true이면, 불투명 호스트 구문 분석 input의 결과를 반환한다.
-
Assert: input은 빈 문자열이 아니다.
-
input에 퍼센트 인코딩된 바이트가 포함되어 있으면, domain-percent-encoded 검증 오류.
-
domain을 input의 퍼센트 디코딩에 BOM 없는 UTF-8 디코딩을 실행한 결과로 둔다.
또는, BOM 없는 UTF-8 디코딩 또는 실패를 사용하고, failure에 대해 조기 반환하도록 결합할 수 있다. 도메인 파서는 U+FFFD (�)에서 실패하기 때문이다.
-
asciiDomain을 도메인 파서를 domain과 false로 실행한 결과로 둔다.
-
asciiDomain이 failure이면, failure를 반환한다.
-
asciiDomain이 숫자로 끝나면:
-
domain이 ASCII 문자열이 아니면, IPv4-non-ASCII-input 검증 오류.
-
IPv4 구문 분석 asciiDomain의 결과를 반환한다.
-
-
asciiDomain을 반환한다.
숫자로 끝나는지 검사기는 ASCII 문자열 input을 받아 다음 단계를 실행한다. 이 단계들은 boolean을 반환한다.
-
Assert: input은 빈 문자열이 아니다.
-
parts를 input을 U+002E (.)에서 엄격하게 분할한 결과로 둔다.
-
last를 parts의 마지막 항목으로 둔다.
-
last가 빈 문자열이 아니고 ASCII 숫자만 포함하면, true를 반환한다.
잘못된 입력 "
09"는 이후 단계에서 IPv4 파서에 의해 잡힌다. -
last를 IPv4 숫자로 구문 분석했을 때 failure를 반환하지 않으면, true를 반환한다.
이는 last가 "
0X" 또는 "0x"이고, 그 뒤에 0개 이상의 ASCII 16진 숫자가 오는지 검사하는 것과 동등하다. -
false를 반환한다.
IPv4 파서는 ASCII 문자열 input을 받아 다음 단계를 실행한다. 이 단계들은 failure 또는 IPv4 주소를 반환한다.
IPv4 파서는 직접 호출해서는 안 된다. 대신 호스트 파서의 반환 값이 IPv4 주소인지 확인한다.
-
parts를 input을 U+002E (.)에서 엄격하게 분할한 결과로 둔다.
-
parts의 마지막 항목이 빈 문자열이면:
-
parts의 크기가 4보다 작으면, IPv4-too-few-parts 검증 오류.
-
parts의 크기가 4보다 크면, IPv4-too-many-parts 검증 오류, failure를 반환한다.
-
numbers를 빈 목록으로 둔다.
-
parts의 각 part에 대해 반복한다:
-
result를 part를 구문 분석한 결과로 둔다.
-
result가 failure이면, IPv4-non-numeric-part 검증 오류, failure를 반환한다.
-
result[1]이 true이면, IPv4-non-decimal-part 검증 오류.
-
result[0]을 numbers에 추가한다.
-
-
numbers의 어떤 항목이든 255보다 크면, IPv4-out-of-range-part 검증 오류.
-
numbers에서 마지막 항목을 제외한 어떤 항목이든 255보다 크면, failure를 반환한다.
-
numbers의 마지막 항목이 256(5 − numbers의 크기)보다 크거나 같으면, failure를 반환한다.
-
ipv4를 numbers의 마지막 항목으로 둔다.
-
counter를 0으로 둔다.
-
numbers의 각 n에 대해 반복한다:
-
ipv4를 n × 256(3 − counter)만큼 증가시킨다.
-
counter를 1만큼 증가시킨다.
-
-
ipv4를 반환한다.
IPv4 숫자 파서는 ASCII 문자열 input을 받아 다음 단계를 실행한다. 이 단계들은 failure 또는 숫자와 boolean의 튜플을 반환한다.
-
input이 빈 문자열이면, failure를 반환한다.
-
validationError를 false로 둔다.
-
R을 10으로 둔다.
-
input이 적어도 두 개의 코드 포인트를 포함하고 처음 두 코드 포인트가 "
0X" 또는 "0x"이면:-
validationError를 true로 설정한다.
-
input에서 처음 두 코드 포인트를 제거한다.
-
R을 16으로 설정한다.
-
-
그렇지 않고, input이 적어도 두 개의 코드 포인트를 포함하고 첫 번째 코드 포인트가 U+0030 (0)이면:
-
validationError를 true로 설정한다.
-
input에서 첫 번째 코드 포인트를 제거한다.
-
R을 8로 설정한다.
-
-
input이 빈 문자열이면, (0, true)를 반환한다.
-
input에 radix-R 숫자가 아닌 코드 포인트가 포함되어 있으면 failure를 반환한다.
-
output을 input이 radix-R 표기법에서 나타내는 수학적 정수 값으로 둔다. 이때 값 0부터 15까지의 숫자에는 ASCII 16진 숫자를 사용한다.
-
(output, validationError)를 반환한다.
IPv6 파서는 스칼라 값 문자열 input을 받아 다음 단계를 실행한다. 이 단계들은 failure 또는 IPv6 주소를 반환한다.
IPv6 파서는 이론적으로 직접 호출할 수 있지만, 실제로 그렇게 하기 전에 이 문서의 편집자들과 논의하기 바란다.
-
pieceIndex를 0으로 둔다.
-
compress를 null로 둔다.
-
pointer를 input에 대한 포인터로 둔다.
-
c가 U+003A (:)이면:
-
remaining이 U+003A (:)로 시작하지 않으면, IPv6-invalid-compression 검증 오류, failure를 반환한다.
-
pointer를 2만큼 증가시킨다.
-
pieceIndex를 1만큼 증가시킨 다음 compress를 pieceIndex로 설정한다.
-
-
c가 EOF 코드 포인트가 아닌 동안:
-
pieceIndex가 8이면, IPv6-too-many-pieces 검증 오류, failure를 반환한다.
-
c가 U+003A (:)이면:
-
compress가 null이 아니면, IPv6-multiple-compression 검증 오류, failure를 반환한다.
- pointer와 pieceIndex를 1만큼 증가시키고, compress를 pieceIndex로 설정한 다음 continue한다.
-
-
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 검증 오류, failure를 반환한다.
-
pointer를 length만큼 감소시킨다.
-
pieceIndex가 6보다 크면, IPv4-in-IPv6-too-many-pieces 검증 오류, failure를 반환한다.
-
numbersSeen을 0으로 둔다.
-
c가 EOF 코드 포인트가 아닌 동안:
-
ipv4Piece를 null로 둔다.
-
numbersSeen이 0보다 크면:
-
c가 U+002E (.)이고 numbersSeen이 4보다 작으면, pointer를 1만큼 증가시킨다.
- 그렇지 않으면, IPv4-in-IPv6-invalid-code-point 검증 오류, failure를 반환한다.
-
-
c가 ASCII 숫자가 아니면, IPv4-in-IPv6-invalid-code-point 검증 오류, failure를 반환한다.
-
-
number를 십진수로 해석한 c로 둔다.
-
ipv4Piece가 null이면, ipv4Piece를 number로 설정한다.
-
그렇지 않고 ipv4Piece가 0이면, IPv4-in-IPv6-invalid-code-point 검증 오류, failure를 반환한다.
-
그렇지 않으면, ipv4Piece를 ipv4Piece × 10 + number로 설정한다.
-
ipv4Piece가 255보다 크면, IPv4-in-IPv6-out-of-range-part 검증 오류, failure를 반환한다.
-
pointer를 1만큼 증가시킨다.
-
-
address[pieceIndex]를 address[pieceIndex] × 0x100 + ipv4Piece로 설정한다.
-
numbersSeen을 1만큼 증가시킨다.
-
numbersSeen이 2 또는 4이면, pieceIndex를 1만큼 증가시킨다.
-
-
numbersSeen이 4가 아니면, IPv4-in-IPv6-too-few-parts 검증 오류, failure를 반환한다.
-
Break한다.
-
-
그렇지 않고, c가 U+003A (:)이면:
-
pointer를 1만큼 증가시킨다.
-
c가 EOF 코드 포인트이면, IPv6-invalid-code-point 검증 오류, failure를 반환한다.
-
-
그렇지 않고, c가 EOF 코드 포인트가 아니면, IPv6-invalid-code-point 검증 오류, failure를 반환한다.
-
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 검증 오류, failure를 반환한다.
-
address를 반환한다.
불투명 호스트 파서는 스칼라 값 문자열 input을 받아, 다음 단계를 실행한다. 이 단계들은 failure 또는 불투명 호스트를 반환한다.
-
input에 금지된 호스트 코드 포인트가 포함되어 있으면, host-invalid-code-point 검증 오류, failure를 반환한다.
-
input에 코드 포인트가 포함되어 있고, 그것이 URL 코드 포인트도 아니며 U+0025 (%)도 아니면, invalid-URL-unit 검증 오류.
-
input에 U+0025 (%)가 포함되어 있고 그 뒤의 두 코드 포인트가 ASCII 16진 숫자가 아니면, invalid-URL-unit 검증 오류.
-
input에 C0 제어 퍼센트 인코딩 집합을 사용하여 UTF-8 퍼센트 인코딩을 실행한 결과를 반환한다.
3.6. 호스트 직렬화
IPv6 직렬화기는 IPv6 주소 address를 받아 다음 단계를 실행한다. 이 단계들은 ASCII 문자열을 반환한다.
-
output을 빈 문자열로 둔다.
-
compress를 주어진 address에 대해 IPv6 주소의 압축된 조각 인덱스를 찾는 결과로 둔다.
-
ignore0을 false로 둔다.
-
address의 조각들의 인덱스에 있는 각 pieceIndex에 대해 반복한다:
-
ignore0이 true이고 address[pieceIndex]가 0이면, continue한다.
-
그렇지 않고, ignore0이 true이면, ignore0을 false로 설정한다.
-
compress가 pieceIndex이면:
-
pieceIndex가 0이면 separator를 "
::"로 두고, 그렇지 않으면 U+003A (:)로 둔다. -
separator를 output에 추가한다.
-
ignore0을 true로 설정하고 continue한다.
-
-
address[pieceIndex]를 가능한 가장 짧은 소문자 16진수로 표현하여 output에 추가한다.
-
pieceIndex가 7이 아니면, U+003A (:)를 output에 추가한다.
-
-
output을 반환한다.
이 알고리즘은 IPv6 주소 텍스트 표현을 위한 권고안의 권고를 요구한다. [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 파서는 임의의 스칼라 값 문자열을 받아 failure 또는 URL을 반환한다. 또한 0개 이상의 검증 오류를 기록할 수도 있다.
-
URL은 메모리 내 표현으로 볼 수 있다.
-
유효한 URL 문자열은 URL 파서에 주어졌을 때 검증 오류나 failure를 발생시키지 않는 입력을 정의한다. 즉, 적합하거나 유효하다고 간주되는 입력이다.
-
URL 직렬화기는 URL을 받아 ASCII 문자열을 반환한다. (그 문자열이 이후 구문 분석되면, 그 결과는 같다. 즉, URL은 직렬화된 URL과 같다.) URL 직렬화기의 출력이 항상 유효한 URL 문자열인 것은 아니다.
| 입력 | 기준 | 유효 여부 | 출력 |
|---|---|---|---|
https:example.org
| ❌ | https://example.org/
| |
https://////example.com///
| ❌ | https://example.com///
| |
https://example.com/././foo
| ✅ | https://example.com/foo
| |
hello:world
| https://example.com/
| ✅ | hello:world
|
https:example.org
| https://example.com/
| ❌ | https://example.com/example.org
|
\example\..\demo/.\
| https://example.com/
| ❌ | https://example.com/demo/
|
example
| https://example.com/demo
| ✅ | https://example.com/example
|
file:///C|/demo
| ❌ | file:///C:/demo
| |
..
| file:///C:/demo
| ✅ | file:///C:/
|
file://localhost/
| ✅ | file:///
| |
file://loc%61lhost/
| ❌ | file:///
| |
https://user:[email protected]/
| ❌ | https://user:[email protected]/
| |
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을 디스패치하는 데 사용할 수 있다. 초기값은 빈 문자열이다.
URL의 사용자 이름은 사용자 이름을 식별하는 ASCII 문자열이다. 초기값은 빈 문자열이다.
URL의 비밀번호는 비밀번호를 식별하는 ASCII 문자열이다. 초기값은 빈 문자열이다.
URL의 호스트는 null 또는 호스트이다. 초기값은 null이다.
다음 표는 허용되는 URL의 스킴 / 호스트 조합을 나열한다.
| 스킴 | 호스트 | |||||
|---|---|---|---|---|---|---|
| 도메인 | IPv4 주소 | IPv6 주소 | 불투명 호스트 | 빈 호스트 | null | |
"file"을 제외한 특수
스킴
| ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
"file"
| ✅ | ✅ | ✅ | ❌ | ✅ | ❌ |
| 기타 | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
URL의 포트는 null 또는 네트워킹 포트를 식별하는 16비트 부호 없는 정수이다. 초기값은 null이다.
URL의 경로는 일반적으로 위치를 식별하는 URL 경로이다. 초기값은 « »이다.
특수 URL의 경로는 항상 목록이다. 즉, 결코 불투명하지 않다.
URL의 쿼리는 null 또는 ASCII 문자열이다. 초기값은 null이다.
URL의 프래그먼트는 null 또는 ASCII 문자열이며, URL의 다른 구성 요소들이 식별하는 리소스에 대한 추가 처리에 사용할 수 있다. 초기값은 null이다.
URL은 또한 연결된 blob URL 항목을 가지며, 이는 null 또는 blob URL 항목이다. 초기값은 null이다.
이는 "blob" URL이 참조하는 객체와 그 출처를 캐시하는 것을
지원하는 데 사용된다. 이들이 캐시되는 것이 중요한 이유는, URL이 구문 분석과 가져오기 사이에
blob
URL 저장소에서 제거될 수 있지만, 가져오기는 여전히
성공해야 하기 때문이다.
다음 표는 유효한 URL 문자열이 구문 분석될 때 URL의 구성 요소에 어떻게 매핑되는지를 나열한다. 사용자 이름, 비밀번호, 그리고 blob URL 항목은 생략되어 있다. 아래 예에서 이들은 각각 빈 문자열, 빈 문자열, null이다.
| 입력 | 스킴 | 호스트 | 포트 | 경로 | 쿼리 | 프래그먼트 |
|---|---|---|---|---|---|---|
https://example.com/
| "https"
| "example.com"
| null | « 빈 문자열 » | null | null |
https://localhost:8000/search?q=text#hello
| "https"
| "localhost"
| 8000 | « "search" »
| "q=text"
| "hello"
|
urn:isbn:9780307476463
| "urn"
| null | null | "isbn:9780307476463"
| null | null |
file:///ada/Analytical%20Engine/README.md
| "file"
| 빈 문자열 | null | « "ada", "Analytical%20Engine", "README.md" »
| null | null |
URL 경로는 URL 경로 세그먼트 또는 0개 이상의 URL 경로 세그먼트의 목록이다.
URL 경로 세그먼트는 ASCII 문자열이다. 일반적으로 디렉터리나 파일을 가리키지만, 미리 정의된 의미는 없다.
단일 점 URL 경로 세그먼트는
"."이거나 "%2e"와 ASCII
대소문자 구분 없는
일치를 하는 URL 경로 세그먼트이다.
이중 점 URL 경로 세그먼트는
".."이거나 ".%2e", "%2e.", 또는 "%2e%2e"와
ASCII
대소문자 구분 없는
일치를 하는 URL 경로 세그먼트이다.
4.2. URL 기타
특수 스킴은 다음 표의 첫 번째 열에 나열된 ASCII 문자열이다. 특수 스킴에 대한 기본 포트는 같은 행의 두 번째 열에 나열되어 있다. 그 밖의 모든 ASCII 문자열에 대한 기본 포트는 null이다.
| 특수 scheme | 기본 포트 |
|---|---|
"ftp"
| 21 |
"file"
| null |
"http"
| 80 |
"https"
| 443 |
"ws"
| 80 |
"wss"
| 443 |
URL이 특수하다는 URL의 scheme이 특수 scheme일 때입니다. URL이 특수하지 않다는 URL의 scheme이 특수 scheme이 아닐 때입니다.
URL은 자격 증명을 포함한다는 username 또는 password가 빈 문자열이 아닐 때입니다.
URL은 불투명 경로를 가진다는 것은 경로가 URL 경로 세그먼트일 때입니다.
URL은 username/password/port를 가질 수
없다는 host가
null이나 빈 문자열이거나, scheme이
"file"일 때입니다.
URL은 기본 URL로 지정될 수 있습니다.
기본 URL은 입력이 상대-URL 문자열일 수 있을 때 URL 파서에 유용합니다.
Windows 드라이브 문자는 두 개의 코드 포인트로, 첫 번째는 ASCII 알파벳이고 두 번째는 U+003A(:) 또는 U+007C(|)입니다.
정규화된 Windows 드라이브 문자는 두 번째 코드 포인트가 U+003A(:)인 Windows 드라이브 문자입니다.
URL 작성 섹션에 따라, 오직 정규화된 Windows 드라이브 문자만 적합합니다.
문자열이 Windows 드라이브 문자로 시작한다는 다음 조건을 모두 만족할 때입니다:
- 문자열의 길이가 2 이상이다
- 첫 두 코드 포인트가 Windows 드라이브 문자이다
- 문자열의 길이가 2이거나, 세 번째 코드 포인트가 U+002F(/), U+005C(\), U+003F(?), U+0023(#) 중 하나이다.
url의 경로를 단축하기 절차:
4.3. URL 작성
유효한 URL 문자열은 relative-URL-with-fragment 문자열 또는 absolute-URL-with-fragment 문자열이어야 합니다.
absolute-URL-with-fragment 문자열은 absolute-URL 문자열이며, 선택적으로 U+0023(#)와 URL-fragment 문자열이 뒤따를 수 있습니다.
absolute-URL 문자열은 다음 중 하나여야 합니다:
-
URL-스킴 문자열로서, ASCII 대소문자를 구분하지 않는 방식으로 특수 스킴과 일치하고, "
file"과는 ASCII 대소문자를 구분하지 않는 방식으로 일치하지 않으며, 그 뒤에 U+003A (:)와 스킴-상대-특수-URL 문자열이 이어지는 것 -
URL-스킴 문자열로서, ASCII 대소문자를 구분하지 않는 방식으로 특수 스킴과 일치하지 않으며, 그 뒤에 U+003A (:)와 다음 중 하나가 이어지는 것: 스킴-상대-URL 문자열, 경로-절대-비-권한-URL 문자열, 또는 불투명-경로-URL 문자열
-
URL-스킴 문자열로서, ASCII 대소문자를 구분하지 않는 방식으로 "
file"과 일치하고, 그 뒤에 U+003A (:)와 스킴-상대-file-URL 문자열이 이어지는 것
어느 것이든 선택적으로 그 뒤에 U+003F (?)와 URL-쿼리 문자열이 이어질 수 있다.
URL-스킴 문자열은 하나의 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진수를 나타내는 하나 이상의 ASCII 숫자로서, 그 수는 16비트 부호 없는 정수여야 한다.
스킴-상대-URL 문자열은
"//"이어야 하며, 그 뒤에 불투명-호스트-및-포트 문자열이 이어지고, 선택적으로 그 뒤에
경로-절대-URL
문자열이 이어질 수 있다.
불투명-호스트-및-포트 문자열은 빈 문자열이거나 다음이어야 한다: 유효한 불투명 호스트 문자열, 선택적으로 그 뒤에 U+003A (:)와 URL-포트 문자열이 이어질 수 있다.
스킴-상대-file-URL 문자열은
"//"이어야 하며, 선택적으로 그 뒤에 다음 중 하나가 이어질 수 있다:
-
유효한 호스트 문자열, 선택적으로 그 뒤에 경로-절대-URL 문자열이 이어질 수 있음
경로-절대-URL 문자열은 U+002F (/)이어야 하며, 그 뒤에 0개 이상의 URL-경로-세그먼트 문자열이 이어지고, 각 항목은 서로 U+002F (/)로 구분되어야 한다.
경로-절대-비-권한-URL 문자열은 경로-절대-URL 문자열이어야 하며, 두 개의 U+002F (/) 코드 포인트로 시작하지 않아야 한다.
경로-상대-URL 문자열은 0개 이상의 URL-경로-세그먼트 문자열이어야 하며, 각 항목은 서로 U+002F (/)로 구분되고, U+002F (/)로 시작하지 않아야 한다.
A 경로-상대-스킴-없음-URL 문자열은 경로-상대-URL 문자열이어야 하며, 다음으로 시작하지 않아야 한다: URL-스킴 문자열, 그 뒤에 U+003A (:)가 이어지는 것.
불투명-경로-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에서 문서 인코딩이 레거시 인코딩인 경우, URL-query 문자열 안의 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)을 함께 받아, 다음 단계를 실행한다:
웹 브라우저가 아닌 구현은 기본 URL 파서만 구현하면 된다.
웹 브라우저의 주소 표시줄에 있는 사용자 입력이 URL 레코드로 변환되는 방식은 이 표준의 범위 밖이다. 이 표준은 신뢰 결정과 관련된 URL 렌더링 요구사항을 포함한다.
-
url을 input에 대해 기본 URL 파서를 base 및 encoding과 함께 실행한 결과로 둔다.
-
url이 failure이면, failure를 반환한다.
-
url의 스킴이 "
blob"이 아니면, url을 반환한다. -
url의 blob URL 항목을 blob URL을 해석한 결과로 설정한다. 그 결과가 failure를 반환하지 않았다면 해당 결과로, 그렇지 않으면 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 또는 failure를 반환한다. 이들이 전달되면, 알고리즘은 전달된 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 감소시킨다.
-
그렇지 않으면, failure를 반환한다.
-
- 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의 첫 번째 코드 포인트부터) 다시 시작한다.
-
그렇지 않으면, failure를 반환한다.
이 failure 표시는
Location객체의protocol설정자에서만 사용된다. 또한, 이 상태에서 앞서 발생하는 failure가 아닌 종료는 해당 설정자를 정의하기 위한 의도적인 차이이다.
-
- no scheme state
-
-
base가 null이거나, base가 불투명 경로를 가지고 c가 U+0023 (#)이 아니면, missing-scheme-non-relative-URL 유효성 검사 오류, failure를 반환한다.
-
그렇지 않고, 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로 설정한다.
-
그렇지 않고, c가 EOF 코드 포인트가 아니면:
-
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 감소시킨다.
-
- 특수 권한 슬래시 무시 상태
- 권한 상태
-
-
c가 U+0040 (@)이면:
-
atSignSeen이 true이면, "
%40"을 buffer 앞에 추가한다. -
atSignSeen을 true로 설정한다.
-
buffer의 각 codePoint에 대해:
-
codePoint가 U+003A (:)이고 passwordTokenSeen이 false이면, passwordTokenSeen을 true로 설정하고 continue한다.
-
encodedCodePoints를 UTF-8 퍼센트 인코딩을 codePoint에 userinfo 퍼센트 인코딩 집합을 사용하여 실행한 결과로 둔다.
-
passwordTokenSeen이 true이면, encodedCodePoints를 url의 비밀번호에 추가한다.
-
그렇지 않으면, encodedCodePoints를 url의 사용자 이름에 추가한다.
-
-
buffer를 빈 문자열로 설정한다.
-
그렇지 않고, 다음 중 하나가 true이면:
-
c가 EOF 코드 포인트, U+002F (/), U+003F (?), 또는 U+0023 (#)이다
그러면:
-
atSignSeen이 true이고 buffer가 빈 문자열이면, host-missing 검증 오류, failure를 반환한다.
-
pointer를 buffer의 코드 포인트 길이 + 1만큼 감소시키고, buffer를 빈 문자열로 설정한 뒤 state를 호스트 상태로 설정한다.
-
-
그렇지 않으면, c를 buffer에 추가한다.
-
- 호스트 상태
- 호스트명 상태
-
-
state override가 주어지고 url의 스킴이 "
file"이면, pointer를 1만큼 감소시키고 state를 파일 호스트 상태로 설정한다. -
그렇지 않고, c가 U+003A (:)이고 insideBrackets가 false이면:
-
그렇지 않고, 다음 중 하나가 true이면:
-
c가 EOF 코드 포인트, U+002F (/), U+003F (?), 또는 U+0023 (#)이다
그러면 pointer를 1만큼 감소시킨 다음:
-
url이 특수하고 buffer가 빈 문자열이면, host-missing 검증 오류, failure를 반환한다.
-
그렇지 않고, state override가 주어지고 buffer가 빈 문자열이며, url이 자격 증명을 포함하거나 url의 포트가 null이 아니면, failure를 반환한다.
-
host가 failure이면, failure를 반환한다.
-
state override가 주어졌으면, 반환한다.
-
-
그렇지 않으면:
-
- 포트 상태
-
-
그렇지 않고, 다음 중 하나가 true이면:
-
c가 EOF 코드 포인트, U+002F (/), U+003F (?), 또는 U+0023 (#)이다;
-
state override가 주어진다,
그러면:
-
buffer가 빈 문자열이 아니면:
-
port를 buffer가 radix-10에서 값 0부터 9까지의 숫자에 ASCII 숫자를 사용하여 나타내는 수학적 정수 값으로 둔다.
-
port가 16비트 부호 없는 정수가 아니면, port-out-of-range 검증 오류, failure를 반환한다.
-
port가 url의 스킴의 기본 포트이면 url의 포트를 null로 설정하고, 그렇지 않으면 port로 설정한다.
-
buffer를 빈 문자열로 설정한다.
-
state override가 주어졌으면, 반환한다.
-
-
state override가 주어졌으면, failure를 반환한다.
-
state를 경로 시작 상태로 설정하고 pointer를 1만큼 감소시킨다.
-
-
그렇지 않으면, port-invalid 검증 오류, failure를 반환한다.
- 파일 상태
-
-
url의 스킴을 "
file"로 설정한다. -
url의 호스트를 빈 문자열로 설정한다.
-
c가 U+002F (/) 또는 U+005C (\)이면:
-
c가 U+005C (\)이면, invalid-reverse-solidus 검증 오류.
-
state를 파일 슬래시 상태로 설정한다.
-
-
그렇지 않고, base가 null이 아니며 base의 스킴이 "
file"이면:-
url의 호스트를 base의 호스트로, url의 경로를 base의 경로의 복제본으로, 그리고 url의 쿼리를 base의 쿼리로 설정한다.
-
그렇지 않고, c가 U+0023 (#)이면, url의 프래그먼트를 빈 문자열로 설정하고 state를 프래그먼트 상태로 설정한다.
-
그렇지 않고, c가 EOF 코드 포인트가 아니면:
-
url의 쿼리를 null로 설정한다.
-
pointer부터 input의 끝까지의 코드 포인트 부분 문자열이 Windows 드라이브 문자로 시작하지 않으면, url의 경로를 단축한다.
-
그렇지 않으면:
-
url의 경로를 « »로 설정한다.
이는 (플랫폼 독립적인) Windows 드라이브 문자 특이 동작이다.
-
state를 경로 상태로 설정하고 pointer를 1만큼 감소시킨다.
-
-
-
그렇지 않으면, state를 경로 상태로 설정하고, pointer를 1만큼 감소시킨다.
-
- 파일 슬래시 상태
-
-
c가 U+002F (/) 또는 U+005C (\)이면:
-
c가 U+005C (\)이면, invalid-reverse-solidus 검증 오류.
-
state를 파일 호스트 상태로 설정한다.
-
-
그렇지 않으면:
-
base가 null이 아니고 base의 스킴이 "
file"이면:-
pointer부터 input의 끝까지의 코드 포인트 부분 문자열이 Windows 드라이브 문자로 시작하지 않고 base의 경로[0]이 정규화된 Windows 드라이브 문자이면, base의 경로[0]을 url의 경로에 추가한다.
이는 (플랫폼 독립적인) Windows 드라이브 문자 특이 동작이다.
-
state를 경로 상태로 설정하고, pointer를 1만큼 감소시킨다.
-
-
- 파일 호스트 상태
-
-
c가 EOF 코드 포인트, U+002F (/), U+005C (\), U+003F (?), 또는 U+0023 (#)이면, pointer를 1만큼 감소시킨 다음:
-
state override가 주어지지 않았고 buffer가 Windows 드라이브 문자이면, file-invalid-Windows-drive-letter-host 검증 오류, state를 경로 상태로 설정한다.
이는 (플랫폼 독립적인) Windows 드라이브 문자 특이 동작이다. buffer는 여기서 재설정되지 않고 대신 경로 상태에서 사용된다.
-
그렇지 않고, buffer가 빈 문자열이면:
-
그렇지 않으면, 다음 단계를 실행한다:
-
-
그렇지 않으면, c를 buffer에 추가한다.
-
- 경로 시작 상태
-
-
url이 특수하면:
-
c가 U+005C (\)이면, invalid-reverse-solidus 검증 오류.
-
state를 경로 상태로 설정한다.
-
c가 U+002F (/) 또는 U+005C (\)가 아니면, pointer를 1만큼 감소시킨다.
-
-
그렇지 않고, state override가 주어지지 않았으며 c가 U+003F (?)이면, url의 쿼리를 빈 문자열로 설정하고 state를 쿼리 상태로 설정한다.
-
그렇지 않고, state override가 주어지지 않았으며 c가 U+0023 (#)이면, url의 프래그먼트를 빈 문자열로 설정하고 state를 프래그먼트 상태로 설정한다.
-
그렇지 않고, c가 EOF 코드 포인트가 아니면:
-
그렇지 않고, state override가 주어졌으며 url의 호스트가 null이면, 빈 문자열을 url의 경로에 추가한다.
-
- 경로 상태
-
-
다음 중 하나가 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+0023 (#)이면, url의 프래그먼트를 빈 문자열로 설정하고 state를 프래그먼트 상태로 설정한다.
-
-
그렇지 않으면, 다음 단계를 실행한다:
-
c가 URL 코드 포인트가 아니고 U+0025 (%)도 아니면, invalid-URL-unit 검증 오류.
-
c가 U+0025 (%)이고 remaining이 두 개의 ASCII 16진 숫자로 시작하지 않으면, invalid-URL-unit 검증 오류.
-
c를 경로 퍼센트 인코딩 집합을 사용하여 UTF-8 퍼센트 인코딩하고, 그 결과를 buffer에 추가한다.
-
-
- 불투명 경로 상태
-
-
그렇지 않고, c가 U+0023 (#)이면, url의 프래그먼트를 빈 문자열로 설정하고 state를 프래그먼트 상태로 설정한다.
-
그렇지 않고, c가 U+0020 SPACE이면:
-
그렇지 않고, c가 EOF 코드 포인트가 아니면:
-
c가 URL 코드 포인트가 아니고 U+0025 (%)도 아니면, invalid-URL-unit 검증 오류.
-
c가 U+0025 (%)이고 remaining이 두 개의 ASCII 16진 숫자로 시작하지 않으면, invalid-URL-unit 검증 오류.
-
c를 C0 제어 퍼센트 인코딩 집합을 사용하여 UTF-8 퍼센트 인코딩하고, 그 결과를 url의 경로에 추가한다.
-
- 쿼리 상태
-
-
encoding이 UTF-8이 아니고 다음 중 하나가 true이면:
그러면 encoding을 UTF-8로 설정한다.
-
다음 중 하나가 true이면:
-
state override가 주어지지 않았고 c가 U+0023 (#)이다
-
c가 EOF 코드 포인트이다
그러면:
-
queryPercentEncodeSet를 url이 특수하면 특수 쿼리 퍼센트 인코딩 집합으로 두고, 그렇지 않으면 쿼리 퍼센트 인코딩 집합으로 둔다.
-
encoding, buffer, 그리고 queryPercentEncodeSet으로 인코딩 후 퍼센트 인코딩을 수행하고, 그 결과를 url의 쿼리에 추가한다.
이 작업은 상태를 가지는 ISO-2022-JP 인코더 때문에 코드 포인트 단위로 호출할 수 없다.
-
buffer를 빈 문자열로 설정한다.
-
c가 U+0023 (#)이면, url의 프래그먼트를 빈 문자열로 설정하고 state를 프래그먼트 상태로 설정한다.
-
-
그렇지 않고, c가 EOF 코드 포인트가 아니면:
-
c가 URL 코드 포인트가 아니고 U+0025 (%)도 아니면, invalid-URL-unit 검증 오류.
-
c가 U+0025 (%)이고 remaining이 두 개의 ASCII 16진 숫자로 시작하지 않으면, invalid-URL-unit 검증 오류.
-
c를 buffer에 추가한다.
-
-
- 프래그먼트 상태
-
-
c가 EOF 코드 포인트가 아니면:
-
c가 URL 코드 포인트가 아니고 U+0025 (%)도 아니면, invalid-URL-unit 검증 오류.
-
c가 U+0025 (%)이고 remaining이 두 개의 ASCII 16진 숫자로 시작하지 않으면, invalid-URL-unit 검증 오류.
-
c를 프래그먼트 퍼센트 인코딩 집합을 사용하여 UTF-8 퍼센트 인코딩하고, 그 결과를 url의 프래그먼트에 추가한다.
-
-
-
url을 반환한다.
username 설정을 url과 username에 대해 실행할 때, url의 username을 username에 UTF-8 퍼센트 인코드를 userinfo percent-encode set으로 실행한 결과로 설정한다.
password 설정을 url과 password에 대해 실행할 때, url의 password를 password에 UTF-8 퍼센트 인코드를 userinfo percent-encode set으로 실행한 결과로 설정한다.
4.5. URL 직렬화
URL 직렬화기는 URL url을 받고, 선택적인 boolean 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와 동일한지 판단할 때, 선택적 불리언 fragment 제외(기본값: false)와 함께 다음 단계를 실행한다:
-
serializedA를 직렬화를 A에 대해 fragment 제외를 fragment 제외로 하여 실행한 결과로 둔다.
-
serializedB를 직렬화를 B에 대해 fragment 제외를 fragment 제외로 하여 실행한 결과로 둔다.
-
serializedA가 serializedB와 같으면 true를, 아니면 false를 반환한다.
4.7. 오리진
오리진의 정의는 HTML에서 필수 배경 정보를 참고하세요. [HTML]
URL url의 오리진은 아래 단계들을 실행하여 얻어지는 오리진으로, url의 스킴에 따라 분기한다:
- "
blob" -
-
url의 blob URL entry가 null이 아니면, url의 blob URL entry의 environment의 오리진을 반환.
-
pathURL을 파싱한 URL 경로 직렬화 url의 결과로 둔다.
-
pathURL이 실패면 새 불투명 오리진을 반환한다.
-
pathURL의 scheme이 "
http", "https", 또는 "file"이면 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을 표시하는 주요 목적이 사용자가 보안 또는 신뢰 결정을 내리게 하는 경우에 적용된다. 예를 들어, 사용자는 브라우저 주소창에 렌더링된 URL을 기반으로 신뢰 결정을 내릴 것으로 기대된다.
4.8.1. 사람이 읽기 어려운 또는 중요하지 않은 구성요소 단순화
스푸핑 기회를 제공하거나 보안 관련 정보를 방해할 수 있는 구성요소를 제거한다:
-
브라우저는 URL의 host만 렌더링할 수 있다. 이는 최종 사용자가 host와 경로 등 URL의 다른 부분을 구별하는 것이 중요한 경우에 적용된다. 브라우저는 host를 더 단순화하여 등록 가능 도메인에 주의를 끌도록 고려할 수 있다. 예를 들어, 브라우저는 앞쪽의
www또는m도메인 레이블을 생략하여 host를 단순화하거나, 등록 가능 도메인만 표시하여 서브도메인이 제공하는 스푸핑 기회를 제거할 수 있다(https://examplecorp.attacker.com/등). -
브라우저는 URL의 username과 password를 렌더링해서는 안 된다. 이는 host로 오인될 수 있기 때문이다(
https://[email protected]/등). -
브라우저는 표시 영역이 단일 스킴만 허용하는 경우 URL의 scheme을 표시하지 않을 수 있다(예: 브라우저 기능이
https://를 생략하는 경우). 그렇지 않으면 스킴을 사람이 읽을 수 있는 문자열(예: "보안 아님"), 보안 표시 아이콘 또는 둘 모두로 대체하거나 보충할 수 있다.
4.8.2. 생략(Elision)
공간이 제한된 표시에서는 사용자가 보안 결정을 내릴 때 오해하지 않도록 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의 다른 부분을 렌더링한다면, 그 percent-encoded 바이트 시퀀스는 해당 시퀀스를 percent-decoding한 것에 BOM 없이 UTF-8 디코드를 실행한 결과 코드 포인트로 대체되어야 한다. 단, 그렇게 해서 해당 시퀀스가 보이지 않게 되는 경우는 제외한다. 브라우저는 스푸핑 위험을 나타내는 특정 시퀀스(예: U+1F512 (🔒))를 디코드하지 않도록 선택할 수 있다.
-
브라우저는 양방향 텍스트를 왼쪽에서 오른쪽 임베딩 안에 있는 것처럼 렌더링해야 한다. [BIDI]
안타깝게도 렌더링된 URL은 문자열이며 어디에나 나타날 수 있으므로, 렌더링된 URL을 위한 특정 양방향 알고리즘은 널리 채택되지 않을 것이다. 양방향 텍스트는 URL의 각 부분과 상호작용하여 렌더링이 모델과 달라질 수 있다. 양방향 언어 사용자는 특히 일반 텍스트 환경에서 이를 예상하게 될 수 있다.
5.
application/x-www-form-urlencoded
application/x-www-form-urlencoded 포맷은
목록에 있는 튜플 각각을 name과
value로 구성된 쌍으로 인코딩하는 방법을 제공한다.
application/x-www-form-urlencoded 포맷은 여러 면에서 이상하고 기형적인 결과물이며, 수년간 구현
사고와 타협의 결과로 상호운용성을 위해 필요한 요구사항 집합으로 이어졌지만, 결코 좋은 설계 관행을 나타내지는 않는다. 특히, 반복적(때로는 중첩된) 문자 인코딩과 바이트 시퀀스 간 변환의 꼬인
세부사항을 주의 깊게 살펴야 한다. 안타깝게도 HTML 폼의 보편적 사용으로 인해 이 포맷은 널리 쓰이고 있다. [HTML]
5.1. application/x-www-form-urlencoded 파싱
레거시 서버 중심 구현은 인코딩이 UTF-8이 아닌
경우나 name이 `_charset`인 튜플에 대해 특별한 처리 로직을 지원해야 할 수 있다. 이러한 로직은 여기서 기술하지 않으며, UTF-8만이
준수하는
인코딩이다.
application/x-www-form-urlencoded 파서는 바이트 시퀀스
input을 받아 다음 단계를 실행한다:
-
sequences를 input을 0x26(&)으로 분할한 결과로 둔다.
-
output을 name과 value가 문자열을 담는 튜플로 구성된, 초기에는 빈 목록으로 둔다.
-
각 바이트 시퀀스 bytes에 대해 sequences에서:
-
bytes가 빈 바이트 시퀀스이면 계속.
-
bytes에 0x3D(=)가 있으면, name을 bytes의 처음부터 첫 번째 0x3D(=) 직전까지의 바이트로, value를 첫 번째 0x3D(=) 이후부터 끝까지의 바이트로 둔다. 0x3D(=)가 첫 번째 바이트면 name은 빈 바이트 시퀀스가 되고, 마지막이면 value는 빈 바이트 시퀀스가 된다.
-
그 외에는 name을 bytes 값으로, value를 빈 바이트 시퀀스로 둔다.
-
name과 value의 모든 0x2B(+)를 0x20(SP)로 치환한다.
-
nameString과 valueString을 각각 BOM 없는 UTF-8 디코드를 퍼센트 디코딩된 name과 value에 대해 실행한 결과로 둔다.
-
append (nameString, valueString)를 output에 추가.
-
-
output을 반환한다.
5.2. application/x-www-form-urlencoded 직렬화
application/x-www-form-urlencoded 직렬화기는
name-value 튜플 tuples 목록과 선택적 인코딩
encoding(기본 UTF-8)을 받아 다음 단계를 실행한다. 반환값은 ASCII 문자열이다.
-
encoding을 output encoding을 얻기를 encoding에 대해 실행한 결과로 설정한다.
-
output을 빈 문자열로 한다.
-
각 tuple에 대해 tuples에서 반복한다:
-
name을 다음의 결과로 한다: percent-encode after encoding을 encoding, tuple의 name, 그리고
application/x-www-form-urlencodedpercent-encode set으로 실행한 결과. -
value를 다음의 결과로 한다: percent-encode after encoding을 encoding, tuple의 value, 그리고
application/x-www-form-urlencodedpercent-encode set으로 실행한 결과. -
output이 빈 문자열이 아니라면 U+0026 (&)를 output에 추가한다.
- name을 추가하고 U+003D (=)를 추가한 뒤 value를 output에 추가한다.
- output을 반환한다.
5.3. 후크(Hooks)
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 객체:
URLSearchParams객체.
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"
입력이 relative-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
getter 반환값으로 문자열화된다):
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
setter 단계:
-
parsedURL에 basic URL 파서를 입력값에 실행한 결과를 할당합니다.
-
this의 query object의 list를 비웁니다.
-
query가 null이 아니면 this의 query object의 list에 파싱 query 결과를 할당합니다.
protocol
setter 단계는
basic
URL 파싱을 입력값과 U+003A (:)가 뒤따르도록 한 후
this의 URL을 url로
하고
scheme start
state를 state override로 지정하여 실행합니다.
username
setter 단계:
-
this의 URL이 username/password/port를 가질 수 없으면 return.
-
set the username을 this의 URL과 입력값으로 수행합니다.
password
setter 단계:
-
this의 URL이 username/password/port를 가질 수 없으면 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-port 문자열을 반환하므로
setter가 항상 둘 다 "재설정"한다고 생각했을 수 있어, 이는 예상과 다를 수 있다.
hostname
설정자 단계는 다음과 같다:
port
설정자 단계는 다음과 같다:
pathname getter 단계는 URL 경로
직렬화를 this의 URL에 대해 실행한 결과를 반환하는 것이다.
pathname
설정자 단계는 다음과 같다:
search getter 단계는 다음과 같다:
search
설정자 단계는 다음과 같다:
hash getter 단계는 다음과 같다:
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
percent-encode set에 포함된 모든 것을 percent-encode하며,
U+0020 SPACE는 U+002B(+)로 인코딩한다.
인코딩은 무시하고(UTF-8 사용), search
는
query
percent-encode set이나 special-query percent-encode set에
포함된 모든 것을 percent-encode한다(해당 URL이 special인지에 따라 다름).
URLSearchParams
객체에는 다음이 연관되어 있다:
initialize를 URLSearchParams
객체 query에 init으로 실행할 때:
update를 URLSearchParams
객체 query에 실행할 때:
new URLSearchParams(init)
생성자 단계는 다음과 같다:
-
init이 문자열이고 앞에 U+003F(?)가 있으면 처음 코드 포인트를 제거한다.
-
initialize를 this와 init에 실행한다.
delete(name, value)
메서드 단계는 다음과 같다:
getAll(name) 메서드 단계는
this의
list에서 name이 name인 모든 tuple의
value를 리스트 순서대로 반환하며, 없으면 빈 sequence를 반환합니다.
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 pair는 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".
HTML의 EventSource
및 HashChangeEvent
인터페이스는 적절한 명명 예시이다. [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), 그리고 zealousidealroll 여러분께 진심으로 감사드립니다!
이 표준은 Anne van Kesteren (Apple, [email protected])이 작성했습니다.
지적 재산권
Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). 이 저작물은 크리에이티브 커먼즈 저작자 표시 4.0 국제 라이선스에 따라 라이선스가 부여됩니다. 소스 코드에 포함된 부분에 대해서는, 해당 부분은 BSD 3-Clause 라이선스에 따라 소스 코드에 라이선스가 부여됩니다.
이 문서는 현행 표준(Living Standard)입니다. 특허 심사 버전에 관심이 있다면 현행 표준 심사 초안을 참고하십시오.