2024-12-01 10:00:01

URL中允许的字符

有人知道可以在GET中使用而不经过编码的完整字符列表吗?目前我使用A-Z - A-Z和0-9…但我想知道完整的名单。

我也感兴趣的是,是否会发布关于即将添加中文、阿拉伯语url的规范(显然这将对我的问题产生很大影响)。


当前回答

编辑:正如@Jukka K. Korpela正确指出的那样,RFC 1738由RFC 3986更新。 这已经扩展和澄清了对主机有效的字符,不幸的是,它不容易复制和粘贴,但我会尽我所能。

按首先匹配的顺序排列:

host        = IP-literal / IPv4address / reg-name

IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"

IPvFuture   = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )

IPv6address =         6( h16 ":" ) ls32
                  /                       "::" 5( h16 ":" ) ls32
                  / [               h16 ] "::" 4( h16 ":" ) ls32
                  / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
                  / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
                  / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
                  / [ *4( h16 ":" ) h16 ] "::"              ls32
                  / [ *5( h16 ":" ) h16 ] "::"              h16
                  / [ *6( h16 ":" ) h16 ] "::"

ls32        = ( h16 ":" h16 ) / IPv4address
                  ; least-significant 32 bits of address

h16         = 1*4HEXDIG 
               ; 16 bits of address represented in hexadecimal

IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet

dec-octet   = DIGIT                 ; 0-9
              / %x31-39 DIGIT         ; 10-99
              / "1" 2DIGIT            ; 100-199
              / "2" %x30-34 DIGIT     ; 200-249
              / "25" %x30-35          ; 250-255

reg-name    = *( unreserved / pct-encoded / sub-delims )

unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"     <---This seems like a practical shortcut, most closely resembling original answer

reserved    = gen-delims / sub-delims

gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
              / "*" / "+" / "," / ";" / "="

pct-encoded = "%" HEXDIG HEXDIG

来自RFC 1738规范的原始答案:

因此,只有字母数字,特殊字符“$-_.+!*'(),”,和 可以使用用于保留目的的保留字符 没有在URL中编码。

^自1998年起过时。

其他回答

RFC3986定义了两组你可以在URI中使用的字符:

Reserved Characters: :/?#[]@!$&'()*+,;= reserved = gen-delims / sub-delims gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" The purpose of reserved characters is to provide a set of delimiting characters that are distinguishable from other data within a URI. URIs that differ in the replacement of a reserved character with its corresponding percent-encoded octet are not equivalent. Unreserved Characters: A-Za-z0-9-_.~ unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" Characters that are allowed in a URI but do not have a reserved purpose are called unreserved.

即将到来的改变是针对中文,阿拉伯语域名,而不是uri。国际化的uri称为iri,在RFC 3987中定义。尽管如此,我还是建议不要自己这么做,而是依赖于现有的、经过测试的库,因为有很多URI编码/解码的选择,以及规范上认为安全的,以及实际使用(浏览器)上认为安全的。

URI中允许的字符要么是保留的,要么是不保留的(或者是百分比字符作为百分比编码的一部分)。

http://en.wikipedia.org/wiki/Percent-encoding#Types_of_URI_characters

说这些是RFC 3986非保留字符(第2.3节),以及保留字符(第2.2节),如果他们需要保留他们的特殊含义。还有一个百分比字符作为百分比编码的一部分。

这个答案讨论了字符可以包含在URL片段部分中而不进行转义。我单独发布了一个答案,因为这部分与这里的其他优秀答案略有不同(并且可以结合使用)。

片段部分不会被发送到服务器,在这个例子中,它是在#后面的字符:

https://example.com/#STUFF-HERE

规范

RFC 3986中的相关规范为:

  fragment    = *( pchar / "/" / "?" )
  pchar       = unreserved / pct-encoded / sub-delims / ":" / "@"
  unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
  sub-delims  = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

这也引用了RFC 2234中的规则

  ALPHA       =  %x41-5A / %x61-7A   ; A-Z / a-z
  DIGIT       =  %x30-39             ; 0-9

结果

所以完整的列表,不包括转义(pct编码)是:

A-Z -z 0-9。_ ~ !$ & ' () * +,;=: @ / ?

为了方便起见,这里有一个匹配有效的、未转义的片段的PCRE表达式:

/^[A-Za-z0-9\-._~!$&'()*+,;=:@\/?]*$/

编码

算起来,有:

26 + 26 + 10 + 19 = 81代码点

您可以使用基数81来有效地编码这里的数据。

这些都列在RFC3986中。请参阅收集的ABNF中的URI,以了解在哪里允许什么,以及用于解析/验证的正则表达式。