URL

현행 표준 — 최근 업데이트

참여하기:
GitHub whatwg/url (새 이슈, 오픈 이슈)
Matrix에서 채팅하기
커밋:
GitHub whatwg/url/commits
이 커밋 기준 스냅샷
@urlstandard
테스트:
web-platform-tests url/ (진행 중인 작업)
번역 (비규범적):
日本語
简体中文
한국어

요약

URL 표준은 URL, 도메인, IP 주소, application/x-www-form-urlencoded 형식, 그리고 이들의 API를 정의합니다.

목표

URL 표준은 URL의 완전한 상호 운용성을 달성하기 위해 다음과 같은 접근 방식을 취합니다:

편집자가 주제를 더 깊이 학습함에 따라 목표의 범위가 다소 증가할 수 있습니다.

1. 인프라스트럭처

이 명세는 Infra에 의존합니다. [INFRA]

이 명세에서 사용되는 일부 용어들은 다음 표준 및 명세에서 정의됩니다:


정수를 직렬화하다는, 가능한 가장 짧은 십진수로 표현하는 것을 의미합니다.

1.1. 작성

검증 오류는 입력과 유효한 입력이 일치하지 않음을 나타냅니다. 사용자 에이전트, 특히 적합성 검사기는 이러한 오류를 어딘가에 보고하는 것이 권장됩니다.

검증 오류가 발생해도 파서가 종료된다는 의미는 아닙니다. 파서의 종료는 항상 명시적으로, 예를 들어 return 문을 통해 나타납니다.

검증 오류를 알리는 것은 오류 처리 방식이 직관적이지 않을 수 있고, 레거시 사용자 에이전트가 올바른 오류 처리를 구현하지 않을 수 있으며, 작성된 의도가 다른 개발자에게 명확하지 않을 수 있으므로 유용합니다.

오류 유형 오류 설명 실패
IDNA
domain-to-ASCII

Unicode ToASCII가 오류를 기록하거나 빈 문자열을 반환합니다. [UTS46]

Unicode ToASCII 오류에 대한 세부 정보가 기록된 경우, 사용자 에이전트는 이를 전달하는 것이 권장됩니다.


(단, domainASCII 문자열인 경우는 제외)
domain-invalid-code-point

입력의 호스트금지된 도메인 코드 포인트를 포함합니다.

URL이 특수한 경우 호스트는 처리되기 전에 퍼센트 디코딩되며, 이는 다음 호스트 부분이 "exa#mple.org"가 되게 하여 이 오류를 발생시킵니다.

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

호스트 구문 분석
host-invalid-code-point

(특수가 아닌 URL에서) 불투명 호스트금지된 호스트 코드 포인트를 포함합니다.

"foo://exa[mple.org"

IPv4-empty-part

IPv4 주소가 U+002E (.)로 끝납니다.

"https://127.0.0.1./"

·
IPv4-too-many-parts

IPv4 주소가 정확히 4개의 부분으로 구성되어 있지 않습니다.

"https://1.2.3.4.5/"

IPv4-non-numeric-part

IPv4 주소 부분이 숫자가 아닙니다.

"https://test.42"

IPv4-non-decimal-part

IPv4 주소가 16진수 또는 8진수 숫자를 사용해 표현된 숫자를 포함합니다.

"https://127.0.0x0.1"

·
IPv4-out-of-range-part

IPv4 주소 부분이 255를 초과합니다.

"https://255.255.4000.1"


(마지막 부분에 적용되는 경우에만)
IPv6-unclosed

IPv6 주소에 닫는 U+005D (])가 없습니다.

"https://[::1"

IPv6-invalid-compression

IPv6 주소가 부적절한 압축으로 시작합니다.

"https://[:1]"

IPv6-too-many-pieces

IPv6 주소가 8개보다 많은 조각을 포함합니다.

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

IPv6-multiple-compression

IPv6 주소가 둘 이상의 위치에서 압축되어 있습니다.

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

IPv6-invalid-code-point

IPv6 주소ASCII 16진수 숫자 또는 U+003A (:)가 아닌 코드 포인트를 포함합니다. 또는 예기치 않게 끝납니다.

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

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

IPv6-too-few-pieces

압축되지 않은 IPv6 주소가 8개보다 적은 조각을 포함합니다.

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

IPv4-in-IPv6-too-many-pieces

IPv6 주소IPv4 주소 구문을 사용합니다: IPv6 주소에 6개보다 많은 조각이 있습니다.

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

IPv4-in-IPv6-invalid-code-point

IPv6 주소IPv4 주소 구문을 사용합니다:

  • IPv4 부분이 비어 있거나 ASCII 숫자가 아닌 문자를 포함합니다.
  • IPv4 부분에 선행 0이 포함되어 있습니다.
  • IPv4 부분이 너무 많습니다.

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

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

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

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

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

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

IPv6 주소IPv4 주소 구문을 사용합니다: IPv4 부분이 255를 초과합니다.

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

IPv4-in-IPv6-too-few-parts

IPv6 주소IPv4 주소 구문을 사용합니다: IPv4 주소가 너무 적은 부분을 포함합니다.

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

URL 구문 분석
invalid-URL-unit

URL 단위가 아닌 코드 포인트가 발견되었습니다.

"https://example.org/>"

" https://example.org "

"ht
tps://example.org
"

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

·
special-scheme-missing-following-solidus

입력의 스킴 뒤에 "//"가 오지 않습니다.

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

"https:example.org"

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

입력은 스킴이 없습니다. 이는 입력이 ASCII 알파로 시작하지 않고, 기본 URL이 제공되지 않았거나 기본 URL불투명 경로를 가지기 때문에 기본 URL로 사용할 수 없기 때문입니다.

입력의 스킴이 없고 기본 URL이 주어지지 않았습니다:

const url = new URL("💩");

입력의 스킴은 없지만, 기본 URL불투명 경로를 가집니다.

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

URL이 특수 스킴을 가지며, U+002F (/) 대신 U+005C (\)를 사용합니다.

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

·
invalid-credentials

입력이 자격 증명을 포함합니다.

"https://user@example.org"

"ssh://user@example.org"

·
host-missing

입력이 특수 스킴을 가지지만, 호스트를 포함하지 않습니다.

"https://#fragment"

"https://:443"

"https://user:pass@"

port-out-of-range

입력의 포트가 너무 큽니다.

"https://example.org:70000"

port-invalid

입력의 포트가 유효하지 않습니다.

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

file-invalid-Windows-drive-letter

입력이 상대 URL 문자열이며, Windows 드라이브 문자로 시작하고 기본 URL스킴이 "file"입니다.

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

file: URL의 호스트가 Windows 드라이브 문자입니다.

"file://c:"

·

1.2. 파서

EOF 코드 포인트는 문자열이나 코드 포인트 스트림의 끝을 나타내는 개념적인 코드 포인트입니다.

문자열 input에 대한 포인터input 내의 코드 포인트를 가리키는 정수입니다. 처음에는 input의 시작을 가리킵니다. 만약 값이 −1이면 아무 곳도 가리키지 않습니다. input코드 포인트 길이보다 크거나 같으면 EOF 코드 포인트를 가리킵니다.

포인터가 사용될 때, c코드 포인트포인터가 가리키는 위치를 참조합니다. 단, 아무 곳도 가리키지 않을 때는 사용할 수 없습니다. 포인터가 아무 곳도 가리킬 때 c는 사용할 수 없습니다.

포인터가 사용될 때, remaining문자열의 끝까지의 코드 포인트 서브스트링포인터 + 1 부터 참조합니다. 단, cEOF 코드 포인트가 아닐 때만 사용할 수 있습니다. cEOF 코드 포인트일 때 remaining은 사용할 수 없습니다.

"mailto:username@example"가 처리 중인 문자열이고 포인터가 @을 가리킨다면, c는 U+0040 (@)이고 remaining은 "example"입니다.

빈 문자열을 처리 중이고 포인터가 시작을 가리키다가 −1로 감소된다면, cremaining을 사용하는 것은 오류입니다.

1.3. 퍼센트 인코딩 바이트

퍼센트 인코딩 바이트는 U+0025 (%) 뒤에 두 개의 ASCII 16진수가 오는 것입니다.

퍼센트 인코딩 바이트 시퀀스는 퍼센트 디코딩BOM 없이 UTF-8 디코드 또는 실패에 전달될 때 실패로 끝나지 않는 것이 일반적으로 좋습니다. 이 중요성은 퍼센트 인코딩 바이트가 사용되는 위치에 따라 다릅니다. 예를 들어, 호스트 파서에서는 이 권고를 따르지 않으면 치명적이지만, URL 렌더링에서는 퍼센트 인코딩 바이트퍼센트 디코딩되어 렌더링되지 않습니다.

byte byte를 퍼센트 인코딩하려면, U+0025 (%) 뒤에 byte를 나타내는 두 개의 ASCII 대문자 16진수가 오는 문자열을 반환합니다.

byte sequence input을 퍼센트 디코딩하려면, 다음 절차를 수행합니다:

inputASCII 바이트가 아닌 바이트가 포함되어 있을 때 BOM 없이 UTF-8 디코드 외의 것을 사용하는 것은 안전하지 않으며 권장되지 않습니다.

  1. output을 빈 byte sequence로 둡니다.

  2. input의 각 byte에 대해:

    1. byte가 0x25 (%)가 아니면 outputbyte를 추가합니다.

    2. 그렇지 않고, byte가 0x25 (%)이며 inputbyte 다음 두 바이트가 0x30(0)~0x39(9), 0x41(A)~0x46(F), 0x61(a)~0x66(f) 범위에 속하지 않으면 outputbyte를 추가합니다.

    3. 그 외의 경우:

      1. bytePointinputbyte 뒤의 두 바이트를 디코딩 후 16진수 숫자로 해석한 값으로 둡니다.

      2. bytePoint 값을 가지는 바이트를 output에 추가합니다.

      3. input의 다음 두 바이트를 건너뜁니다.

  3. output을 반환합니다.

string input을 퍼센트 디코딩하려면:

  1. bytesinputUTF-8 인코딩 결과로 둡니다.

  2. bytes퍼센트 디코딩 결과를 반환합니다.

일반적으로 퍼센트 인코딩 결과는 입력보다 U+0025 (%) 코드 포인트가 더 많고, 퍼센트 디코딩 결과는 입력보다 0x25 (%) 바이트가 더 적습니다.


percent-encode set집합이며, 코드 포인트의 집합이다.

C0 control percent-encode setpercent-encode set이며, C0 제어 문자와 U+007E (~)보다 큰 모든 코드 포인트로 구성된다.

