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没有问题。 当然你不应该用&;
由于编码序列像&
。 一般来说,同样的原因对%
来说也是有效的。 和=
因为它将一个值分配给参数名称。
最后我会说可以使用这些未经编码的:
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。