URL中允许的字符

有没有人知道可以在GET中使用的字符的完整列表,而不被编码? 目前我正在使用AZ az和0-9 …但我正在查找完整列表。

我也很感兴趣,如果有一个规范发布的中文,阿拉伯文网址的增加(显然这将对我的问题产生重大影响)

从RFC 1738规范:

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

编辑:正如@ Jukka K. Korpela正确地指出,这RFC由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 

URI中允许的字符既可以是保留的,也可以是非保留的(或者百分号是百分比编码的一部分)

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

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

66个未保留字符的完整列表在RFC3986中,这里是: http ://tools.ietf.org/html/rfc3986#section-2.3

这是以下任何字符:

 [A-Za-z0-9_.-~] 

从这里

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

这些在RFC3986中列出。 查看收集的ABNF的URI来看看什么是允许的地方和解析/验证的正则表达式 。

我通过请求我的网站(apache)以德语键盘上的所有可用字符作为URL参数来测试它:

 http://example.com/?^1234567890ß´qwertzuiopü+asdfghjklöä#<yxcvbnm,.-°!"§$%&/()=? `QWERTZUIOPÜ*ASDFGHJKLÖÄ\'>YXCVBNM;:_²³{[]}\|µ@€~ 

这些没有被编码:

 ^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,.-!/()=?`*;:_{}[]\|~ 

urlencode()之后不进行编码:

 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_ 

rawurlencode()之后不进行编码:

 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~ 

注意:由于RFC 1738,在PHP 5.3.0之前的rawurlencode()编码。 但是这已被RFC 3986所取代,因此现在可以安全使用。 但我不明白为什么例如{}通过rawurlencode()编码,因为它们没有在RFC 3986中提到。

我做的另一个测试是关于邮件文本中的自动链接。 我测试了Mozilla Thunderbird,aol.com,outlook.com,gmail.com,gmx.de和yahoo.de,他们完全链接了包含这些字符的URL:

 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~+#,%&=*;:@ 

当然? 也被连接起来,但只有当它被使用一次。

现在有些人会建议只使用rawurlencode()字符,但是你有没有听说有人打开这些​​网站有问题?

星号
http://wayback.archive.org/web/*/http://google.com

结肠
https://en.wikipedia.org/wiki/Wikipedia:About


https://plus.google.com/+google

在标志,冒号,逗号和感叹号
HTTPS://www.google.com/maps/place/USA/@36.2218457,…

因为这些字符应该可以使用unncoded没有问题。 当然你不应该用&; 由于编码序列像&amp; 。 一般来说,同样的原因对%来说也是有效的。 和=因为它将一个值分配给参数名称。

最后我会说可以使用这些未经编码的:

 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~!+,*:@ 

但是,如果你期望随机生成的网址,你不应该使用.! ,因为这些标记句子的结尾,一些邮件应用程序不会自动链接URL的最后一个字符。 例:

 Visit http://example.com/foo=bar! ! 

即将到来的变化是中国,阿拉伯域名,而不是URI。 国际化的URI称为IRI,在RFC 3987中定义。 不过,我建议不要自己这样做,而要依靠现有的经过测试的库,因为URI编码/解码有很多选择,规范认为是安全的,而实际使用(浏览器) 。

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

  • 保留字符:/?#[]@!$&'()*+,;=

    reserved = gen-delims / sub-delims

    gen-delims =“:”/“/”/“?” /“#”/“[”/“]”/“@”

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

    保留字符的目的是提供一组可以区分URI内的其他数据的分隔字符。 用相应的百分比编码字节替换保留字符的URI不相同。

  • 未保留字符A-Za-z0-9-_.~

    unreserved = ALPHA / DIGIT /“ – ”/“。” /“_”/“〜”

    URI中允许使用但不具有保留目的的字符称为unreserved。