Title: URL Standard
Group: WebSpecs
H1: URL
Shortname: url
Status: LS
No Editor: true
Abstract: The URL Standard defines URLs, domains, IP addresses, the application/x-www-form-urlencoded
format, and their APIs.
Indent: 2
The URL standard takes the following approach towards making URLs fully interoperable:
Align RFC 3986 and RFC 3987 with contemporary implementations and obsolete them in the process. (E.g. spaces, other "illegal" code points, query encoding, equality, canonicalization, are all concepts not entirely shared, or defined.) URL parsing needs to become as solid as HTML parsing. [[RFC3986]] [[RFC3987]]
Standardize on the term URL. URI and IRI are just confusing. In practice a single algorithm is used for both so keeping them distinct is not helping anyone. URL also easily wins the search result popularity contest.
Supplanting Origin of a URI [sic]. [[RFC6454]]
Define URL's existing JavaScript API in full detail and add
enhancements to make it easier to work with. Add a new URL
object as well for URL manipulation without usage of HTML elements. (Useful
for JavaScript worker environments.)
As the editors learn more about the subject matter the goals might increase in scope somewhat.
A URL is a universal identifier.
A URL consists of components, namely a scheme, scheme data, username, password, host, port, path, query, and fragment.
http://username:password@example.com:8000/path?query#fragment
contains values for all URL components except
scheme data.
javascript:doSomething()
contains values for only
scheme and
scheme data.
A URL's scheme is a string that identifies the type of URL and can be used to dispatch a URL for further processing after parsing. It is initially null.
A URL's scheme data is a string holding the contents of a URL. It is initially null.
A URL's scheme data will be null if its initial scheme is a relative scheme, and otherwise will be the only component other than scheme that differs from its initial value.
A URL's username is a string identifying a user. It is initially the empty string.
A URL's password is either null or a string identifying a user's credentials. It is initially null.
A URL's host is either null or a host. It is initially null.
A URL's port is a string that identifies a networking port. It is initially the empty string.
A URL's path is a list of zero or more strings holding data, usually identifying a location in hierarchical form. It is initially the empty list.
A URL's query is either null or a string holding data. It is initially null.
A URL's fragment is either null or a string holding data that can be used for further processing on the resource the URL's other components identify. It is initially null.
A URL also has an associated
object that is either null or a
Blob
. It is initially null.
[[!FILEAPI]]
At this point this is used primarily to support "blob
"
URLs, but others can be added going forward, hence "object".
A relative scheme is a scheme listed in the first column of the following table. A default port is a relative scheme's optional corresponding port and is listed in the second column on the same row.
scheme | port |
---|---|
"ftp " | "21 "
|
"file " | |
"gopher " | "70 "
|
"http " | "80 "
|
"https " | "443 "
|
"ws " | "80 "
|
"wss " | "443 "
|
A URL includes credentials if either its username is not the empty string or its password is non-null.
A URL can be designated as base URL.
A base URL is useful for the URL parser when the input is potentially a relative URL.
A URL must be written as either a
relative URL or an
absolute URL, optionally followed by
"#
" and a
fragment.
An absolute URL must be a
scheme, followed by
":
", followed by either a
scheme-relative URL, if
scheme is a relative scheme, or
scheme data otherwise, optionally followed
by "?
" and a query.
A scheme must be one
ASCII alpha, followed by zero or more of
ASCII alphanumeric, "+
",
"-
", and ".
". A
scheme must be registered
....
The syntax of scheme data
depends on the scheme and is typically
defined alongside it. Standards must define
scheme data within the constraints of zero or
more URL units, excluding "?
".
A relative URL must be either a
scheme-relative URL, an
absolute-path-relative URL,
or a path-relative URL that
does not start with a scheme and
":
", optionally followed by a "?
" and
a query.
At the point where a relative URL is parsed, a base URL must be in scope.
A scheme-relative URL must be
"//
", optionally followed by
userinfo and "@
",
followed by a host, optionally followed
by ":
" and a port,
optionally followed by an
absolute-path-relative URL.
Userinfo must be a
username, optionally followed by a
":
" and a
password.
A username must be zero or more
URL units, excluding "/
",
":
, "?
", and "@
".
A password must be zero or more
URL units, excluding "/
",
"?
", and "@
".
A host must be either a domain,
or an IPv4 address,
or "[
" followed
by an IPv6 address followed by
"]
".
A domain must be a string that is a valid domain.
Textual representation of IPv4 address does not appear to be defined by an RFC. See Textual Representation of IPv4 and IPv6 Addresses for some history.
An IPv6 address is defined in the "Text Representation of Addresses" chapter of IP Version 6 Addressing Architecture. [[!RFC4291]]
A port must be zero or more ASCII digits.
An
absolute-path-relative URL
must be "/
", followed by a
path-relative URL that does not
start with "/
".
A path-relative URL must be zero or
more path segments separated from each
other by a "/
".
A path segment must be zero or more URL units,
excluding "/
" and "?
".
A query must be zero or more URL units.
A fragment must be zero or more URL units.
The URL code points are ASCII alphanumeric,
"!
",
"$
",
"&
",
"'
",
"(
",
")
",
"*
",
"+
",
",
",
"-
",
".
",
"/
",
":
",
";
",
"=
",
"?
",
"@
",
"_
",
"~
",
and code points in the ranges
U+00A0 to U+D7FF,
U+E000 to U+FDCF,
U+FDF0 to U+FFFD,
U+10000 to U+1FFFD,
U+20000 to U+2FFFD,
U+30000 to U+3FFFD,
U+40000 to U+4FFFD,
U+50000 to U+5FFFD,
U+60000 to U+6FFFD,
U+70000 to U+7FFFD,
U+80000 to U+8FFFD,
U+90000 to U+9FFFD,
U+A0000 to U+AFFFD,
U+B0000 to U+BFFFD,
U+C0000 to U+CFFFD,
U+D0000 to U+DFFFD,
U+E0000 to U+EFFFD,
U+F0000 to U+FFFFD,
U+100000 to U+10FFFD.
Code points higher than U+009F will be converted to percent-encoded bytes by the URL parser, except for code points appearing in fragments.
The URL units are URL code points and percent-encoded bytes.
The URL parser takes a string input, optionally with a base URL base, and optionally with an encoding encoding override, and then runs these steps:
Let url be the result of running the basic URL parser on input with base, and encoding override as provided.
If url is failure, return failure.
If url's scheme is not
"blob
", return url.
If url's scheme data is not in the blob URL store, return url. [[!FILEAPI]]
Set url's object to a structured clone of the entry in the blob URL store corresponding to url's scheme data. [[!HTML]]
Return url.
The basic URL parser takes a string input, optionally with a base URL base, optionally with an encoding encoding override, optionally with an URL url and a state override state override, and then runs these steps:
The encoding override argument is a legacy concept only relevant for
HTML. The url and state override arguments are only for
use by methods of objects implementing the URLUtils
interface.
[[!HTML]]
When the url and state override arguments are not passed the basic URL parser returns either a URL or failure. If they are passed the algorithm simply modifies the passed url and can terminate without returning anything.
If url is not given:
Set url to a new URL.
Remove any leading and trailing ASCII whitespace from input.
If base is not given, set it a new URL with
scheme
set to about
.
If encoding override is not given, set it to utf-8.
url
on the input passing url, base and
encoding override.
Return url.
x
is present" is
to be interpreted to mean "the grammar rule for
x
matches some part of the
input
when that input
is parsed according to
the given railroad diagram". Note that if the railroad diagram contains
alternatives where multiple alternatives could potentially match the
input, only the first matching input is considered to be present.
* The phrase "value of
x
" is to be
interpreted to mean "the value returned by the function
x(input)
when the function x
is passed some
part of the original input
during the parsing of that
original input
according to the given railroad diagram".
Note: extracting the railroad diagrams from this specification and
interpreting them in isolation will produce incorrect results. In particular,
the definitions provided in the prose modifies these parsing algorithms in
important ways including returning failure and early termination.
Sequence: Choice: N: file-url N: non-relative-url N: relative-url Optional: Sequence: T: ? N: query Optional: Sequence: T: # N: fragment
input
according to the above railroad diagram.
result
be the value of file-url
, non-relative-url
,
or relative-url
depending on which is present.
query
is present, set result.query
to the value of
query
.
fragment
is present, set result.fragment
to the
value of fragment
.
result.scheme
has a default port, and if result.port
is
equal to that default, then delete the port
property from result
.
result
.
Choice: Sequence: T: file T: : T: any of [a-zA-Z] Choice: T: : T: | Optional: Choice: T: \ T: / N: path Sequence: ZeroOrMore: T: / T: any of [a-zA-Z] T: | Optional: T: / N: path Sequence: T: file T: : Optional: Sequence: T: / T: / N: host ZeroOrMore: T: / N: path"
file
" is to be matched case insensitively.
input
according to the above railroad diagram.
result
be an empty object.
file:c:\foo\bar.html
result.scheme
to "file
".
result.path
to the value of path
.
result.path
if it is an empty
string and if there is a second element which has a non-empty value.
:
" in the input
concatenated with a ":
". Prepend this string to
result.path
.
/C|\foo\bar
result.scheme
to "file
".
host
is present, set result.host
to the value of host
.
host
is not present and no slashes
precede the path
in the input, then prepend base.path
minus the last element to the result.path
.
result.path
to the value of path
.
file:/example.com/
result.scheme
to "file
".
result.path
to the value of path
.
result.path
if it is an empty
string and if there is a second element which has a non-empty value.
/
" (if any) in the production rule concatenated
with a ":
". Prepend this string to the result.path
array.
result
.
At the present time, file URLs are generally not
interoperable, and therefore are effectively implementation defined.
Furthermore, the parsing rules in this section have not enjoyed wide review,
and therefore are more likely to be subject to change than other parts of this
specification.
bug 27518
proposes to remove all normative definitions for file URLs that are not
known to be interoperable.
Bug 23550
and
bug 23717
suggest less drastic changes.
Sequence: N: scheme T: : N: scheme-data
javascript:alert("Hello, world!");
input
according to the above railroad diagram.
scheme
does not
match any relative scheme then return failure.
encoding override
to "utf-8
".
result
to be a JSON object with scheme
set to be the result returned by scheme
, and
schemeData
set to the value of scheme-data
.
result
.
The resolution of
bug 26338
may change how encoding override is handled.
The resolution of
bug 27233
may add support for relative URLs for unknown schemes.
Choice: Sequence: Optional: Sequence: N: non-file-relative-scheme T: : Choice: T: / T: \ Choice: T: / T: \ N: authority Optional: Sequence: Choice: T: / T: \ N: path Sequence: N: non-file-relative-scheme T: : Optional: Choice: T: \ T: / N: authority Optional: Sequence: Choice: T: / T: \ N: path Sequence: N: non-file-relative-scheme T: : N: path N: path
input
according to the above railroad diagram.
http://user:pass@example.org:21
/foo/bar
//
")
immediately follows the first colon in the input, indicate a
conformance error.
result
be the value of authority
.
non-file-relative-scheme
is present in the input, then
set result.scheme
to the value of non-file-relative-scheme
.
non-file-relative-scheme
is not present,
then set result.scheme
to the value of base.scheme
.
path
is present, set result.path
to the value of
path
.
ftp:/example.com/
parsed using a base of
http://example.org/foo/bar
scheme
equals base.scheme
then return failure.
result
be the value of authority
.
result.scheme
to the value of non-file-relative-scheme
.
result.host
is either an empty string or contains a
colon, then terminate parsing with a parse exception.
path
is present, set result.path
to the value of
path
.
http:foo/bar
result
be an empty object.
result.scheme
to the value of non-file-relative-scheme
.
result.scheme
to the value of scheme
.
result.host
to base.host
.
result.path
by the path concatenation of
base.path
and path
.
/foo/bar
result
be an empty object.
result.scheme
to base.scheme
.
result.host
to base.host
.
result.path
to path
result.path
with the path concatenation of base.path
and result.Path
.
result
.
Choice: T: ftp T: gopher T: https T: http T: wss T: wsSchemes are to be matched against the input in a case insensitive manner.
input
according to the above railroad diagram.
encoding override
to "utf-8
" if the scheme matches
"wss
" or "ws
".
The resolution of
bug 26338
may change how encoding override is handled.
Sequence: T: any of [a-zA-Z] ZeroOrMore: T: any of [-a-zA-Z+.]A scheme consists of an ASCII alpha, followed by zero or more ASCII alpha or any of the following code points: hyphen-minus (
U+002D
), plus sign (U+002B
) or full stop
(U+002D
).
Return the results as a lowercased string.
Sequence: Optional: Sequence: N: user Optional: Sequence: T: : N: password T: @ N: host Optional: Sequence: T: : N: port
input
according to the above railroad diagram.
result
be an empty object.
user
is present, set result.username
to the value of
user
.
password
is present, set result.password
to the
value of password
.
result.host
to the value of host
up to the first "@
" sign,
if any. If no "@
" signs are present in the value of host
, then
set result.host
to the value of host
.
@
" signs are present in the value of host
,
then perform the following steps:
info
to the value of "%40
" plus the remainder of the
host
after the first "@
" sign. Replace all remaining "@
" signs in
info
, with the string "%40
".
password
is present, append info
to result.password
.
password
is not present and user
is present, append info
to result.username
.
user
is not present, set
result.username
to info
.
port
is present, set result.port
to its value.
result
.
ZeroOrMore: T: any except [/\?#@:]Consume all code points until either a solidus (
U+002F
),
a reverse solidus (U+005C
),
a question mark (U+003F
),
a number sign (U+0023
),
a commercial at (U+0040
),
a colon (U+003A
),
or the end of string is encountered.
Return the cleansed result using the
default encode set.
ZeroOrMore: T: any except [/\?#@]Consume all code points until either a solidus (
U+002F
),
a reverse solidus (U+005C
),
a question mark (U+003F
),
a number sign (U+0023
),
a commercial at (U+0040
),
or the end of string is encountered.
Return the cleansed result using the
default encode set.
Choice: Sequence: N: ipv6addr Sequence: N: ipv4addr ZeroOrMore: T: any except [:/\?#]
input
according to the above railroad diagram.
ipv6addr
is present, return the value of ipv6addr
.
ipv4addr
is present, return the value of ipv4addr
.
result
be the characters matched by the railroad diagram.
U+0009
, U+000A
, U+000D
, U+200B
, U+2060
, or U+FEFF
code points are
present in result
, remove those code points and indicate a
conformance error.
domain
be the result of
host parsing result
. If this results
in a failure, terminate processing with a parse exception. If host parsing returned a value that was
different than what was provided as input, indicate a conformance
error.
domain
as an ipv4addr
. If this succeeds, replace domain
with the result.
domain
as follows:
U+002E
(full stop) code points
domain
.
The resolution of
bug 25334
may change what codepoints are allowed in a domain.
The resolution of
bug 27266
may change the way domain names and trailing dots are handled.
Sequence: T: [ Sequence: Optional: Sequence: ZeroOrMore: Sequence: N: h16 T: : T: : ZeroOrMore: Sequence: N: h16 T: : Choice: N: h16 N: ls32 T: ]
pre
be the set of h16
values before the double colon, if present.
post
be the remaining h16
value before the last value
last
be the trailing h16
or ls32
value.
h16
values and one ls32
value.
h16
or ls32
) is more than six.
ls32
value present, indicate a parse exception
and terminate processing if consecutive colon code points are present in
the input or if there are more than one ls32
value after the
consecutive colons.
0
" values to pre
while the sum of the lengths of the pre
and
post
arrays is less than six.
0
" value to pre
if no ls32
item is present in the input and
the sum of the lengths of the pre
and post
array is seven.
last
to pre
.
pre
as a string, plus ']'.
The resolution of
bug 27234
may add support for link-local addresses.
Sequence: Optional: Sequence: N: number T: . Optional: Sequence: N: number T: . Optional: Sequence: N: number T: . N: number
number
is greater or equal to 256
, terminate
processing with a parse exception.
number
is greater than or equal to 256
to the power of (5
minus the number of number
s present in the input), terminate processing
with a parse exception.
number
s are present, indicate a
conformance error.
n
be the last number
.
number
is present, add it's
value times 256
**3
to n
.
number
is present, add it's
value times 256
**2
to n
.
number
is present, add it's value times 256
to n
.
result
be an empty array.
n
modulo 256
to result
.
n
to the value of the integer quotient of n
divided by 256
.
result
with a Full Stop (U+002E
) code point, and
return the results as a string.
The resolution of
bug 26431
may change this definition.
Choice: Sequence: T: 0 Choice: T: x T: X OneOrMore: T: any of [0-9a-fA-F] Sequence: T: 0 OneOrMore: T: any of [0-7] OneOrMore: T: any of [0-9]Three production rules, with uppercase and lowercase variants, are defined for numbers. Parse the values as hexadecimal, octal, and decimal integers respectively. Indicate a conformance error if the value is hexadecimal or octal. Return the result as an integer.
Sequence: T: any of [0-9A-Fa-f] Optional: T: any of [0-9A-Fa-f] Optional: T: any of [0-9A-Fa-f] Optional: T: any of [0-9A-Fa-f]Return up to four ASCII hex digits as a string.
Sequence: N: decimal-byte T: . N: decimal-byte T: . N: decimal-byte T: . N: decimal-byteReturn four decimal
8
-bit pieces separated by full
stop code points as a string.
Sequence: Optional: T: any of [0-2] Optional: T: any of [0-9] T: any of [0-9]Decimal bytes are a string of up to three decimal digits. If the results converted to an integer are greater than
255
, terminate processing with
a parse exception.
ZeroOrMore: T: any except [/\?#]
U+002F
),
a reverse solidus (U+005C
),
a question mark (U+003F
),
or the end of string is encountered.
result
be the cleansed set of code points using
null as the encode set.
U+0030
code points from result
until either the leading
code point is not U+0030
or result
consists of exactly one code point.
result
are not ASCII digits:
input
was not set, terminate processing with a
parse exception.
result
starting with the first non-digit code point.
The resolution of
bug 26446
may change port from a string to a number.
Sequence: ZeroOrMore: Sequence: ZeroOrMore: T: any except [/\?#] Choice: T: / T: \ ZeroOrMore: T: any except [/\?#]
\
"), indicate
a conformance error.
.
" or "%2e
" (case insensitive),
then process this name based on the position in the array:
1
, replace the entry with an empty string.
..
", ".%2e
", "%2e.
",
or "%2e%2e
" (all to be compared in a case insensitive manner),
then process this name based on the position in the array:
The resolution of
bug 24163
may change what code points to escape in the path.
ZeroOrMore: T: any except [?#]Consume all code points until either a question mark (
U+003F
), a
number sign (U+0023
), or the end of string is encountered.
Return the cleansed result using null as
the encode set.
The resolution of
bug 24246
may change what code points to escape in the scheme data.
ZeroOrMore: T: any except [#]Consume all code points until either a number sign (
U+0023
) or the end of string is encountered.
Return the cleansed result using the
the result using the query encode set.
The resolution of
bug 27280
may change how code points < 0x20
are handled.
ZeroOrMore: T: any
result
be the remaining code points in the input.
U+0000
characters are present in result
, remove those
characters from result
and indicate a
conformance error.
result
are neither a Percent Sign (U+0025
) nor
a URL code point, indicate a
conformance error.
Unfortunately not using percent-encoding is intentional as implementations with majority market share exhibit this behavior.
The resolution of
bug 26988
may add support for parsing URLs without decoding the fragment identifier.
Setter Rules {#setter-rules}
---
URLUtils and
URLUtilsReadOnly members invoke the following setter
rules with url
set to a non-null
value.
Sequence: N: scheme Optional: T: : ZeroOrMore: T: anySet
url.scheme
to value returned by scheme
.
ZeroOrMore: T: anyIf
url.scheme_data
is not null, return.
Set url.username
to the
percent encoded
value using the
username encode set.
ZeroOrMore: T: anyIf
url.scheme_data
is not null, return.
Set url.password
to the
percent encoded value
using the
password encode set.
Sequence: N: host Optional: Sequence: T: : N: port Optional: Sequence: Optional: T: any of [/\?#] ZeroOrMore: T: anyIf
url.scheme_data
is not null, return.
Set url.host
to the value returned by host
.
If port
is present, set result.port
to its value.
Sequence: N: host Optional: T: any of [:/\?#] ZeroOrMore: T: anyIf
url.scheme_data
is not null, return.
Set url.host
to the value returned by host
.
Sequence: N: port Optional: T: any of [/\?#] ZeroOrMore: T: anyIf
url.scheme_data
is not null or url.scheme
is "file
", return.
If url.scheme
has a default port, and if port
is equal to that
default, then set the port
property of url
to the empty string.
Otherwise, set url.port
to the value returned by port
.
Sequence: Optional: Choice: T: / T: \ N: path Optional: T: any of [/\?#] ZeroOrMore: T: anyIf
url.scheme_data
is not null, return.
Set url.path
to the value returned by path
.
Sequence: Optional: T: ? ZeroOrMore: T: anySet
url.query
to the
percent encoded value
after the initial question mark (U+003F
), if any, using the query encode
set.
Sequence: Optional: T: # ZeroOrMore: T: anySet
url.fragment
to the
percent encoded value
after the initial number sign (U+0023
), if any, using the
simple encode set
Common Functions {#common-functions}
---
To percent encode a byte into a
percent-encoded byte, return a string consisting of
"%
", followed by a double-digit, uppercase, hexadecimal
representation of byte.
To percent decode a byte sequence input, run these steps:
Using anything but a utf-8 decoder when the input contains bytes outside the range 0x00 to 0x7F might be insecure and is not recommended.
Let output be an empty byte sequence.
For each byte byte in input, run these steps:
If byte is not `%
`, append
byte to output.
Otherwise, if byte is `%
` and the next two
bytes after byte in input are not in the ranges
0x30 to 0x39, 0x41 to 0x46, and 0x61 to 0x66, append byte to
output.
Otherwise, run these substeps:
Let bytePoint be the two bytes after byte in input, decoded, and then interpreted as hexadecimal number.
Append a byte whose value is bytePoint to output.
Skip the next two bytes in input.
Return output.
To utf-8 percent encode a code point, using an encode set, run these steps:
If code point is not in encode set, return code point.
Let bytes be the result of running utf-8 encode on code point.
Percent encode each byte in bytes, and then return them concatenated, in the same order.
The domain to ASCII function given a domain domain, runs these steps:
Let result be the result of running Unicode ToASCII with domain_name set to domain, UseSTD3ASCIIRules set to false, processing_option set to Transitional_Processing, and VerifyDnsLength set to false.
If result is a failure value, return failure.
Return result.
The domain to Unicode function given a domain domain, runs these steps:
Let result be the result of running Unicode ToUnicode with domain_name set to domain, UseSTD3ASCIIRules set to false.
Return result, ignoring any returned errors.
User agents are encouraged to report errors through a developer console.
A domain is a valid domain if these steps return success:
Let result be the result of running Unicode ToASCII with domain_name set to domain, UseSTD3ASCIIRules set to true, processing_option set to Nontransitional_Processing, and VerifyDnsLength set to true.
If result is a failure value, return failure.
Set result to the result of running Unicode ToUnicode with domain_name set to result, UseSTD3ASCIIRules set to true.
If result contains any errors, return failure.
Return success.
Ideally we define this in terms of a sequence of code points that make up a valid domain rather than through a whack-a-mole: bug 25334.
The host parser takes a string input and then runs these steps:
If input is the empty string, return failure.
Let domain be the result of utf-8 decode without BOM on the percent decoding of utf-8 encode on input.
Let asciiDomain be the result of running domain to ASCII on domain.
If asciiDomain is failure, return failure.
If asciiDomain contains one of
U+0000,
U+0009,
U+000A,
U+000D,
U+0020,
"#
",
"%
",
"/
",
":
",
"?
",
"@
",
"[
",
"\
",
and
"]
",
return failure.
Return asciiDomain.
U+0025
), indicate a conformance
error.
U+0025
) that is not
immediately followed by two hexadecimal characters, indicate a
conformance error.
U+0009
, U+000A
or U+000D
characters are present in the string, remove those characters and indicate
a conformance error.
encoding override
, then
percent encode
that result using the provided encode set.
The URL serializer takes a URL url, optionally an exclude fragment flag, and then runs these steps:
Let output be url's
scheme and
":
" concatenated.
If url's scheme data is unset:
Append "//
" to output.
If url's username is not the empty string or url's password is non-null, run these substeps:
Append url's host, serialized, to output.
If url's port
is not the empty string, append ":
" concatenated with
url's port to
output.
Append "/
" concatenated with the strings in
url's path
(including empty strings), separated from each other by
"/
" to output.
Otherwise, append url's scheme data to output.
If url's query is non-null,
append "?
" concatenated with url's
query to output.
If the exclude fragment flag is unset and
url's fragment is
non-null, append "#
" concatenated with
url's fragment to
output.
Return output.
The host serializer takes null or a host host and then runs these steps:
If host is null, return the empty string.
If host is an
IPv6 address, return
"[
", followed by the result of running the
IPv6 serializer on host,
followed by "]
".
Otherwise, host is a domain or an IPv4 address, return host.
The IPv6 serializer takes an IPv6 address address and then runs these steps:
Let output be the empty string.
Let compress pointer be a pointer to the first 16-bit piece in the first longest sequences of address's 16-bit pieces that are 0.
In 0:f:0:0:f:f:0:0
it would point to
the second 0.
If there is no sequence of address's 16-bit pieces that are 0 longer than one, set compress pointer to null.
For each piece in address's pieces, run these substeps:
If compress pointer points to
piece, append "::
" to
output if piece is
address's first piece and append
":
" otherwise, and then run these substeps again with all
subsequent pieces in
address's pieces
that are 0 skipped or go the next step in the overall set of steps if
that leaves no pieces.
Append piece, represented as the shortest possible lowercase hexadecimal number, to output.
If piece is not
address's last piece,
append ":
" to output.
Return output.
This algorithm requires the recommendation from A Recommendation for IPv6 Address Text Representation. [[RFC5952]]
See origin's definition in HTML for the necessary background information. [[!HTML]]
A URL's origin is the origin returned by running these steps, switching on URL's scheme:
blob
"
Let url be the result of parsing URL's scheme data.
If url is failure, return a new globally unique identifier. Otherwise, return url's origin.
The origin of
blob:https://whatwg.org/d0360e2f-caee-469f-9a2f-87d5b0456f6f
is
the tuple
(https
, whatwg.org
, 443
).
ftp
"
gopher
"
http
"
https
"
ws
"
wss
"
Return a tuple consisting of URL's scheme, its host, and its default port if its port is the empty string, and its port otherwise.
file
"
Unfortunate as it is, this is left as an exercise to the reader. When in doubt, return a new globally unique identifier.
Return a new globally unique identifier.
[Constructor(USVString url, optional USVString base = "about:blank"), Exposed=(Window,Worker)] interface URL { static USVString domainToASCII(USVString domain); static USVString domainToUnicode(USVString domain); }; URL implements URLUtils; [NoInterfaceObject, Exposed=(Window,Worker)] interface URLUtils { 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; attribute URLSearchParams searchParams; attribute USVString hash; }; [NoInterfaceObject, Exposed=(Window,Worker)] interface URLUtilsReadOnly { stringifier readonly attribute USVString href; readonly attribute USVString origin; readonly attribute USVString protocol; readonly attribute USVString host; readonly attribute USVString hostname; readonly attribute USVString port; readonly attribute USVString pathname; readonly attribute USVString search; readonly attribute USVString hash; };
Except where different objects implementing URLUtilsReadOnly
are identical
to objects implementing URLUtils
.
Since all members are readonly and certain members from
URLUtils
are not exposed a number of potential optimizations is possible
compared to objects implementing URLUtils
. These are left as an exercise to
the reader.
Specifications defining objects implementing URLUtils
or
URLUtilsReadOnly
must define a
get the base algorithm, which must return the
appropriate base URL for the object.
Specifications defining objects implementing URLUtils
may
define update steps to make it possible for an
underlying string (such as an
attribute value)
to be updated. The update steps are passed a string
value for this purpose.
An object implementing URLUtils
or URLUtilsReadOnly
has an
associated input (a string),
query encoding
(an encoding),
query object
(a URLSearchParams
object or null), and a
url (a URL or null).
Unless stated otherwise, query encoding is
utf-8 and
query object is null. The others follow
from the set the input algorithm.
The associated query encoding is a legacy concept only relevant for HTML. [[!HTML]]
Specifications defining objects implementing URLUtils
or
URLUtilsReadOnly
must use the
set the input algorithms to set
input, url, and
query object. To
set the input given input
and optionally a url, run these steps:
Otherwise, run these substeps:
Set url to null.
If input is null, set input to the empty string.
Otherwise, run these subsubsteps:
Set input to input.
Let url be the result of running the URL parser on input with base URL being the result of running get the base and query encoding as encoding override.
If url is not failure, set url to url.
Let query be url's query if url is non-null, and the empty string otherwise.
If query object is null, set
query object to a
new URLSearchParams
object
using query, and then append the
context object to
query object's list of
url objects.
Otherwise, set query object's list to the result of parsing query.
To run the pre-update steps for an object implementing
URLUtils
, optionally given a value, run these steps:
If value is not given, let value be the result of serializing the associated url.
Run the update steps with value.
The
URL(url, base)
constructor, when invoked, must run these steps:
Let parsedBase be the result of running the basic URL parser on base.
If parsedBase is failure,
throw a TypeError
exception.
Set parsedURL to the result of running the basic URL parser on url with parsedBase.
If parsedURL is failure,
throw a TypeError
exception.
Let result be a new URL
object.
Let result's get the base return parsedBase.
Run result's set the input given the empty string and parsedURL.
Return result.
To Basic URL parse a string into a URL without using a base URL, invoke the constructor with a single argument:
var input = "https://example.org/💩", url = new URL(input) url.pathname // "/%F0%9F%92%A9"
Alternatively you can use the base URL of a
document through
baseURI
:
var input = "/💩", url = new URL(input, document.baseURI) url.href // "https://url.spec.whatwg.org/%F0%9F%92%A9"
URL
staticsThe
domainToASCII(domain)
static method, when invoked, must run these steps:
Let asciiDomain be the result of
invoking host
with
domain as input.
If asciiDomain matches
ipv6addr
or
ipv4addr
or
failure, return the empty string.
Return asciiDomain.
The
domainToUnicode(domain)
static method, when invoked, must run these steps:
Let asciiDomain be the result of invoking domainToASCII with domain as input.
Return the result of running domain to Unicode on asciiDomain.
Add domainToUI() which follows the UA conventions for when to use the Unicode representation?
URLUtils
and URLUtilsReadOnly
membersThe URLUtils
and URLUtilsReadOnly
interfaces are
not exposed on the global object. They are meant to augment other interfaces, such as
URL
.
The href
attribute's getter must run
these steps:
Return the serialization of url.
The href
attribute's setter must run these steps:
Let input be the given value.
If the context object
is a
URL
object, run these substeps:
Let parsedURL be the result of running the basic URL parser on input with base URL being the result of running get the base.
If parsedURL is failure,
throw a TypeError
exception.
Run set the input given the empty string and parsedURL.
Otherwise, run these substeps:
Run the set the input algorithm for input.
Run the pre-update steps with the input.
This means that if the href
attribute is set to
value that would cause the URL parser to return
failure, that value is still passed through unchanged. This is one of those unfortunate
legacy incidents.
var a = document.createElement("a"), input = "https://test:test/" // invalid port makes the parser return failure a.href = test a.href === test // true
The origin
attribute's getter must
run these steps:
If url is null, return the empty string.
Return the Unicode serialization of url's origin. [[!HTML]]
It returns the Unicode rather than the ASCII serialization for
compatibility with HTML's MessageEvent
feature.
[[!HTML]]
The protocol
attribute's getter
must run these steps:
The protocol
attribute's setter must
run these steps:
If url is null, terminate these steps.
set-protocol
on the input with
url as url.
Run the pre-update steps.
The username
attribute's getter
must run these steps:
The username
attribute's setter must
run these steps:
If url is null, or its scheme data is set, terminate these steps.
Set url's username to the empty string.
For each code point in username, utf-8 percent encode it using the username encode set, and append the result to url's username.
Run the pre-update steps.
The password
attribute's getter
must run these steps:
The resolution of bug 27516 may remove the ability to access passwords from scripts.
The password
attribute's setter must
run these steps:
If url is null, or its scheme data is set, terminate these steps.
If password is the empty string, set url's password to null.
Otherwise, run these substeps:
Set url's password to the empty string.
For each code point in password, utf-8 percent encode it using the password encode set, and append the result to url's password.
Run the pre-update steps.
The host
attribute's getter must run
these steps:
If url is null, return the empty string.
If port is the empty string, return host, serialized.
Return host,
serialized,
":
", and port
concatenated.
The host
attribute's setter must run these
steps:
If url is null, or its scheme data is set, terminate these steps.
set-host
on the input with
url as url.
Run the pre-update steps.
The hostname
attribute's getter
must run these steps:
If url is null, return the empty string.
Return host, serialized.
The hostname
attribute's setter must
run these steps:
If url is null, or its scheme data is set, terminate these steps.
set-hostname
on the input with
url as url.
Run the pre-update steps.
The port
attribute's getter must run
these steps:
The port
attribute's setter must run these steps:
If url is null, its
scheme data is set, or its
scheme is "file
",
terminate these steps.
set-port
on the input with url as
url.
Run the pre-update steps.
The pathname
attribute's getter
must run these steps:
If url is null, return the empty string.
If the scheme data is set, return scheme data.
Return "/
" concatenated with the strings in
path (including empty strings),
separated from each other by "/
".
The pathname
attribute's setter must
run these steps:
If url is null, or its scheme data is set, terminate these steps.
Empty path.
set-pathname
on the input with
url as url.
Run the pre-update steps.
The search
attribute's getter must
run these steps:
If url is null, or its query is either null or the empty string, return the empty string.
Return "?
" concatenated with
query.
The search
attribute's setter must run these steps:
If url is null, terminate these steps.
If the given value is the empty string, set query to null, empty query object's list, run its update steps, and terminate these steps.
Let input be the given value with a single leading
"?
" removed, if any.
Set query to the empty string.
set-search
on the input
with url as url, and the
associated query encoding as
encoding override.
Set query object's list to the result of parsing input.
Run query object's update steps.
The update steps of query object are run to ensure all url objects remain synchronized.
The searchParams
attribute's getter
must return the query object.
The searchParams
attribute's setter must run
these steps:
Let object be the given value.
Remove the context object from query object's list of url objects.
Append the context object to object's list of url objects.
Set query object to object.
Set query to the serialization of the query object's list.
Run the pre-update steps.
The hash
attribute's getter must run
these steps:
If url is null, or its fragment is either null or the empty string, return the empty string.
Return "#
" concatenated with
fragment.
The hash
attribute's setter must run these steps:
If url is null, or its
scheme is
"javascript
", terminate these steps.
If the given value is the empty string, set fragment to null, run the pre-update steps, and terminate these steps.
Let input be the given value with a single leading
"#
" removed, if any.
Set fragment to the empty string.
set-hash
on the input
with url as url.
Run the pre-update steps.
URLSearchParams
[Constructor(optional (USVString or URLSearchParams) init = ""), Exposed=(Window,Worker)] interface URLSearchParams { void append(USVString name, USVString value); void delete(USVString name); USVString? get(USVString name); sequence<USVString> getAll(USVString name); boolean has(USVString name); void set(USVString name, USVString value); iterable<USVString, USVString>; stringifier; };
A URLSearchParams
object has an associated
list of name-value pairs, which is initially
empty.
A URLSearchParams
object has an associated list of zero or more
url objects, which is initially empty.
URLSearchParams
objects always use
utf-8 as
encoding, despite the existence of
concepts such as
query encoding. This is to
encourage developers to migrate towards
utf-8, which they really ought to
have done a long time ago now.
To create a
new URLSearchParams
object, optionally
using init, run these steps:
Let query be a new URLSearchParams
object.
If init is the empty string or null, return query.
If init is a string, set query's list to the result of parsing init.
If init is a URLSearchParams
object, set
query's list to a copy
of init's list.
Return query.
A URLSearchParams
object's
update steps are to run these steps for
each associated url object
urlObject, in order:
Set urlObject's url's
query to the
serialization of
URLSearchParams
object's
list.
Run urlObject's pre-update steps.
The
URLSearchParams(init)
constructor, when invoked, must return a
new URLSearchParams
object
using init if given.
The
append(name, value)
method, when invoked, must run these steps:
Append a new name-value pair whose name is name and value is value, to list.
Run the update steps.
The
delete(name)
method, when invoked, must run these steps:
Remove all name-value pairs whose name is name from list.
Run the update steps.
The
get(name)
method, when invoked, must return the value of the first name-value pair whose name is
name in list, and null if
there is no such pair.
The
getAll(name)
method, when invoked, must return the values of all name-value pairs whose name is
name, in list,
in list order, and the empty sequence otherwise.
The
set(name, value)
method, when invoked, must run these steps:
If there are any name-value pairs whose name is name, in list, set the value of the first such name-value pair to value and remove the others.
Otherwise, append a new name-value pair whose name is name and value is value, to list.
Run the update steps.
The
has(name)
method, when invoked, must return true if there is a name-value pair whose name is
name in list, and false
otherwise.
The value pairs to iterate over are the list name-value pairs with the key being the name and the value the value.
The stringifier must return the
serialization of the
URLSearchParams
object's
list.
A standard that exposes URLs, should expose the
URL as a string (by serializing an
internal URL). A standard should not expose a URL using a
URL
object. URL
objects are meant for URL manipulation. In IDL the USVString type
should be used.
The higher-level notion here is that values are to be exposed as immutable data structures.
If a standard decides to use a variant of the name "URL" for a feature it defines, it should name such a feature "url" (i.e. lowercase and with an "l" at the end). Names such as "URL", "URI", and "IRI" should not be used. However, if the name is a compound, "URL" (i.e. uppercase) is preferred, e.g. "newURL" and "oldURL".
The {{EventSource}} and
< The While this description makes
The features provided by the
The
If encoding override is not given, set it to
utf-8.
If encoding override is not
utf-8 and input contains bytes
whose value is greater than 0x7F, return failure.
This can only happen if input was not
generated through the serializer or
Let sequences be the result of splitting
input on ` If the isindex flag is set and the first byte sequence in
sequences does not contain a ` Let pairs be an empty list of name-value pairs where both name
and value hold a byte sequence.
For each byte sequence bytes in sequences,
run these substeps:
If bytes is the empty byte sequence, run these substeps for the
next byte sequence.
If bytes contains a ` Otherwise, let name have the value of bytes
and let value be the empty byte sequence.
Replace any ` If use _charset_ flag is set, name is
` Let result be the result of
getting an encoding
for value,
decoded.
If result is not failure, unset use _charset_ flag and
set encoding override to result.
Add a pair consisting of name and
value to pairs.
Let output be an empty list of name-value pairs where both name
and value hold a string.
For each name-value pair in pairs, append a name-value pair to
output where the new name and value appended to output
are the result of running encoding override's
decoder on the
percent decoding of the name and value from
pairs, respectively.
Return output.
The
Let output be the empty string.
For each byte in input, depending on
byte:
Append U+002B to output.
Append a code point whose value is byte to
output.
Append byte,
percent encoded, to
output.
Return output.
The
If encoding override is not given, set it to
utf-8.
Let output be the empty string.
For each pair in pairs, run
these substeps:
Let outputPair be a copy of pair.
Replace outputPair's name and value with the result of running
encode on them using
encoding override, respectively.
Replace outputPair's name and value with their
serialization.
If pair is not the first pair in pairs, append
" Append outputPair's name, followed by " The
Some terms used in this specification are defined in the
DOM, Encoding, IDNA, and Web IDL Standards.
[[!DOM]]
[[!ENCODING]]
[[!IDNA]]
[[!WEBIDL]]
The ASCII digits are code points in the range U+0030 to U+0039.
The ASCII hex digits are ASCII digits or are
code points in the range U+0041 to U+0046 or in the range U+0061 to U+0066.
The ASCII alpha are code points in the range U+0041 to U+005A
or in the range U+0061 to U+007A.
The ASCII alphanumeric are ASCII digits or
ASCII alpha.
A percent-encoded byte is " The simple encode set are all code points less than
U+0020 (i.e. excluding U+0020) and all code points greater than U+007E.
The default encode set is the
simple encode set and code points U+0020,
' The password encode set is the
default encode set and code points
" The username encode set is the
password encode set and code point
" The query encode set is defined to be code points that are less
than U+0021, greater than U+007E, or one of U+0022, U+0023, U+003C, U+003E,
and U+0060.
A host is a network address in the
form of a domain, an IPv4 address, or an
IPv6 address.
A domain identifies a realm within a network.
An IPv4 address is a 32-bit
identifier and for the purposes of this specification represented as an ordered
list of four 8-bit pieces.
[[RFC791]]
An IPv6 address is a 128-bit
identifier and for the purposes of this specification is either represented as an ordered
list of eight 16-bit
pieces, or as a list of seven 16-bit pieces
followed by a single
32-bit piece. [[RFC4291]]
There have been a lot of people that have helped make
URLs more interoperable over the years and
thereby furthered the goals of this standard. Likewise many people have helped making this
standard what it is today.
With that, many thanks to
Adam Barth,
Albert Wiersch,
Alexandre Morgaut,
Arkadiusz Michalski,
Behnam Esfahbod,
Bobby Holley,
Boris Zbarsky,
Brandon Ross,
Dan Appelquist,
Daniel Bratell,
David Håsäther,
David Sheets,
David Singer,
Erik Arvidsson,
Gavin Carothers,
Geoff Richards,
Glenn Maynard,
Henri Sivonen,
Ian Hickson,
James Graham,
James Manger,
James Ross,
Joshua Bell,
Kevin Grandon,
Larry Masinter,
Mark Davis,
Marcos Cáceres,
Martin Dürst,
Mathias Bynens,
Michael Peick,
Michael™ Smith,
Michel Suignard,
Peter Occil,
Rodney Rehm,
Roy Fielding,
Santiago M. Mola,
Simon Pieters,
Simon Sapin,
Tab Atkins,
Tantek Çelik,
Tim Berners-Lee,
Vyacheslav Matva, and
成瀬ゆい (Yui Naruse)
for being awesome!
This standard is written by
Anne van Kesteren
(Mozilla,
annevk@annevk.nl)
and
Sam Ruby
(IBM,
rubys@intertwingly.net).
Per CC0, to
the extent possible under law, the editors have waived all copyright and related or
neighboring rights to this work.
application/x-www-form-urlencoded
application/x-www-form-urlencoded
format is a simple way to
encode name-value pairs in a byte sequence where all bytes are in the 0x00 to 0x7F range.
application/x-www-form-urlencoded
sound dated — and really, it is — the
format is in widespread use due to its prevalence of HTML forms.
[[!HTML]]
application/x-www-form-urlencoded
parsingapplication/x-www-form-urlencoded
parser
are mainly relevant for server-oriented implementations. A browser-based implementation
only needs what the
application/x-www-form-urlencoded
string parser
requires.
application/x-www-form-urlencoded
parser
takes a byte sequence input, optionally with an
encoding encoding override,
optionally with a use _charset_ flag, and optionally with an
isindex flag, and then runs these steps:
URLSearchParams
.
&
`.
=
`, prepend
`=
` to the first byte sequence in sequences.
=
`, then let
name be the bytes from the start of bytes up to but
excluding its first `=
`, and let value be the
bytes, if any, after the first `=
` up to the end of
bytes. If `=
` is the first byte, then
name will be the empty byte sequence. If it is the last, then
value will be the empty byte sequence.
+
` in name and
value with 0x20.
_charset_
`, run these substeps:
application/x-www-form-urlencoded
serializingapplication/x-www-form-urlencoded
byte serializer
takes a byte sequence input and then runs these steps:
application/x-www-form-urlencoded
serializer
takes a list of name-value pairs pairs, optionally with an
encoding
encoding override, and then runs these steps:
&
" to output.
=
",
followed by outputPair's value to output.
Hooks
application/x-www-form-urlencoded
string parser
takes a string input,
utf-8 encodes it, and then
returns the result of
application/x-www-form-urlencoded
parsing
it.
Terminology
%
", followed by
two ASCII hex digits. Sequences of
percent-encoded bytes, after
conversion to bytes, should not cause a
utf-8 decoder to run into any
errors.
"
',
"#
",
"<
",
">
",
"?
",
and
"`
".
/
",
"@
",
and
"\
".
:
".
Acknowledgments
{
"IDNA": {
"authors": [
"Mark Davis",
"Michel Suignard"
],
"href": "http://www.unicode.org/reports/tr46/",
"title": "Unicode IDNA Compatibility Processing",
"publisher": "Unicode Consortium"
},
"DOM": {
"authors": [
"Anne van Kesteren",
"Aryeh Gregor",
"Ms2ger"
],
"href": "https://dom.spec.whatwg.org/",
"title": "DOM",
"publisher": "WHATWG"
},
"ENCODING": {
"authors": [
"Anne van Kesteren"
],
"href": "https://encoding.spec.whatwg.org/",
"title": "Encoding",
"publisher": "WHATWG"
},
"FILEAPI": {
"authors": [
"Arun Ranganathan",
"Jonas Sicking"
],
"href": "http://dev.w3.org/2006/webapi/FileAPI/",
"title": "File API",
"publisher": "W3C"
},
"RFC791": {
"authors": [
"Jon Postel"
],
"href": "http://tools.ietf.org/html/rfc791",
"title": "Internet Protocol",
"publisher": "IETF"
},
"WEBIDL": {
"authors": [
"Cameron McCormack",
"Jonas Sicking"
],
"href": "http://heycam.github.io/webidl/",
"title": "Web IDL",
"publisher": "W3C"
}
}
urlPrefix: http://dev.w3.org/2006/webapi/FileAPI/; type: dfn
text: blob
text: blob url store; url: #BlobURLStore
urlPrefix: https://dom.spec.whatwg.org/; type: dfn
text: concept-attribute-value
text: concept-document
text: context object
text: dom-node-baseuri
urlPrefix: https://encoding.spec.whatwg.org/; type: dfn
text: ascii whitespace
text: concept-encoding-get
text: decoder
text: encode
text: encoding
text: error
text: utf-8
text: utf-8 decode without bom
text: utf-8 encode
text: utf-8 decoder
urlPrefix: https://html.spec.whatwg.org/multipage/
urlPrefix: comms.html; type: interface;
text: EventSource
text: HashChangeEvent
urlPrefix: browsers.html; type: dfn;
text: origin
text: unicode serialization of an origin
urlPrefix: infrastructure.html; type: dfn;
text: structured clone
urlPrefix: http://heycam.github.io/webidl/#dfn-; type: dfn;
text: throw
text: value pairs to iterate over
url: http://www.unicode.org/reports/tr46/#ToASCII; type: dfn; text: toascii
url: http://www.unicode.org/reports/tr46/#ToUnicode; type: dfn; text: tounicode