fragment percent-encode setpercent-encode set이며, C0 control percent-encode set과 U+0020 SPACE, U+0022 ("), U+003C (<), U+003E (>), U+0060 (`)으로 이루어진다.

query percent-encode setpercent-encode set이며, C0 control percent-encode set과 U+0020 SPACE, U+0022 ("), U+0023 (#), U+003C (<), U+003E (>)로 이루어진다.

query percent-encode setfragment percent-encode set에서 U+0060 (`)이 빠져있으므로 그와 같은 관점에서 정의할 수 없다.

special-query percent-encode setpercent-encode set이며, query percent-encode set과 U+0027 (')으로 이루어진다.

path percent-encode setpercent-encode set이며, query percent-encode set과 U+003F (?), U+005E (^), U+0060 (`), U+007B ({), U+007D (})로 이루어진다.

userinfo percent-encode setpercent-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 setpercent-encode set이며, userinfo percent-encode set과 U+0024 ($)부터 U+0026 (&)까지, U+002B (+), U+002C (,)을 포함한다.

이것은 HTMLregisterProtocolHandler()에서 사용되고, 다른 표준에서 데이터를 percent-encode 하여 URL경로(path), 쿼리(query), 프래그먼트(fragment) 혹은 불투명 호스트(opaque host)에 삽입하는 데에도 사용될 수 있다. UTF-8 percent-encode와 함께 사용하면 JavaScript의 encodeURIComponent()와 동일한 결과를 준다. [HTML] [ECMA-262]

application/x-www-form-urlencoded percent-encode setpercent-encode set이며, component percent-encode set과 U+0021 (!), U+0027 (')부터 U+0029 오른쪽 괄호, 그리고 U+007E (~)를 포함한다.

application/x-www-form-urlencoded percent-encode setASCII 영숫자, U+002A (*), U+002D (-), U+002E (.), U+005F (_)를 제외한 모든 코드 포인트를 포함한다.

percent-encode after encoding 은 다음과 같이 주어진 인코딩(encoding) encoding, 스칼라 값 문자열(scalar value string) input, 그리고 percent-encode set percentEncodeSet을 사용한다:

  1. 단언: encodingUTF-8이거나 percentEncodeSetspecial-query percent-encode set 또는 application/x-www-form-urlencoded percent-encode set이어야 한다.

  2. spaceAsPluspercentEncodeSetapplication/x-www-form-urlencoded percent-encode set이면 true로, 그렇지 않으면 false로 한다.

  3. encoder인코더 가져오기encoding에 대해 실행한 결과로 한다.

  4. inputQueueinputI/O 큐로 변환한 값으로 한다.

  5. output을 빈 문자열로 한다.

  6. potentialError를 0으로 한다.

    while 루프를 시작하려면 이 값이 null이 아니어야 한다.

  7. potentialError가 null이 아닐 동안:

    1. encodeOutput을 비어 있는 I/O 큐로 한다.

    2. potentialErrorencode or failinputQueue, encoder, encodeOutput으로 실행한 결과로 한다.

    3. encodeOutput을 바이트 시퀀스로 변환한 각 byte에 대해:

      1. spaceAsPlus가 true이고 byte가 0x20 (SP)이면, output에 U+002B (+)를 추가하고 계속한다.

      2. isomorph코드 포인트로 두고, 그 byte이 된다.

      3. 단언: percentEncodeSetASCII 코드 포인트가 아닌 모든 값을 포함한다.

      4. isomorphpercentEncodeSet에 없다면 outputisomorph를 추가한다.

      5. 그렇지 않으면, percent-encode byte를 해서 결과를 output에 추가한다.

    4. 만약 potentialError가 null이 아니라면, output에 “%26%23”, 그리고 ASCII 숫자potentialError를 10진수로 가장 짧은 시퀀스로 나타낸 뒤, “%3B”를 덧붙인다.

      이것은 encodingUTF-8이 아닐 때 발생할 수 있다.

  8. output을 반환한다.

percentEncodeSet 인자 값 중 U+0025 (%)를 인코딩하여 “왕복 가능한 데이터(roundtripable data)”를 제공하는 것은 component percent-encode setapplication/x-www-form-urlencoded percent-encode set 두 가지 뿐이다. percentEncodeSet 인자의 다른 값들 (즉, URL 파서에서 사용되는 값)은 U+0025 (%)를 변환하지 않고 넘겨서 적절하게 표현하려면 먼저 percent-encode 해야 한다.

UTF-8 percent-encode스칼라 값 scalarValuepercentEncodeSet에 대해 percent-encode after encodingUTF-8, scalarValue(문자열), percentEncodeSet에 대해 수행한 결과를 반환한다.

UTF-8 percent-encode스칼라 값 문자열 inputpercentEncodeSet을 사용해 percent-encode after encodingUTF-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]

URLA에서 B로 전달할 때 두 쪽 모두 신중하게 상황을 고려해야 합니다. A는 원하지 않는 데이터를 유출할 수 있고, B는 예상치 못한 입력을 받아 사용자에게 해를 끼칠 수 있습니다. 특히 BA를 절대 신뢰해서는 안 되며, 언제든지 A로부터 오는 URL이 신뢰할 수 없는 소스일 수 있습니다.

3. 호스트 (도메인 및 IP 주소)

상위 수준에서 호스트, 유효한 호스트 문자열, 호스트 파서, 호스트 직렬화기는 다음과 같이 연관됩니다:

파싱-직렬화 라운드트립의 결과는 호스트 파서isOpaque 인자에 따라 다음과 같습니다:

입력 출력 (isOpaque = false) 출력 (isOpaque = true)
EXAMPLE.COM example.com (도메인) EXAMPLE.COM (불투명 호스트)
example%2Ecom example%2Ecom (불투명 호스트)
faß.example xn--fa-hia.example (도메인) fa%C3%9F.example (불투명 호스트)
0 0.0.0.0 (IPv4) 0 (불투명 호스트)
%30 %30 (불투명 호스트)
0x 0x (불투명 호스트)
0xffffffff 255.255.255.255 (IPv4) 0xffffffff (불투명 호스트)
[0:0::1] [::1] (IPv6)
[0:0::1%5D 실패
[0:0::%31]
09 실패 09 (불투명 호스트)
example.255 example.255 (불투명 호스트)
example^example 실패

3.1. 호스트 표현

호스트도메인, IP 주소, 불투명 호스트, 또는 빈 호스트입니다. 일반적으로 호스트는 네트워크 주소로 사용되지만, 네트워크 주소가 필요하지 않은 URL에서 불투명 식별자로 사용되기도 합니다.

전형적인 URL에서 host불투명 호스트인 예시는 git://github.com/whatwg/url.git입니다.

아래 문단에서 참조된 RFC는 정보 제공용입니다. 특별히 명시하지 않는 한 호스트 작성, 파싱, 직렬화에 영향을 주지 않습니다.

도메인은 네트워크 내 영역을 식별하는 비어 있지 않은 ASCII 문자열입니다. [RFC1034]

도메인 레이블도메인 domain을 U+002E(.)로 엄격하게 분할한 결과입니다.

example.comexample.com. 도메인은 동등하지 않으며, 일반적으로 별개의 것으로 취급됩니다.

IP 주소IPv4 주소 또는 IPv6 주소입니다.

IPv4 주소는 네트워크 주소를 식별하는 32비트 부호 없는 정수입니다. [RFC791]

IPv6 주소는 네트워크 주소를 식별하는 128비트 부호 없는 정수입니다. 이 정수는 리스트로 이루어진 8개의 16비트 부호 없는 정수로 구성되며, IPv6 주소조각이라 부릅니다. [RFC4291]

<zone_id> 지원은 의도적으로 생략되었습니다.

불투명 호스트는 추가 처리가 가능한 비어 있지 않은 ASCII 문자열입니다.

빈 호스트는 빈 문자열입니다.

3.2. 호스트 기타

금지된 호스트 코드 포인트는 U+0000(NULL), U+0009(TAB), U+000A(LF), U+000D(CR), U+0020(공백), U+0023(#), U+002F(/), U+003A(:), U+003C(<), U+003E(>), U+003F(?), U+0040(@), U+005B([), U+005C(\), U+005D(]), U+005E(^), 또는 U+007C(|) 입니다.

금지된 도메인 코드 포인트금지된 호스트 코드 포인트, C0 제어 문자, U+0025(%), 또는 U+007F(DELETE)입니다.

호스트의 public suffix를 얻으려면 host host에 대해 다음 절차를 실행합니다. 결과는 null 또는 Public Suffix List에 포함된 host의 일부를 나타내는 도메인입니다. [PSL]

  1. host도메인이 아니면 null을 반환합니다.

  2. trailingDothost"."로 끝나면 ".", 아니면 빈 문자열로 둡니다.

  3. publicSuffixhost를 도메인으로 하여 Public Suffix List 알고리즘을 실행한 결과로 둡니다. [PSL]

  4. 단언(Assert): publicSuffixASCII 문자열이며, 끝이 trailingDot으로 끝납니다.

  5. publicSuffix를 반환합니다.

호스트의 등록 가능 도메인을 얻으려면 host host에 대해 다음 절차를 실행합니다. 결과는 null 또는 hostpublic suffix와 그 앞의 도메인 레이블(있다면)로 구성된 도메인입니다.

  1. hostpublic suffix가 null이거나 hostpublic suffixhost와 동등하다면 null을 반환합니다.

  2. trailingDothost"."로 끝나면 ".", 아니면 빈 문자열로 둡니다.

  3. registrableDomainhost를 도메인으로 하여 Public Suffix List 알고리즘을 실행한 결과로 둡니다. [PSL]

  4. 단언(Assert): registrableDomainASCII 문자열이며, 끝이 trailingDot으로 끝납니다.

  5. 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가 주어지면, 다음 단계를 실행한다. 이 단계들은 실패 또는 도메인을 반환한다.

  1. beStrict가 true이면:

    1. domain_namedomain으로 설정하고, CheckHyphens를 true로, CheckBidi를 true로, CheckJoiners를 true로, UseSTD3ASCIIRules를 true로, Transitional_Processing를 false로, VerifyDnsLength를 true로, IgnoreInvalidPunycode를 false로 설정하여 Unicode ToASCII를 실행한 결과를 result라 하자. [UTS46]

    2. result가 실패 값이면, domain-to-ASCII 검증 오류이며, 실패를 반환한다.

    3. result를 반환한다.

  2. result를 null로 하자.

  3. domainASCII 문자열이면:

    1. domain_namedomain으로 설정하고, CheckHyphens를 false로, CheckBidi를 true로, CheckJoiners를 true로, UseSTD3ASCIIRules를 false로, Transitional_Processing를 false로, VerifyDnsLength를 false로, IgnoreInvalidPunycode를 false로 설정하여 Unicode ToASCII를 실행한 결과가 실패 값이면, domain-to-ASCII 검증 오류이다. [UTS46]

    2. result소문자화된 domain으로 설정한다.

    beStrict가 false이고 domainASCII 문자열인 경우, Unicode ToASCII 실패는 웹 호환성 때문에 전체 알고리즘 실패가 아니라 검증 오류만 발생시킨다. IgnoreInvalidPunycode만으로는 충분하지 않은데, Punycode가 성공적으로 디코드될 수 있지만 여전히 유효성 기준에는 실패할 수 있기 때문이다. 예를 들어 xn--8i7caawww로 디코드되며, 그 코드 포인트들의 상태는 "mapped"이다. [UTS46]

  4. 그렇지 않으면:

    1. domain_namedomain으로 설정하고, CheckHyphens를 false로, CheckBidi를 true로, CheckJoiners를 true로, UseSTD3ASCIIRules를 false로, Transitional_Processing를 false로, VerifyDnsLength를 false로, IgnoreInvalidPunycode를 false로 설정하여 Unicode ToASCII를 실행한 결과로 result를 설정한다. [UTS46]

    2. result가 실패 값이면, domain-to-ASCII 검증 오류이며, 실패를 반환한다.

  5. result가 빈 문자열이면, domain-to-ASCII 검증 오류이며, 실패를 반환한다.

  6. result금지된 도메인 코드 포인트를 포함하면, domain-invalid-code-point 검증 오류이며, 실패를 반환한다.

    웹 호환성 및 DNS 기반이 아닌 시스템과의 호환성 때문에 금지된 도메인 코드 포인트UseSTD3ASCIIRules가 true일 때 허용되지 않는 것들의 하위 집합이다. issue #397도 참조하라.

  7. result를 반환한다.

이 문서와 웹 플랫폼 전반은 IDNA2008이 아니라 Unicode IDNA Compatibility Processing을 사용한다. 예를 들어, ☕.example은 실패가 아니라 xn--53h.example이 된다. [UTS46] [RFC5890]

도메인 domain이 주어졌을 때, domain to Unicode 알고리즘은 다음 단계를 실행한다:

  1. domain_namedomain으로 설정하고, CheckHyphens를 false로, CheckBidi를 true로, CheckJoiners를 true로, UseSTD3ASCIIRules를 false로, Transitional_Processing를 false로, IgnoreInvalidPunycode를 false로 설정하여 Unicode ToUnicode를 실행한 결과를 result라 하자. [UTS46]

  2. 오류가 기록되었다면, domain을 반환한다.

    domain호스트 파서의 결과로만 나올 수 있으므로, 기록된 모든 오류는 이미 검증 오류로 표시되었을 것이다. domain을 반환하면 도메인 파서domain to Unicodexn--8i7caa와 같은 입력에서 왕복 변환되도록 보장한다.

  3. result를 반환한다.

3.4. 호스트 작성

유효한 호스트 문자열유효한 도메인 문자열, 유효한 IPv4 주소 문자열, 또는 다음이어야 한다: U+005B ([), 뒤이어 유효한 IPv6 주소 문자열, 뒤이어 U+005D (]).

문자열 input은 다음 단계들이 true를 반환하면 유효한 도메인이다:

  1. domaininput 및 true로 도메인 파서를 실행한 결과라 하자.

  2. domain이 failure이면 false를 반환하고, 그렇지 않으면 true를 반환한다.

이상적으로는 이를 두더지 잡기식 방식이 아니라 유효한 도메인을 구성하는 코드 포인트 시퀀스로 정의한다: issue 245.

유효한 도메인 문자열유효한 도메인인 문자열이어야 한다.

유효한 IPv4 주소 문자열은 0부터 255까지의 범위에 있는 십진수를 나타내는 ASCII 숫자로 된 가능한 한 가장 짧은 문자열 네 개가 U+002E (.)로 서로 구분된 것이어야 한다.

유효한 IPv6 주소 문자열IP 버전 6 주소 지정 아키텍처의 "주소의 텍스트 표현" 장에서 정의된다. [RFC4291]

유효한 불투명 호스트 문자열은 다음 중 하나여야 한다:

이는 구별하기 위해 문맥이 필요하므로 유효한 호스트 문자열 정의의 일부가 아니다.

3.5. 호스트 파싱

호스트 파서는 선택적 불리언 isOpaque(기본값 false)와 함께 스칼라 값 문자열 input을 받아, 다음 단계를 실행한다. 이 단계들은 실패 또는 호스트를 반환한다.

  1. input이 U+005B ([)로 시작하면:

    1. input이 U+005D (])로 끝나지 않으면, IPv6-unclosed 검증 오류이며, 실패를 반환한다.

    2. 선행 U+005B ([)와 후행 U+005D (])를 제거한 input으로 IPv6 파싱을 수행한 결과를 반환한다.

  2. isOpaque가 true이면, input으로 불투명 호스트 파싱을 수행한 결과를 반환한다.

  3. Assert: input은 빈 문자열이 아니다.

  4. input퍼센트 디코딩에 대해 BOM 없는 UTF-8 디코드를 실행한 결과를 domain이라 하자.

    또는 실패에 대한 조기 반환과 결합하여 BOM 없는 UTF-8 디코드 또는 실패를 사용할 수도 있다. 이는 도메인 파서가 U+FFFD (�)에서 실패하기 때문이다.

  5. domain 및 false로 도메인 파서를 실행한 결과를 asciiDomain이라 하자.

  6. asciiDomain이 실패이면, 실패를 반환한다.

  7. asciiDomain숫자로 끝나면, asciiDomain으로 IPv4 파싱을 수행한 결과를 반환한다.

  8. asciiDomain을 반환한다.


숫자로 끝나는지 검사기ASCII 문자열 input을 받아 다음 단계를 실행합니다. 이 단계들은 불리언을 반환합니다.

  1. partsinput을 U+002E (.)에서 엄격하게 분할한 결과로 둡니다.

  2. parts의 마지막 항목이 빈 문자열이면:

    1. parts크기가 1이면, false를 반환합니다.

    2. parts에서 마지막 항목제거합니다.

  3. lastparts의 마지막 항목으로 둡니다.

  4. last가 비어 있지 않고 ASCII 숫자만 포함하면, true를 반환합니다.

    잘못된 입력 "09"는 이후 단계에서 IPv4 파서에 의해 잡힙니다.

  5. lastIPv4 숫자로 구문 분석한 결과가 실패를 반환하지 않으면, true를 반환합니다.

    이는 last가 "0X" 또는 "0x"이고, 그 뒤에 0개 이상의 ASCII 16진수 숫자가 오는지 검사하는 것과 같습니다.

  6. false를 반환합니다.

IPv4 파서ASCII 문자열 input을 받아 다음 단계를 실행합니다. 이 단계들은 실패 또는 IPv4 주소를 반환합니다.

IPv4 파서는 직접 호출되어서는 안 됩니다. 대신 호스트 파서의 반환값이 IPv4 주소인지 확인하십시오.

  1. partsinput을 U+002E (.)에서 엄격하게 분할한 결과로 둡니다.

  2. parts의 마지막 항목이 빈 문자열이면:

    1. IPv4-empty-part 검증 오류.

    2. parts크기가 1보다 크면, parts에서 마지막 항목제거합니다.

  3. parts크기가 4보다 크면, IPv4-too-many-parts 검증 오류, 실패를 반환합니다.

  4. numbers를 빈 리스트로 둡니다.

  5. parts의 각 part에 대해 반복합니다:

    1. resultpart구문 분석한 결과로 둡니다.

    2. result가 실패이면, IPv4-non-numeric-part 검증 오류, 실패를 반환합니다.

    3. result[1]이 true이면, IPv4-non-decimal-part 검증 오류.

    4. result[0]을 numbers추가합니다.

  6. numbers의 어떤 항목이라도 255보다 크면, IPv4-out-of-range-part 검증 오류.

  7. numbers에서 마지막 항목을 제외한 어떤 항목이라도 255보다 크면, 실패를 반환합니다.

  8. numbers의 마지막 항목이 256(5 − numbers크기) 이상이면, 실패를 반환합니다.

  9. ipv4numbers의 마지막 항목으로 둡니다.

  10. numbers에서 마지막 항목제거합니다.

  11. counter를 0으로 둡니다.

  12. numbers의 각 n에 대해 반복합니다:

    1. ipv4n × 256(3 − counter)만큼 증가시킵니다.

    2. counter를 1만큼 증가시킵니다.

  13. ipv4를 반환합니다.

IPv4 숫자 파서ASCII 문자열 input을 받아 다음 단계를 실행합니다. 이 단계들은 실패 또는 숫자와 불리언의 튜플을 반환합니다.

  1. input이 빈 문자열이면, 실패를 반환합니다.

  2. validationError를 false로 둡니다.

  3. R을 10으로 둡니다.

  4. input이 적어도 두 개의 코드 포인트를 포함하고 첫 두 코드 포인트가 "0X" 또는 "0x"이면:

    1. validationError를 true로 설정합니다.

    2. input에서 첫 두 코드 포인트를 제거합니다.

    3. R을 16으로 설정합니다.

  5. 그렇지 않고, input이 적어도 두 개의 코드 포인트를 포함하고 첫 코드 포인트가 U+0030 (0)이면:

    1. validationError를 true로 설정합니다.

    2. input에서 첫 코드 포인트를 제거합니다.

    3. R을 8로 설정합니다.

  6. input이 빈 문자열이면, (0, true)를 반환합니다.

  7. input이 기수-R 숫자가 아닌 코드 포인트를 포함하면, 실패를 반환합니다.

  8. outputASCII 16진수 숫자를 값 0부터 15까지의 숫자에 사용하여, input이 기수-R 표기법으로 나타내는 수학적 정수 값으로 둡니다.

  9. (output, validationError)를 반환합니다.


IPv6 파서스칼라 값 문자열 input을 받아 다음 단계를 실행합니다. 이 단계들은 실패 또는 IPv6 주소를 반환합니다.

IPv6 파서는 이론상 직접 호출될 수 있지만, 실제로 그렇게 하기 전에 이 문서의 편집자들과 논의하십시오.

  1. IPv6 주소인 새 address를 두며, 그 조각은 모두 0입니다.

  2. pieceIndex를 0으로 둡니다.

  3. compress를 null로 둡니다.

  4. pointerinput에 대한 포인터로 둡니다.

  5. c가 U+003A (:)이면:

    1. remaining이 U+003A (:)로 시작하지 않으면, IPv6-invalid-compression 검증 오류, 실패를 반환합니다.

    2. pointer를 2만큼 증가시킵니다.

    3. pieceIndex를 1만큼 증가시킨 다음 compresspieceIndex로 설정합니다.

  6. cEOF 코드 포인트가 아닌 동안:

    1. pieceIndex가 8이면, IPv6-too-many-pieces 검증 오류, 실패를 반환합니다.

    2. c가 U+003A (:)이면:

      1. compress가 null이 아니면, IPv6-multiple-compression 검증 오류, 실패를 반환합니다.

      2. pointerpieceIndex를 1만큼 증가시키고, compresspieceIndex로 설정한 다음, 계속합니다.
    3. valuelength를 0으로 둡니다.

    4. length가 4보다 작고 cASCII 16진수 숫자인 동안, valuevalue × 0x10 + 16진수로 해석한 c로 설정하고, pointerlength를 1씩 증가시킵니다.

    5. c가 U+002E (.)이면:

      1. length가 0이면, IPv4-in-IPv6-invalid-code-point 검증 오류, 실패를 반환합니다.

      2. pointerlength만큼 감소시킵니다.

      3. pieceIndex가 6보다 크면, IPv4-in-IPv6-too-many-pieces 검증 오류, 실패를 반환합니다.

      4. numbersSeen을 0으로 둡니다.

      5. cEOF 코드 포인트가 아닌 동안:

        1. ipv4Piece를 null로 둡니다.

        2. numbersSeen이 0보다 크면:

          1. c가 U+002E (.)이고 numbersSeen이 4보다 작으면, pointer를 1만큼 증가시킵니다.

          2. 그렇지 않으면, IPv4-in-IPv6-invalid-code-point 검증 오류, 실패를 반환합니다.
        3. cASCII 숫자가 아니면, IPv4-in-IPv6-invalid-code-point 검증 오류, 실패를 반환합니다.

        4. cASCII 숫자인 동안:

          1. number를 십진수로 해석한 c로 둡니다.

          2. ipv4Piece가 null이면, ipv4Piecenumber로 설정합니다.

          3. 그렇지 않고, ipv4Piece가 0이면, IPv4-in-IPv6-invalid-code-point 검증 오류, 실패를 반환합니다.

          4. 그렇지 않으면, ipv4Pieceipv4Piece × 10 + number로 설정합니다.

          5. ipv4Piece가 255보다 크면, IPv4-in-IPv6-out-of-range-part 검증 오류, 실패를 반환합니다.

          6. pointer를 1만큼 증가시킵니다.

        5. address[pieceIndex]를 address[pieceIndex] × 0x100 + ipv4Piece로 설정합니다.

        6. numbersSeen을 1만큼 증가시킵니다.

        7. numbersSeen이 2 또는 4이면, pieceIndex를 1만큼 증가시킵니다.

      6. numbersSeen이 4가 아니면, IPv4-in-IPv6-too-few-parts 검증 오류, 실패를 반환합니다.

      7. 중단합니다.

    6. 그렇지 않고, c가 U+003A (:)이면:

      1. pointer를 1만큼 증가시킵니다.

      2. cEOF 코드 포인트이면, IPv6-invalid-code-point 검증 오류, 실패를 반환합니다.

    7. 그렇지 않고, cEOF 코드 포인트가 아니면, IPv6-invalid-code-point 검증 오류, 실패를 반환합니다.

    8. address[pieceIndex]를 value로 설정합니다.

    9. pieceIndex를 1만큼 증가시킵니다.

  7. compress가 null이 아니면:

    1. swapspieceIndexcompress로 둡니다.

    2. pieceIndex를 7로 설정합니다.

    3. pieceIndex가 0이 아니고 swaps가 0보다 큰 동안, address[pieceIndex]를 address[compress + swaps − 1]과 교환한 다음, pieceIndexswaps를 모두 1만큼 감소시킵니다.

  8. 그렇지 않고, compress가 null이고 pieceIndex가 8이 아니면, IPv6-too-few-pieces 검증 오류, 실패를 반환합니다.

  9. address를 반환합니다.


불투명 호스트 파서스칼라 값 문자열 input을 받아 다음 단계를 실행합니다. 이 단계들은 실패 또는 불투명 호스트를 반환합니다.

  1. input금지된 호스트 코드 포인트를 포함하면, host-invalid-code-point 검증 오류, 실패를 반환합니다.

  2. input코드 포인트URL 코드 포인트가 아니고 U+0025 (%)도 아닌 것을 포함하면, invalid-URL-unit 검증 오류.

  3. input이 U+0025 (%)를 포함하고, 그 뒤의 두 코드 포인트ASCII 16진수 숫자가 아니면, invalid-URL-unit 검증 오류.

  4. C0 제어 퍼센트 인코딩 집합을 사용해 inputUTF-8 퍼센트 인코딩을 실행한 결과를 반환합니다.

3.6. 호스트 직렬화

호스트 직렬화기호스트 host를 받아 다음 단계를 실행합니다. 이 단계들은 ASCII 문자열을 반환합니다.

  1. hostIPv4 주소이면, hostIPv4 직렬화기를 실행한 결과를 반환합니다.

  2. 그렇지 않고, hostIPv6 주소이면, U+005B ([) 뒤에 hostIPv6 직렬화기를 실행한 결과가 오고, 그 뒤에 U+005D (])가 오는 문자열을 반환합니다.

  3. 그렇지 않으면, host도메인, 불투명 호스트, 또는 빈 호스트이므로, host를 반환합니다.

IPv4 직렬화기IPv4 주소 address를 받아 다음 단계를 실행합니다. 이 단계들은 ASCII 문자열을 반환합니다.

  1. output을 빈 문자열로 둡니다.

  2. naddress의 값으로 둡니다.

  3. 1부터 4까지의 범위(양끝 포함)에 있는 각 i에 대해 반복합니다:

    1. n % 256을 직렬화한 값을 output 앞에 붙입니다.

    2. i가 4가 아니면, U+002E (.)를 output 앞에 붙입니다.

    3. n을 floor(n / 256)으로 설정합니다.

  4. output을 반환합니다.

IPv6 직렬화기IPv6 주소 address를 받아 다음 단계를 실행합니다. 이 단계들은 ASCII 문자열을 반환합니다.

  1. output을 빈 문자열로 둡니다.

  2. compressaddress가 주어졌을 때 IPv6 주소의 압축된 조각 인덱스를 찾은 결과로 둡니다.

  3. ignore0을 false로 둡니다.

  4. address조각들의 인덱스에 있는 각 pieceIndex에 대해 반복합니다:

    1. ignore0이 true이고 address[pieceIndex]가 0이면, 계속합니다.

    2. 그렇지 않고, ignore0이 true이면, ignore0을 false로 설정합니다.

    3. compresspieceIndex이면:

      1. separatorpieceIndex가 0이면 "::"로, 그렇지 않으면 U+003A (:)로 둡니다.

      2. separatoroutput에 추가합니다.

      3. ignore0을 true로 설정하고 계속합니다.

    4. address[pieceIndex]를 가능한 가장 짧은 소문자 16진수로 표현하여 output에 추가합니다.

    5. pieceIndex가 7이 아니면, U+003A (:)를 output에 추가합니다.

  5. output을 반환합니다.

이 알고리즘은 A Recommendation for IPv6 Address Text Representation의 권고를 필요로 합니다. [RFC5952]

IPv6 주소의 압축된 조각 인덱스를 찾으려면, IPv6 주소 address가 주어졌을 때:

  1. longestIndex를 null로 둡니다.

  2. longestSize를 1로 둡니다.

  3. foundIndex를 null로 둡니다.

  4. foundSize를 0으로 둡니다.

  5. address조각들의 인덱스에 있는 각 pieceIndex에 대해 반복합니다:

    1. address조각[pieceIndex]이 0이 아니면:

      1. foundSizelongestSize보다 크면, longestIndexfoundIndex로 설정하고 longestSizefoundSize로 설정합니다.

      2. foundIndex를 null로 설정합니다.
      3. foundSize를 0으로 설정합니다.
    2. 그렇지 않으면:

      1. foundIndex가 null이면, foundIndexpieceIndex로 설정합니다.

      2. foundSize를 1만큼 증가시킵니다.

  6. foundSizelongestSize보다 크면, foundIndex를 반환합니다.

  7. longestIndex를 반환합니다.

0:f:0:0:f:f:0:0에서는 두 번째 0을 가리키게 됩니다.

3.7. 호스트 동등성

호스트 A호스트 B동등한지 판단하려면, AB와 같으면 true를, 아니면 false를 반환합니다.

인증서 비교는 도메인의 끝점 점을 무시하는 호스트 동등성 비교가 필요합니다. 그러나 이러한 호스트는 DNS 길이 등 URL에서 강제하지 않는 다양한 측면도 강제됩니다. 이 둘을 더 가깝게 만들 방법이나 좋은 통합 모델에 관한 의견이 있으면 issue를 등록해주세요.

4. URL

상위 수준에서, URL, 유효한 URL 문자열, URL 파서, 그리고 URL 직렬화기는 다음과 같이 관련됩니다:

입력 기준(Base) 유효성 출력
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

기준(Base)과 출력 URL은 간결함을 위해 직렬화 형태로 표시됩니다.

4.1. URL 표현

URL은 범용 식별자를 나타내는 구조체입니다. 유효한 URL 문자열과 구분하기 위해, URL 레코드라고도 부를 수 있습니다.

URL스킴ASCII 문자열로, URL의 유형을 식별하며 구문 분석 후 추가 처리를 위해 URL을 전달하는 데 사용할 수 있습니다. 초기값은 빈 문자열입니다.

URL사용자 이름은 사용자 이름을 식별하는 ASCII 문자열입니다. 초기값은 빈 문자열입니다.

URL비밀번호는 비밀번호를 식별하는 ASCII 문자열입니다. 초기값은 빈 문자열입니다.

URL호스트는 null 또는 호스트입니다. 초기값은 null입니다.

다음 표는 허용되는 URLscheme / host 조합을 보여줍니다.

scheme host
도메인 IPv4 주소 IPv6 주소 불투명 호스트 빈 호스트 null
특수 scheme (단 "file" 제외)
"file"
기타

URLport는 null 또는 네트워킹 포트를 식별하는 16비트 부호 없는 정수입니다. 처음에는 null입니다.

URLpath는 보통 위치를 식별하는 URL 경로입니다. 처음에는 « »입니다.

특수한 URL경로는 항상 리스트입니다. 즉, 불투명하지 않습니다.

URLquery는 null 또는 ASCII 문자열입니다. 처음에는 null입니다.

URLfragment는 null 또는 ASCII 문자열이며, URL의 다른 컴포넌트가 식별하는 리소스에서 추가 처리에 사용할 수 있습니다. 처음에는 null입니다.

URL에는 null 또는 blob URL entryblob URL entry가 연결되어 있습니다. 처음에는 null입니다.

이는 "blob" URL이 참조하는 객체와 그 origin을 캐싱하는 데 사용됩니다. URL이 파싱과 fetch 사이에 blob URL store에서 제거되어도 fetch가 성공해야 하므로 캐싱이 중요합니다.

다음 표는 유효한 URL 문자열파싱했을 때 URL의 컴포넌트로 어떻게 매핑되는지를 보여줍니다. username, password, blob URL entry는 생략되었으며, 아래 예시에서는 각각 빈 문자열, 빈 문자열, null입니다.

입력 스킴 호스트 포트 경로 쿼리 fragment
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 문자열입니다. 일반적으로 디렉터리나 파일을 가리키지만, 사전에 정의된 의미는 없습니다.

A 단일 점 URL 경로 세그먼트는 "."이거나 "%2e"에 대한 ASCII 대소문자 구분 없는 일치인 URL 경로 세그먼트입니다.

A 이중 점 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 경로 세그먼트일 때입니다.

URLusername/password/port를 가질 수 없다host가 null이나 빈 문자열이거나, scheme이 "file"일 때입니다.

URL기본 URL로 지정될 수 있습니다.

기본 URL은 입력이 상대-URL 문자열일 수 있을 때 URL 파서에 유용합니다.


Windows 드라이브 문자는 두 개의 코드 포인트로, 첫 번째는 ASCII 알파벳이고 두 번째는 U+003A(:) 또는 U+007C(|)입니다.

정규화된 Windows 드라이브 문자는 두 번째 코드 포인트가 U+003A(:)인 Windows 드라이브 문자입니다.

URL 작성 섹션에 따라, 오직 정규화된 Windows 드라이브 문자만 적합합니다.

문자열이 Windows 드라이브 문자로 시작한다는 다음 조건을 모두 만족할 때입니다:

문자열 Windows 드라이브 문자로 시작
"c:"
"c:/"
"c:a"

url의 경로를 단축하기 절차:

  1. 단언: url불투명 경로를 가지지 않는다.

  2. pathurl경로로 둔다.

  3. urlscheme이 "file"이고 path크기가 1이며, path[0]이 정규화된 Windows 드라이브 문자이면 반환한다.

  4. 제거 path의 마지막 항목(있다면).

4.3. URL 작성

유효한 URL 문자열relative-URL-with-fragment 문자열 또는 absolute-URL-with-fragment 문자열이어야 합니다.

absolute-URL-with-fragment 문자열absolute-URL 문자열이며, 선택적으로 U+0023(#)와 URL-fragment 문자열이 뒤따를 수 있습니다.

absolute-URL 문자열은 다음 중 하나여야 합니다:

위 모두는 선택적으로 U+003F(?)와 URL-query 문자열이 뒤따를 수 있습니다.

URL-scheme 문자열은 하나의 ASCII 알파벳 뒤에 0개 이상의 ASCII 영숫자, U+002B(+), U+002D(-), U+002E(.)가 올 수 있습니다. schemeIANA URI [sic] Schemes 레지스트리에 등록해야 합니다. [IANA-URI-SCHEMES] [RFC7595]

relative-URL-with-fragment 문자열relative-URL 문자열이며, 선택적으로 U+0023(#)와 URL-fragment 문자열이 뒤따를 수 있습니다.

relative-URL 문자열기본 URLscheme에 따라 다음 중 하나여야 합니다:

특수 scheme, 단 "file" 제외

scheme-relative-special-URL 문자열

path-absolute-URL 문자열

path-relative-scheme-less-URL 문자열

"file"

scheme-relative-file-URL 문자열

path-absolute-URL 문자열 (기본 URL의 host빈 호스트일 때)

path-absolute-non-Windows-file-URL 문자열 (기본 URL의 host빈 호스트가 아닐 때)

path-relative-scheme-less-URL 문자열

기타

scheme-relative-URL 문자열

path-absolute-URL 문자열

path-relative-scheme-less-URL 문자열

위 모두는 선택적으로 U+003F(?)와 URL-query 문자열이 뒤따를 수 있습니다.

상대-URL 문자열을 파싱할 때는 기본 URL이 null이 아니어야 합니다.

scheme-relative-special-URL 문자열은 "//" 뒤에 유효한 호스트 문자열, 선택적으로 U+003A(:)와 URL-port 문자열, 선택적으로 path-absolute-URL 문자열이 뒤따라야 합니다.

URL-port 문자열은 다음 중 하나여야 합니다:

scheme-relative-URL 문자열은 "//" 뒤에 불투명-호스트-및-포트 문자열, 선택적으로 path-absolute-URL 문자열이 뒤따라야 합니다.

불투명-호스트-및-포트 문자열은 빈 문자열이거나, 유효한 불투명 호스트 문자열 뒤에 선택적으로 U+003A(:)와 URL-port 문자열이 올 수 있습니다.

scheme-relative-file-URL 문자열은 "//" 뒤에 다음 중 하나여야 합니다:

path-absolute-URL 문자열은 U+002F(/) 뒤에 path-relative-URL 문자열이 와야 합니다.

path-absolute-non-Windows-file-URL 문자열path-absolute-URL 문자열로, U+002F(/)로 시작하지 않으며, U+002F(/) 뒤에 Windows 드라이브 문자와 다시 U+002F(/)가 오지 않아야 합니다.

path-relative-URL 문자열은 0개 이상의 URL-path-segment 문자열로, U+002F(/)로 구분되며, 처음이 U+002F(/)가 아니어야 합니다.

path-relative-scheme-less-URL 문자열path-relative-URL 문자열로, 시작이 URL-scheme 문자열과 U+003A(:)가 아니어야 합니다.

URL-path-segment 문자열은 다음 중 하나여야 합니다:

URL-query 문자열은 0개 이상의 URL 유닛입니다.

URL-fragment 문자열은 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-query 문자열의 U+007F(DELETE) 초과 코드 포인트는 문서의 인코딩을 사용하여 퍼센트 인코딩 바이트로 변환됩니다. 이는 한 문서에서 동작하는 URL이 다른 인코딩을 사용하는 문서에 복사되면 문제가 생길 수 있습니다. UTF-8 인코딩을 항상 사용하면 이 문제가 해결됩니다.

예를 들어 다음 HTML 문서를 생각해보세요:

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

문서 인코딩이 windows-1252이므로, 링크의 URLquery는 "sm%F6rg%E5sbord"가 됩니다. 만약 인코딩이 UTF-8이었다면 "sm%C3%B6rg%C3%A5sbord"가 되었을 것입니다.

URL 유닛URL 코드 포인트퍼센트 인코딩 바이트입니다.

퍼센트 인코딩 바이트는 URL 코드 포인트가 아니거나 기록이 금지된 코드 포인트를 인코딩하는 데 사용할 수 있습니다.


username 또는 passwordURL 레코드에서 유효한 URL 문자열로 표현할 방법은 없습니다.

4.4. URL 파싱

URL 파서스칼라 값 문자열 input과 선택적 null 또는 기본 URL base(기본값 null), 선택적 encoding encoding(기본값 UTF-8)을 받아, 다음 단계를 실행합니다:

웹 브라우저가 아닌 구현체는 기본 URL 파서만 구현하면 됩니다.

웹 브라우저 주소창의 사용자 입력이 URL 레코드로 변환되는 과정은 이 표준의 범위에 포함되지 않습니다. 신뢰 결정과 관련된 URL 렌더링 요구사항은 포함되어 있습니다.

  1. url기본 URL 파서input, base, encoding에 대해 실행한 결과로 둡니다.

  2. url이 실패면 실패 반환.

  3. urlscheme이 "blob"이 아니면 url 반환.

  4. urlblob URL entryblob URL 해석 url 실행 결과(실패가 아니면)로, 실패면 null로 설정.

  5. url 반환.


기본 URL 파서스칼라 값 문자열 input과 선택적 null 또는 기본 URL base(기본값 null), 선택적 encoding encoding(기본값 UTF-8), 선택적 URL url, 선택적 상태 오버라이드 state override를 받아 다음 단계를 실행합니다:

encoding 인자는 레거시 개념으로 HTML에만 관련 있습니다. urlstate override 인자는 다양한 API만 사용합니다. [HTML]

urlstate override 인자가 전달되지 않으면 기본 URL 파서는 새 URL 또는 실패를 반환합니다. 전달되면, 알고리즘은 전달된 url을 수정하며 반환 없이 종료할 수 있습니다.

  1. url이 주어지지 않았다면:

    1. url을 새 URL로 설정합니다.

    2. input이 선행 또는 후행 C0 제어 문자 또는 공백을 포함하면, invalid-URL-unit 검증 오류.

    3. input에서 모든 선행 및 후행 C0 제어 문자 또는 공백을 제거합니다.

  2. inputASCII 탭 또는 줄바꿈을 포함하면, invalid-URL-unit 검증 오류.

  3. input에서 모든 ASCII 탭 또는 줄바꿈을 제거합니다.

  4. statestate override가 주어졌다면 그것으로, 그렇지 않으면 스킴 시작 상태로 둡니다.

  5. encodingencoding에서 출력 인코딩 얻기를 수행한 결과로 설정합니다.

  6. buffer를 빈 문자열로 둡니다.

  7. atSignSeen, insideBrackets, passwordTokenSeen을 false로 둡니다.

  8. pointerinput에 대한 포인터로 둡니다.

  9. state에 따라 전환하면서 다음 상태 기계를 계속 실행합니다. 실행 후 pointerEOF 코드 포인트를 가리키면, 다음 단계로 갑니다. 그렇지 않으면, pointer를 1만큼 증가시키고 상태 기계를 계속합니다.

    스킴 시작 상태
    1. cASCII 알파이면, c소문자화하여 buffer에 추가하고, state스킴 상태로 설정합니다.

    2. 그렇지 않고, state override가 주어지지 않았다면, state스킴 없음 상태로 설정하고 pointer를 1만큼 감소시킵니다.

    3. 그렇지 않으면, 실패를 반환합니다.

      이 실패 표시는 오직 Location 객체의 protocol setter에서만 사용됩니다.

    스킴 상태
    1. cASCII 영숫자, U+002B (+), U+002D (-), 또는 U+002E (.)이면, c소문자화하여 buffer에 추가합니다.

    2. 그렇지 않고, c가 U+003A (:)이면:

      1. state override가 주어졌다면:

        1. url스킴특수 스킴이고 buffer특수 스킴이 아니면, 반환합니다.

        2. url스킴특수 스킴이 아니고 buffer특수 스킴이면, 반환합니다.

        3. url자격 증명을 포함하거나 null이 아닌 포트를 가지고, buffer가 "file"이면, 반환합니다.

        4. url스킴이 "file"이고 그 호스트빈 호스트이면, 반환합니다.

      2. url스킴buffer로 설정합니다.

      3. state override가 주어졌다면:

        1. url포트url스킴기본 포트이면, url포트를 null로 설정합니다.

        2. 반환합니다.

      4. buffer를 빈 문자열로 설정합니다.

      5. url스킴이 "file"이면:

        1. remaining이 "//"로 시작하지 않으면, special-scheme-missing-following-solidus 검증 오류.

        2. statefile 상태로 설정합니다.

      6. 그렇지 않고, url특수하고, base가 null이 아니며, base스킴url스킴이라면:

        1. Assert: base특수합니다(따라서 불투명 경로를 갖지 않습니다).

        2. state특수 상대 또는 권한 상태로 설정합니다.

      7. 그렇지 않고, url특수하면, state특수 권한 슬래시 상태로 설정합니다.

      8. 그렇지 않고, remaining이 U+002F (/)로 시작하면, state경로 또는 권한 상태로 설정하고 pointer를 1만큼 증가시킵니다.

      9. 그렇지 않으면, url경로를 빈 문자열로 설정하고 state불투명 경로 상태로 설정합니다.

    3. 그렇지 않고, state override가 주어지지 않았다면, buffer를 빈 문자열로 설정하고, state스킴 없음 상태로 설정한 다음, (input의 첫 번째 코드 포인트부터) 다시 시작합니다.

    4. 그렇지 않으면, 실패를 반환합니다.

      이 실패 표시는 오직 Location 객체의 protocol setter에서만 사용됩니다. 또한, 이 상태에서 앞서 나오는 실패가 아닌 종료는 해당 setter를 정의하기 위한 의도적인 차이입니다.

    스킴 없음 상태
    1. base가 null이거나, base불투명 경로를 갖고 c가 U+0023 (#)이 아니면, missing-scheme-non-relative-URL 검증 오류, 실패를 반환합니다.

    2. 그렇지 않고, base불투명 경로를 갖고 c가 U+0023 (#)이면, url스킴base스킴으로, url경로base경로로, url쿼리base쿼리로, url프래그먼트를 빈 문자열로 설정하고, state프래그먼트 상태로 설정합니다.

    3. 그렇지 않고, base스킴이 "file"이 아니면, state상대 상태로 설정하고 pointer를 1만큼 감소시킵니다.

    4. 그렇지 않으면, statefile 상태로 설정하고 pointer를 1만큼 감소시킵니다.

    특수 상대 또는 권한 상태
    1. c가 U+002F (/)이고 remaining이 U+002F (/)로 시작하면, state특수 권한 슬래시 무시 상태로 설정하고 pointer를 1만큼 증가시킵니다.

    2. 그렇지 않으면, special-scheme-missing-following-solidus 검증 오류를 발생시키고, state상대 상태로 설정한 뒤 pointer를 1만큼 감소시킵니다.

    경로 또는 권한 상태
    1. c가 U+002F (/)이면, state권한 상태로 설정합니다.

    2. 그렇지 않으면, state경로 상태로 설정하고, pointer를 1만큼 감소시킵니다.

    상대 상태
    1. Assert: base스킴은 "file"이 아닙니다.

    2. url스킴base스킴으로 설정합니다.

    3. c가 U+002F (/)이면, state상대 슬래시 상태로 설정합니다.

    4. 그렇지 않고, url특수하고 c가 U+005C (\)이면, invalid-reverse-solidus 검증 오류를 발생시키고, state상대 슬래시 상태로 설정합니다.

    5. 그렇지 않으면:

      1. url사용자 이름base사용자 이름으로, url비밀번호base비밀번호로, url호스트base호스트로, url포트base포트로, url경로base경로복제본으로, 그리고 url쿼리base쿼리로 설정합니다.

      2. c가 U+003F (?)이면, url쿼리를 빈 문자열로 설정하고, state쿼리 상태로 설정합니다.

      3. 그렇지 않고, c가 U+0023 (#)이면, url프래그먼트를 빈 문자열로 설정하고 state프래그먼트 상태로 설정합니다.

      4. 그렇지 않고, cEOF 코드 포인트가 아니면:

        1. url쿼리를 null로 설정합니다.

        2. url경로단축합니다.

        3. state경로 상태로 설정하고 pointer를 1만큼 감소시킵니다.

    상대 슬래시 상태
    1. url특수하고 c가 U+002F (/) 또는 U+005C (\)이면:

      1. c가 U+005C (\)이면, invalid-reverse-solidus 검증 오류.

      2. state특수 권한 슬래시 무시 상태로 설정합니다.

    2. 그렇지 않고, c가 U+002F (/)이면, state권한 상태로 설정합니다.

    3. 그렇지 않으면, url사용자 이름base사용자 이름으로, url비밀번호base비밀번호로, url호스트base호스트로, url포트base포트로, state경로 상태로 설정한 다음, pointer를 1만큼 감소시킵니다.

    특수 권한 슬래시 상태
    1. c가 U+002F (/)이고 remaining이 U+002F (/)로 시작하면, state특수 권한 슬래시 무시 상태로 설정하고 pointer를 1만큼 증가시킵니다.

    2. 그렇지 않으면, special-scheme-missing-following-solidus 검증 오류를 발생시키고, state특수 권한 슬래시 무시 상태로 설정한 뒤 pointer를 1만큼 감소시킵니다.

    특수 권한 슬래시 무시 상태
    1. c가 U+002F (/) 및 U+005C (\) 중 어느 것도 아니면, state권한 상태로 설정하고 pointer를 1만큼 감소시킵니다.

    2. 그렇지 않으면, special-scheme-missing-following-solidus 검증 오류.

    권한 상태
    1. c가 U+0040 (@)이면:

      1. Invalid-credentials 검증 오류.

      2. atSignSeen이 true이면, "%40"을 buffer 앞에 붙입니다.

      3. atSignSeen을 true로 설정합니다.

      4. buffer의 각 codePoint에 대해:

        1. codePoint가 U+003A (:)이고 passwordTokenSeen이 false이면, passwordTokenSeen을 true로 설정하고 계속합니다.

        2. encodedCodePointsuserinfo 퍼센트 인코딩 집합을 사용해 codePointUTF-8 퍼센트 인코딩을 실행한 결과로 둡니다.

        3. passwordTokenSeen이 true이면, encodedCodePointsurl비밀번호에 추가합니다.

        4. 그렇지 않으면, encodedCodePointsurl사용자 이름에 추가합니다.

      5. buffer를 빈 문자열로 설정합니다.

    2. 그렇지 않고, 다음 중 하나가 true이면:

      그러면:

      1. atSignSeen이 true이고 buffer가 빈 문자열이면, host-missing 검증 오류, 실패를 반환합니다.

      2. pointerbuffer코드 포인트 길이 + 1만큼 감소시키고, buffer를 빈 문자열로 설정하며, state호스트 상태로 설정합니다.

    3. 그렇지 않으면, cbuffer에 추가합니다.

    호스트 상태
    호스트명 상태
    1. state override가 주어지고 url스킴이 "file"이면, pointer를 1만큼 감소시키고 statefile 호스트 상태로 설정합니다.

    2. 그렇지 않고, c가 U+003A (:)이고 insideBrackets가 false이면:

      1. buffer가 빈 문자열이면, host-missing 검증 오류, 실패를 반환합니다.

      2. state override가 주어지고 state override호스트명 상태이면, 실패를 반환합니다.

      3. hosturl특수가 아님으로 하여 buffer호스트 구문 분석을 수행한 결과로 둡니다.

      4. host가 실패이면, 실패를 반환합니다.

      5. url호스트host로, buffer를 빈 문자열로, state포트 상태로 설정합니다.

    3. 그렇지 않고, 다음 중 하나가 true이면:

      그러면 pointer를 1만큼 감소시키고, 다음을 수행합니다:

      1. url특수하고 buffer가 빈 문자열이면, host-missing 검증 오류, 실패를 반환합니다.

      2. 그렇지 않고, state override가 주어졌고, buffer가 빈 문자열이며, url자격 증명을 포함하거나 url포트가 null이 아니면, 실패를 반환합니다.

      3. hosturl특수가 아님으로 하여 buffer호스트 구문 분석을 수행한 결과로 둡니다.

      4. host가 실패이면, 실패를 반환합니다.

      5. url호스트host로, buffer를 빈 문자열로, state경로 시작 상태로 설정합니다.

      6. state override가 주어졌다면, 반환합니다.

    4. 그렇지 않으면:

      1. c가 U+005B ([)이면, insideBrackets를 true로 설정합니다.

      2. c가 U+005D (])이면, insideBrackets를 false로 설정합니다.

      3. cbuffer에 추가합니다.

    포트 상태
    1. cASCII 숫자이면, cbuffer에 추가합니다.

    2. 그렇지 않고, 다음 중 하나가 true이면:

      • cEOF 코드 포인트, U+002F (/), U+003F (?), 또는 U+0023 (#)입니다;

      • url특수하고 c가 U+005C (\)입니다; 또는

      • state override가 주어졌습니다,

      그러면:

      1. buffer가 빈 문자열이 아니면:

        1. port를 값 0부터 9까지의 숫자에 ASCII 숫자를 사용해 기수 10으로 buffer가 나타내는 수학적 정수 값으로 둡니다.

        2. port16비트 부호 없는 정수가 아니면, port-out-of-range 검증 오류, 실패를 반환합니다.

        3. porturl스킴기본 포트이면 url포트를 null로 설정하고, 그렇지 않으면 port로 설정합니다.

        4. buffer를 빈 문자열로 설정합니다.

        5. state override가 주어졌다면, 반환합니다.

      2. state override가 주어졌다면, 실패를 반환합니다.

      3. state경로 시작 상태로 설정하고 pointer를 1만큼 감소시킵니다.

    3. 그렇지 않으면, port-invalid 검증 오류, 실패를 반환합니다.

    file 상태
    1. url스킴을 "file"로 설정합니다.

    2. url호스트를 빈 문자열로 설정합니다.

    3. c가 U+002F (/) 또는 U+005C (\)이면:

      1. c가 U+005C (\)이면, invalid-reverse-solidus 검증 오류.

      2. statefile 슬래시 상태로 설정합니다.

    4. 그렇지 않고, base가 null이 아니고 base스킴이 "file"이면:

      1. url호스트base호스트로, url경로base경로복제본으로, 그리고 url쿼리base쿼리로 설정합니다.

      2. c가 U+003F (?)이면, url쿼리를 빈 문자열로 설정하고 state쿼리 상태로 설정합니다.

      3. 그렇지 않고, c가 U+0023 (#)이면, url프래그먼트를 빈 문자열로 설정하고 state프래그먼트 상태로 설정합니다.

      4. 그렇지 않고, cEOF 코드 포인트가 아니면:

        1. url쿼리를 null로 설정합니다.

        2. pointer에서 input의 끝까지의 코드 포인트 부분 문자열Windows 드라이브 문자로 시작하지 않으면, url경로단축합니다.

        3. 그렇지 않으면:

          1. File-invalid-Windows-drive-letter 검증 오류.

          2. url경로를 « »로 설정합니다.

          이는 (플랫폼 독립적인) Windows 드라이브 문자 특이 사항입니다.

        4. state경로 상태로 설정하고 pointer를 1만큼 감소시킵니다.

    5. 그렇지 않으면, state경로 상태로 설정하고, pointer를 1만큼 감소시킵니다.

    file 슬래시 상태
    1. c가 U+002F (/) 또는 U+005C (\)이면:

      1. c가 U+005C (\)이면, invalid-reverse-solidus 검증 오류.

      2. statefile 호스트 상태로 설정합니다.

    2. 그렇지 않으면:

      1. base가 null이 아니고 base스킴이 "file"이면:

        1. url호스트base호스트로 설정합니다.

        2. pointer에서 input의 끝까지의 코드 포인트 부분 문자열Windows 드라이브 문자로 시작하지 않고, base경로[0]이 정규화된 Windows 드라이브 문자이면, base경로[0]을 url경로추가합니다.

          이는 (플랫폼 독립적인) Windows 드라이브 문자 특이 사항입니다.

      2. state경로 상태로 설정하고, pointer를 1만큼 감소시킵니다.

    file 호스트 상태
    1. cEOF 코드 포인트, U+002F (/), U+005C (\), U+003F (?), 또는 U+0023 (#)이면, pointer를 1만큼 감소시킨 다음:

      1. state override가 주어지지 않았고 bufferWindows 드라이브 문자이면, file-invalid-Windows-drive-letter-host 검증 오류를 발생시키고, state경로 상태로 설정합니다.

        이는 (플랫폼 독립적인) Windows 드라이브 문자 특이 사항입니다. 여기서 buffer는 재설정되지 않고 대신 경로 상태에서 사용됩니다.

      2. 그렇지 않고, buffer가 빈 문자열이면:

        1. url호스트를 빈 문자열로 설정합니다.

        2. state override가 주어졌다면, 반환합니다.

        3. state경로 시작 상태로 설정합니다.

      3. 그렇지 않으면, 다음 단계를 실행합니다:

        1. hosturl특수가 아님으로 하여 buffer호스트 구문 분석을 수행한 결과로 둡니다.

        2. host가 실패이면, 실패를 반환합니다.

        3. host가 "localhost"이면, host를 빈 문자열로 설정합니다.

        4. url호스트host로 설정합니다.

        5. state override가 주어졌다면, 반환합니다.

        6. buffer를 빈 문자열로 설정하고 state경로 시작 상태로 설정합니다.

    2. 그렇지 않으면, cbuffer에 추가합니다.

    경로 시작 상태
    1. url특수하면:

      1. c가 U+005C (\)이면, invalid-reverse-solidus 검증 오류.

      2. state경로 상태로 설정합니다.

      3. c가 U+002F (/) 및 U+005C (\) 중 어느 것도 아니면, pointer를 1만큼 감소시킵니다.

    2. 그렇지 않고, state override가 주어지지 않았고 c가 U+003F (?)이면, url쿼리를 빈 문자열로 설정하고 state쿼리 상태로 설정합니다.

    3. 그렇지 않고, state override가 주어지지 않았고 c가 U+0023 (#)이면, url프래그먼트를 빈 문자열로 설정하고 state프래그먼트 상태로 설정합니다.

    4. 그렇지 않고, cEOF 코드 포인트가 아니면:

      1. state경로 상태로 설정합니다.

      2. c가 U+002F (/)가 아니면, pointer를 1만큼 감소시킵니다.

    5. 그렇지 않고, state override가 주어졌으며 url호스트가 null이면, 빈 문자열을 url경로추가합니다.

    경로 상태
    1. 다음 중 하나가 true이면:

      • cEOF 코드 포인트 또는 U+002F (/)입니다

      • url특수하고 c가 U+005C (\)입니다

      • state override가 주어지지 않았고 c가 U+003F (?) 또는 U+0023 (#)입니다

      그러면:

      1. url특수하고 c가 U+005C (\)이면, invalid-reverse-solidus 검증 오류.

      2. buffer이중 점 URL 경로 세그먼트이면:

        1. url경로단축합니다.

        2. c가 U+002F (/)가 아니고, url특수하며 c가 U+005C (\)인 것도 아니면, 빈 문자열을 url경로추가합니다.

          이는 입력 /usr/..에 대해 결과가 경로 없음이 아니라 /임을 의미합니다.

      3. 그렇지 않고, buffer단일 점 URL 경로 세그먼트이며, c가 U+002F (/)도 아니고, url특수하며 c가 U+005C (\)인 것도 아니면, 빈 문자열을 url경로추가합니다.

      4. 그렇지 않고, buffer단일 점 URL 경로 세그먼트가 아니면:

        1. url스킴이 "file"이고, url경로비어 있으며, bufferWindows 드라이브 문자이면, buffer의 두 번째 코드 포인트를 U+003A (:)로 교체합니다.

          이는 (플랫폼 독립적인) Windows 드라이브 문자 특이 사항입니다.

        2. bufferurl경로추가합니다.

      5. buffer를 빈 문자열로 설정합니다.

      6. c가 U+003F (?)이면, url쿼리를 빈 문자열로 설정하고 state쿼리 상태로 설정합니다.

      7. c가 U+0023 (#)이면, url프래그먼트를 빈 문자열로 설정하고 state프래그먼트 상태로 설정합니다.

    2. 그렇지 않으면, 다음 단계를 실행합니다:

      1. cURL 코드 포인트가 아니고 U+0025 (%)도 아니면, invalid-URL-unit 검증 오류.

      2. c가 U+0025 (%) 이고 remaining이 두 개의 ASCII 16진수 숫자로 시작하지 않으면, invalid-URL-unit 검증 오류.

      3. 경로 퍼센트 인코딩 집합을 사용해 cUTF-8 퍼센트 인코딩을 수행하고, 그 결과를 buffer에 추가합니다.

    불투명 경로 상태
    1. c가 U+003F (?)이면, url쿼리를 빈 문자열로 설정하고 state쿼리 상태로 설정합니다.

    2. 그렇지 않고, c가 U+0023 (#)이면, url프래그먼트를 빈 문자열로 설정하고 state프래그먼트 상태로 설정합니다.

    3. 그렇지 않고, c가 U+0020 SPACE이면:

      1. remaining이 U+003F (?) 또는 U+0023 (#)로 시작하면, "%20"을 url경로에 추가합니다.

      2. 그렇지 않으면, U+0020 SPACE를 url경로에 추가합니다.

    4. 그렇지 않고, cEOF 코드 포인트가 아니면:

      1. cURL 코드 포인트가 아니고 U+0025 (%)도 아니면, invalid-URL-unit 검증 오류.

      2. c가 U+0025 (%) 이고 remaining이 두 개의 ASCII 16진수 숫자로 시작하지 않으면, invalid-URL-unit 검증 오류.

      3. C0 제어 퍼센트 인코딩 집합을 사용해 cUTF-8 퍼센트 인코딩을 수행하고, 그 결과를 url경로에 추가합니다.

    쿼리 상태
    1. encodingUTF-8이 아니고 다음 중 하나가 true이면:

      그러면 encodingUTF-8로 설정합니다.

    2. 다음 중 하나가 true이면:

      그러면:

      1. queryPercentEncodeSeturl특수하면 special-query 퍼센트 인코딩 집합으로, 그렇지 않으면 쿼리 퍼센트 인코딩 집합으로 둡니다.

      2. encoding, buffer, queryPercentEncodeSet을 사용해 인코딩 후 퍼센트 인코딩을 수행하고, 그 결과를 url쿼리에 추가합니다.

        이 작업은 상태를 가지는 ISO-2022-JP 인코더 때문에 코드 포인트별로 호출할 수 없습니다.

      3. buffer를 빈 문자열로 설정합니다.

      4. c가 U+0023 (#)이면, url프래그먼트를 빈 문자열로 설정하고 state프래그먼트 상태로 설정합니다.

    3. 그렇지 않고, cEOF 코드 포인트가 아니면:

      1. cURL 코드 포인트가 아니고 U+0025 (%)도 아니면, invalid-URL-unit 검증 오류.

      2. c가 U+0025 (%) 이고 remaining이 두 개의 ASCII 16진수 숫자로 시작하지 않으면, invalid-URL-unit 검증 오류.

      3. cbuffer에 추가합니다.

    프래그먼트 상태
    1. cEOF 코드 포인트가 아니면:

      1. cURL 코드 포인트가 아니고 U+0025 (%)도 아니면, invalid-URL-unit 검증 오류.

      2. c가 U+0025 (%) 이고 remaining이 두 개의 ASCII 16진수 숫자로 시작하지 않으면, invalid-URL-unit 검증 오류.

      3. 프래그먼트 퍼센트 인코딩 집합을 사용해 cUTF-8 퍼센트 인코딩을 수행하고, 그 결과를 url프래그먼트에 추가합니다.

  10. url을 반환합니다.


username 설정urlusername에 대해 실행할 때, urlusernameusernameUTF-8 퍼센트 인코드userinfo percent-encode set으로 실행한 결과로 설정한다.

password 설정urlpassword에 대해 실행할 때, urlpasswordpasswordUTF-8 퍼센트 인코드userinfo percent-encode set으로 실행한 결과로 설정한다.

4.5. URL 직렬화

URL 직렬화기URL url과, 선택적 불리언 fragment 제외(기본값 false)를 받아 다음 단계를 실행한다. 반환값은 ASCII 문자열이다.

  1. outputurlscheme과 U+003A(:)를 연결한 값으로 둔다.

  2. urlhost가 null이 아니면:

    1. "//"를 output에 추가.

    2. url자격 증명 포함이면:

      1. urlusernameoutput에 추가.

      2. urlpassword가 빈 문자열이 아니면, U+003A(:)와 urlpasswordoutput에 추가.

      3. U+0040(@)를 output에 추가.

    3. urlhost직렬화하여 output에 추가.

    4. urlport가 null이 아니면, U+003A(:)와 urlport직렬화하여 output에 추가.

  3. urlhost가 null이고, url불투명 경로를 가지지 않으며, url경로크기가 1보다 크고, url경로[0]이 빈 문자열이면, U+002F(/)와 U+002E(.)를 output에 추가한다.

    이것은 web+demo:/.//not-a-host/ 또는 web+demo:/path/..//not-a-host/가 파싱 후 직렬화되어 web+demo://not-a-host/가 되지 않게 한다(결과는 web+demo:/.//not-a-host/).

  4. URL 경로 직렬화url에 대해 실행한 결과를 output에 추가.

  5. urlquery가 null이 아니면, U+003F(?)와 urlqueryoutput에 추가.

  6. exclude fragment가 false이고 urlfragment가 null이 아니면, U+0023(#)와 urlfragmentoutput에 추가.

  7. output을 반환.

URL 경로 직렬화기URL url을 받아 다음 단계를 실행한다. 반환값은 ASCII 문자열이다.

  1. url불투명 경로를 가지면 url경로를 반환한다.

  2. output을 빈 문자열로 둔다.

  3. segment에 대해 url경로에서, U+002F(/)와 segmentoutput에 추가한다.

  4. output을 반환.

4.6. URL 동등성

URL AURL B동일한지 판단할 때, 선택적 불리언 fragment 제외(기본값: false)와 함께 다음 단계를 실행한다:

  1. serializedA직렬화A에 대해 fragment 제외fragment 제외로 하여 실행한 결과로 둔다.

  2. serializedB직렬화B에 대해 fragment 제외fragment 제외로 하여 실행한 결과로 둔다.

  3. serializedAserializedB와 같으면 true를, 아니면 false를 반환한다.

4.7. 오리진

오리진의 정의는 HTML에서 필수 배경 정보를 참고하세요. [HTML]

URL url오리진은 아래 단계들을 실행하여 얻어지는 오리진으로, url스킴에 따라 분기한다:

"blob"
  1. urlblob URL entry가 null이 아니면, urlblob URL entryenvironment오리진을 반환.

  2. pathURL파싱URL 경로 직렬화 url의 결과로 둔다.

  3. pathURL이 실패면 새 불투명 오리진을 반환한다.

  4. pathURLscheme이 "http", "https", 또는 "file"이면 pathURL오리진을 반환한다.

  5. 불투명 오리진을 반환한다.

blob:https://whatwg.org/d0360e2f-caee-469f-9a2f-87d5b0456f6f오리진튜플 오리진 ("https", "whatwg.org", null, null)이다.

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

튜플 오리진(urlscheme, urlhost, urlport, null)을 반환한다.

"file"

유감스럽게도, 이는 독자에게 맡깁니다. 확실하지 않을 때는 새 불투명 오리진을 반환하세요.

그 외

불투명 오리진을 반환한다.

실제로 이런 URL들은 자기 자신과도 동일 오리진이 될 수 없습니다.

4.8. URL 렌더링

URL은 아래에 설명된 수정과 함께 직렬화된 형태로 렌더링되어야 한다. 이는 URL을 표시하는 주요 목적이 사용자가 보안 또는 신뢰 결정을 내리게 하는 경우에 적용된다. 예를 들어, 사용자는 브라우저 주소창에 렌더링된 URL을 기반으로 신뢰 결정을 내릴 것으로 기대된다.

4.8.1. 사람이 읽기 어려운 또는 중요하지 않은 구성요소 단순화

스푸핑 기회를 제공하거나 보안 관련 정보를 방해할 수 있는 구성요소를 제거한다:

4.8.2. 생략(Elision)

공간이 제한된 표시에서는 사용자가 보안 결정을 내릴 때 오해하지 않도록 URL을 신중하게 생략해야 한다:

4.8.3. 국제화 및 특수 문자

국제화 도메인 이름(IDN), 특수 문자 및 양방향 텍스트는 스푸핑을 방지하기 위해 주의해서 처리해야 한다:

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을 받아 다음 단계를 실행한다:

  1. sequencesinput을 0x26(&)으로 분할한 결과로 둔다.

  2. output을 name과 value가 문자열을 담는 튜플로 구성된, 초기에는 빈 목록으로 둔다.

  3. 바이트 시퀀스 bytes에 대해 sequences에서:

    1. bytes가 빈 바이트 시퀀스이면 계속.

    2. bytes에 0x3D(=)가 있으면, namebytes의 처음부터 첫 번째 0x3D(=) 직전까지의 바이트로, value를 첫 번째 0x3D(=) 이후부터 끝까지의 바이트로 둔다. 0x3D(=)가 첫 번째 바이트면 name은 빈 바이트 시퀀스가 되고, 마지막이면 value는 빈 바이트 시퀀스가 된다.

    3. 그 외에는 namebytes 값으로, value를 빈 바이트 시퀀스로 둔다.

    4. namevalue의 모든 0x2B(+)를 0x20(SP)로 치환한다.

    5. nameStringvalueString을 각각 BOM 없는 UTF-8 디코드퍼센트 디코딩namevalue에 대해 실행한 결과로 둔다.

    6. append (nameString, valueString)를 output에 추가.

  4. output을 반환한다.

5.2. application/x-www-form-urlencoded 직렬화

application/x-www-form-urlencoded 직렬화기는 name-value 튜플 tuples 목록과 선택적 인코딩 encoding(기본 UTF-8)을 받아 다음 단계를 실행한다. 반환값은 ASCII 문자열이다.

  1. encodingoutput encoding을 얻기encoding에 대해 실행한 결과로 설정한다.

  2. output을 빈 문자열로 한다.

  3. tuple에 대해 tuples에서 반복한다:

    1. 단언: tuple의 name과 tuple의 value는 스칼라 값 문자열이다.

    2. name을 다음의 결과로 한다: percent-encode after encodingencoding, tuple의 name, 그리고 application/x-www-form-urlencoded percent-encode set으로 실행한 결과.

    3. value를 다음의 결과로 한다: percent-encode after encodingencoding, tuple의 value, 그리고 application/x-www-form-urlencoded percent-encode set으로 실행한 결과.

    4. output이 빈 문자열이 아니라면 U+0026 (&)를 output에 추가한다.

    5. name을 추가하고 U+003D (=)를 추가한 뒤 valueoutput에 추가한다.
  4. 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 객체에는 다음이 연관되어 있다:

API URL 파서스칼라 값 문자열 url과 선택적 null 또는 스칼라 값 문자열 base(기본값 null)을 받아 다음 단계를 실행한다:

  1. parsedBase를 null로 둔다.

  2. base가 null이 아니면:

    1. parsedBase기본 URL 파서base에 실행한 결과로 설정.

    2. parsedBase가 실패면 실패를 반환.

  3. 기본 URL 파서urlparsedBase와 함께 실행한 결과를 반환.

initializeURL 객체 urlURL urlRecord에 실행할 때:

  1. queryurlRecordquery 값(값이 null이 아니면 그 값, 아니면 빈 문자열)으로 둔다.

  2. urlURLurlRecord로 설정.

  3. urlquery 객체를 새 URLSearchParams 객체로 설정.

  4. 초기화urlquery 객체query에 실행.

  5. urlquery 객체URL 객체url로 설정.

URL 인터페이스를 구현하는 객체의 extract an origin 단계는 thisURLorigin을 반환하는 것이다. [HTML]


new URL(url, base) 생성자 단계는 다음과 같다:

  1. parsedURLAPI URL 파서urlbase(있으면)와 함께 실행한 결과로 둔다.

  2. parsedURL이 실패면 TypeError 예외를 던진다.

  3. initializethisparsedURL에 실행.

문자열을 URL파싱하려면 기준 URL 없이 URL 생성자에 인자를 하나만 넘겨서 호출한다:

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

입력이 상대-URL 문자열이면 예외가 발생한다:

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

이 경우에는 기준 URL이 필요하다:

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

URL 객체는 기준 URL로도 사용할 수 있다(IDL은 인자에 문자열을 요구하며, URL 객체는 href 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) 메서드 단계:

  1. parsedURLAPI URL 파서urlbase(있으면)와 함께 실행한 결과로 둔다.

  2. parsedURL이 실패면 null을 반환.

  3. url을 새 URL 객체로 둔다.

  4. initializeurlparsedURL에 실행.

  5. url을 반환.

정적 canParse(url, base) 메서드 단계:

  1. parsedURLAPI URL 파서urlbase가 있는 경우 실행한 결과를 할당합니다.

  2. parsedURL이 실패면 false를 반환합니다.

  3. true를 반환합니다.


href getter 단계와 toJSON() 메서드 단계는 시리얼라이즈thisURL을 반환하는 것입니다.

href setter 단계:

  1. parsedURLbasic URL 파서를 입력값에 실행한 결과를 할당합니다.

  2. parsedURL이 실패하면 throw TypeError.

  3. thisURLparsedURL을 설정합니다.

  4. thisquery objectlist를 비웁니다.

  5. querythisURLquery를 할당합니다.

  6. query가 null이 아니면 thisquery objectlist파싱 query 결과를 할당합니다.

origin getter 단계는 시리얼라이즈thisURLorigin을 반환합니다. [HTML]

protocol getter 단계는 thisURLscheme 다음에 U+003A (:)를 반환합니다.

protocol setter 단계는 basic URL 파싱을 입력값과 U+003A (:)가 뒤따르도록 한 후 thisURLurl로 하고 scheme start statestate override로 지정하여 실행합니다.

username getter 단계는 thisURLusername을 반환합니다.

username setter 단계:

  1. thisURLusername/password/port를 가질 수 없으면 return.

  2. set the usernamethisURL과 입력값으로 수행합니다.

password getter 단계는 thisURLpassword를 반환합니다.

password setter 단계:

  1. thisURLusername/password/port를 가질 수 없으면 return.

  2. set the passwordthisURL과 입력값으로 수행합니다.

host getter 단계:

  1. urlthisURL을 할당합니다.

  2. urlhost가 null이면 빈 문자열을 반환합니다.

  3. urlport가 null이면 urlhost시리얼라이즈해서 반환합니다.

  4. urlhost시리얼라이즈한 것 뒤에 U+003A (:)와 urlport시리얼라이즈해서 반환합니다.

host setter 단계:

  1. thisURLopaque path를 가지면 return.

  2. Basic URL 파서를 입력값에 thisURLurl로, host statestate override로 지정해 실행합니다.

만약 host setter에 주어진 값에 port가 없다면, thisURLport는 변경되지 않습니다. host getter는 URL-port string을 반환하므로, setter도 항상 둘 다 "리셋"된다고 기대할 수 있으나 그렇지 않을 수 있습니다.

hostname getter 단계:

  1. thisURLhost가 null이면 빈 문자열을 반환합니다.

  2. thisURLhost시리얼라이즈해서 반환합니다.

hostname setter 단계:

  1. thisURLopaque path를 가지면 return.

  2. Basic URL 파서를 입력값에 thisURLurl로, hostname statestate override로 지정해 실행합니다.

port getter 단계:

  1. thisURLport가 null이면 빈 문자열을 반환합니다.

  2. thisURLport시리얼라이즈해서 반환합니다.

port setter 단계:

  1. thisURLusername/password/port를 가질 수 없으면 return.

  2. 입력값이 빈 문자열이면 thisURLport를 null로 설정합니다.

  3. 그 밖의 경우, basic URL 파서를 입력값에 thisURLurl로, port statestate override로 지정해 실행합니다.

pathname getter 단계는 URL 경로 시리얼라이즈thisURL을 반환합니다.

pathname setter 단계:

  1. thisURLopaque path를 가지면 return.

  2. 비우기 thisURLpath.

  3. Basic URL 파서를 입력값에 thisURLurl로, path start statestate override로 지정해 실행합니다.

search getter 단계:

  1. thisURLquery가 null 혹은 빈 문자열이면 빈 문자열을 반환합니다.

  2. U+003F (?) 다음에 thisURLquery를 반환합니다.

search setter 단계:

  1. urlthisURL을 할당합니다.

  2. 입력값이 빈 문자열이면 urlquery를 null로, 비우기 thisquery objectlist를 비우고 return.

  3. input에 입력값에서 선행 U+003F (?) 1개를 제거한 값을 할당합니다.

  4. urlquery를 빈 문자열로 설정합니다.

  5. Basic URL 파서inputurlurl, query statestate override로 지정해 실행합니다.

  6. thisquery objectlist파싱 input 결과를 할당합니다.

searchParams getter 단계는 thisquery object를 반환합니다.

hash getter 단계:

  1. thisURLfragment가 null이거나 빈 문자열이면 빈 문자열을 반환합니다.

  2. U+0023 (#) 다음에 thisURLfragment를 반환합니다.

hash setter 단계:

  1. 입력값이 빈 문자열이면 thisURLfragment를 null로 설정하고 return.

  2. input에 입력값에서 선행 U+0023 (#) 1개를 제거한 값을 할당합니다.

  3. thisURLfragment를 빈 문자열로 설정합니다.

  4. Basic URL 파서inputthisURLurl로, fragment statestate 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 객체(예를 들면 hrefsearch) 와 다를 수 있다. 특히 searchParams 를 사용해 URLquery를 조작할 때 이런 차이로 인해 놀랄 수 있다.

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 사용), searchquery percent-encode set이나 special-query percent-encode set에 포함된 모든 것을 percent-encode한다(해당 URLspecial인지에 따라 다름).

URLSearchParams 객체에는 다음이 연관되어 있다:

initializeURLSearchParams 객체 queryinit으로 실행할 때:

  1. initsequence이면 innerSequence에 대해 init에서:

    1. innerSequence크기가 2가 아니면 TypeError 예외를 던진다.

    2. append (innerSequence[0], innerSequence[1])를 querylist에 추가한다.

  2. 그 외에 initrecord이면 namevalue에 대해 init에서, append (name, value)를 querylist에 추가한다.

  3. 그 외에는:

    1. Assert: init은 문자열이다.

    2. querylist파싱init에 실행한 결과로 설정한다.

updateURLSearchParams 객체 query에 실행할 때:

  1. queryURL 객체가 null이면 반환.

  2. serializedQuery직렬화querylist에 실행한 결과로 둔다.

  3. serializedQuery가 빈 문자열이면 serializedQuery를 null로 설정한다.

  4. queryURL 객체URLqueryserializedQuery로 설정한다.

new URLSearchParams(init) 생성자 단계는 다음과 같다:

  1. init이 문자열이고 앞에 U+003F(?)가 있으면 처음 코드 포인트를 제거한다.

  2. initializethisinit에 실행한다.

size getter 단계는 thislist크기를 반환한다.

append(name, value) 메서드 단계는 다음과 같다:

  1. append (name, value)를 thislist에 추가한다.

  2. updatethis에 실행한다.

delete(name, value) 메서드 단계는 다음과 같다:

  1. value가 주어지면 remove하여 tuples 중 name이 name이고 value가 value인 모든 항목을 thislist에서 삭제합니다.

  2. 그렇지 않으면 remove하여 tuples 중 name이 name인 모든 항목을 thislist에서 삭제합니다.

  3. Update하여 this를 갱신합니다.

get(name) 메서드 단계는 thislist에서 name이 name인 첫 번째 tuple의 value를 반환하며, 없다면 null을 반환합니다.

getAll(name) 메서드 단계는 thislist에서 name이 name인 모든 tuple의 value를 리스트 순서대로 반환하며, 없으면 빈 sequence를 반환합니다.

has(name, value) 메서드 단계:

  1. value가 주어지고, thislist에 name이 name이고 value가 valuetuple이 있으면 true를 반환합니다.

  2. value가 주어지지 않고, thislist에 name이 nametuple이 있으면 true를 반환합니다.

  3. false를 반환합니다.

set(name, value) 메서드 단계:

  1. thislist가 name이 nametuplescontains하면, 첫 번째 tuple의 value를 value로 설정하고, 나머지를 remove합니다.

  2. 그렇지 않으면 append (name, value)를 thislist에 추가합니다.

  3. Update해서 this를 갱신합니다.


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() 메서드 단계:

  1. thislist오름차순으로 정렬한 결과로 설정합니다. ab보다 작으려면 a의 name이 code unit less than b의 name이어야 합니다.

  2. Update해서 this를 갱신합니다.


반복에 사용할 value pairthislisttuples이며, key는 name이고 value는 value입니다.

문자열화 동작 단계는 시리얼라이징thislist를 반환합니다.

6.3. 다른 곳의 URL API

URL를 노출하는 표준은 내부 URL시리얼라이즈하여 문자열로 노출해야 합니다. 표준은 URL 객체로 URL을 노출해서는 안 됩니다. URL 객체는 URL 조작을 위해 사용되는 것입니다. IDL에서는 USVString 타입을 사용해야 합니다.

여기서 더 높은 수준의 개념은 값들이 불변 데이터 구조로 노출되어야 한다는 것이다.

표준이 자신이 정의하는 기능에 "URL"이라는 이름의 변형을 사용하기로 한다면, 해당 기능의 이름을 "url"(소문자, 끝에 "l" 포함)로 지어야 한다. "URL", "URI", "IRI"와 같은 이름은 사용하지 않아야 한다. 다만, 이름이 복합어일 경우 "URL"(대문자)이 선호된다. 예: "newURL", "oldURL".

HTMLEventSourceHashChangeEvent 인터페이스는 적절한 명명 예시이다. [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, annevk@annevk.nl)이 작성했습니다.

지적 재산권

Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). 이 저작물은 크리에이티브 커먼즈 저작자 표시 4.0 국제 라이선스에 따라 라이선스가 부여됩니다. 소스 코드에 포함된 부분에 대해서는, 해당 부분은 BSD 3-Clause 라이선스에 따라 소스 코드에 라이선스가 부여됩니다.

이 문서는 현행 표준(Living Standard)입니다. 특허 심사 버전에 관심이 있다면 현행 표준 심사 초안을 참고하십시오.

색인

이 규격에서 정의한 용어

참조로 정의된 용어

참고 문헌

규범적 참고 문헌

[BIDI]
Manish Goregaokar मनीष गोरेगांवकर; Robin Leroy. 유니코드 양방향 알고리즘. 2025년 8월 13일. 유니코드 표준 부록 #9. URL: https://www.unicode.org/reports/tr9/tr9-51.html
[ENCODING]
Anne van Kesteren. 인코딩 표준. 현행 표준. URL: https://encoding.spec.whatwg.org/
[FILEAPI]
Marijn Kruisselbrink. File API. URL: https://w3c.github.io/FileAPI/
[HTML]
Anne van Kesteren; 외. HTML 표준. 현행 표준. URL: https://html.spec.whatwg.org/multipage/
[IANA-URI-SCHEMES]
Uniform Resource Identifier (URI) Schemes. URL: https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 표준. 현행 표준. URL: https://infra.spec.whatwg.org/
[PSL]
퍼블릭 서픽스 리스트(Public Suffix List). URL: https://publicsuffix.org/
[RFC4291]
R. Hinden; S. Deering. IP 버전 6 주소 지정 아키텍처. 2006년 2월. 초안 표준. URL: https://www.rfc-editor.org/info/rfc4291/
[UTS46]
Mark Davis; Markus Scherer. 유니코드 IDNA 호환성 처리(Unicode IDNA Compatibility Processing). 2025년 9월 4일. 유니코드 기술 표준 #46. URL: https://www.unicode.org/reports/tr46/tr46-35.html
[WEBIDL]
Edgar Chen; Timothy Gu. 웹 IDL 표준(Web IDL Standard). Living Standard. URL: https://webidl.spec.whatwg.org/

설명적 참고 문헌

[ECMA-262]
ECMAScript 언어 명세. URL: https://tc39.es/ecma262/multipage/
[IDNFAQ]
국제화 도메인 이름(IDN) FAQ. URL: https://unicode.org/faq/idn.html
[RFC1034]
P. Mockapetris. 도메인 이름 - 개념 및 기능. 1987년 11월. 인터넷 표준. URL: https://www.rfc-editor.org/info/rfc1034/
[RFC3986]
T. Berners-Lee; R. Fielding; L. Masinter. Uniform Resource Identifier(URI): 일반 구문. 2005년 1월. 인터넷 표준. URL: https://www.rfc-editor.org/info/rfc3986/
[RFC3987]
M. Duerst; M. Suignard. 국제화 리소스 식별자(IRI). 2005년 1월. 제안 표준. URL: https://www.rfc-editor.org/info/rfc3987/
[RFC5890]
J. Klensin. 애플리케이션을 위한 국제화 도메인 이름 (IDNA): 정의 및 문서 프레임워크. 2010년 8월. 제안 표준. URL: https://www.rfc-editor.org/info/rfc5890/
[RFC5952]
S. Kawamura; M. Kawashima. IPv6 주소 텍스트 표현에 대한 권고. 2010년 8월. 제안 표준. URL: https://www.rfc-editor.org/info/rfc5952/
[RFC6454]
A. Barth. 웹 출처 개념. 2011년 12월. 제안 표준. URL: https://www.rfc-editor.org/info/rfc6454/
[RFC7595]
D. Thaler, Ed.; T. Hansen; T. Hardie. URI 스킴에 대한 지침 및 등록 절차. 2015년 6월. 모범 현행 관행. URL: https://www.rfc-editor.org/info/rfc7595/
[RFC791]
J. Postel. 인터넷 프로토콜. 1981년 9월. 인터넷 표준. URL: https://www.rfc-editor.org/info/rfc791/
[UTR36]
Mark Davis; Michel Suignard. Unicode 보안 고려사항. 2014년 9월 19일. Unicode 기술 보고서 #36. URL: https://www.unicode.org/reports/tr36/tr36-15.html
[UTS39]
Mark Davis; Michel Suignard. Unicode 보안 메커니즘. 2025년 9월 4일. Unicode 기술 표준 #39. URL: https://www.unicode.org/reports/tr39/tr39-32.html

IDL 색인

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

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

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

  USVString toJSON();
};

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

  readonly attribute unsigned long size;

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

  undefined sort();

  iterable<USVString, USVString>;
  stringifier;
};

MDN

URL/URL

In all current engines.

Firefox26+Safari14.1+Chrome19+
Opera?Edge79+
Edge (Legacy)12+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js10.0.0+
MDN

URL/canParse_static

Firefox115+Safari17+ChromeNone
Opera?EdgeNone
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js20.0.0+
MDN

URL/hash

In all current engines.

Firefox22+Safari7+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
MDN

URL/host

In all current engines.

Firefox22+Safari7+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
MDN

URL/hostname

In all current engines.

Firefox22+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
MDN

URL/href

In all current engines.

Firefox22+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
MDN

URL/origin

In all current engines.

Firefox26+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)12+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet6.0+Opera Mobile?
Node.js7.0.0+
MDN

URL/password

In all current engines.

Firefox26+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)12+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet6.0+Opera Mobile?
Node.js7.0.0+
MDN

URL/pathname

In all current engines.

Firefox22+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
MDN

URL/port

In all current engines.

Firefox22+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
MDN

URL/protocol

In all current engines.

Firefox22+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
MDN

URL/search

In all current engines.

Firefox22+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)13+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.0.0+
MDN

URL/searchParams

In all current engines.

Firefox29+Safari10.1+Chrome51+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
MDN

URL/toJSON

In all current engines.

Firefox54+Safari11+Chrome71+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.7.0+
MDN

URL/toString

In all current engines.

Firefox54+Safari7+Chrome19+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet6.0+Opera Mobile?
Node.js7.0.0+
MDN

URL/username

In all current engines.

Firefox26+Safari10+Chrome32+
Opera?Edge79+
Edge (Legacy)12+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet6.0+Opera Mobile?
Node.js7.0.0+
MDN

URL

In all current engines.

Firefox19+Safari7+Chrome32+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView4.4+Samsung Internet?Opera Mobile?
Node.js10.0.0+
MDN

URLSearchParams/URLSearchParams

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+

URLSearchParams/entries

In all current engines.

Firefox44+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+

URLSearchParams/forEach

In all current engines.

Firefox44+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+

URLSearchParams/keys

In all current engines.

Firefox44+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+

URLSearchParams/values

In all current engines.

Firefox44+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
MDN

URLSearchParams/append

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
MDN

URLSearchParams/delete

In all current engines.

Firefox29+Safari14+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
MDN

URLSearchParams/get

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
MDN

URLSearchParams/getAll

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
MDN

URLSearchParams/has

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
MDN

URLSearchParams/set

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
MDN

URLSearchParams/size

In all current engines.

Firefox112+Safari17+Chrome113+
Opera?Edge113+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js19.0.0+
MDN

URLSearchParams/sort

In all current engines.

Firefox54+Safari11+Chrome61+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.7.0+
MDN

URLSearchParams/toString

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js7.5.0+
MDN

URLSearchParams

In all current engines.

Firefox29+Safari10.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js10.0.0+