Myl*_*les 168
来自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
Run Code Online (Sandbox Code Playgroud)
Amb*_*ber 41
URI中允许的字符是保留的或未保留的(或百分比字符作为百分比编码的一部分)
http://en.wikipedia.org/wiki/Percent-encoding#Types_of_URI_characters
如果他们需要保留其特殊含义,则说这些是RFC 3986 无保留字符(第2.3节)以及保留字符(第2.2节).还有百分比字符作为百分比编码的一部分.
sla*_*acy 23
66个未保留字符的完整列表在RFC3986中,这里:http://tools.ietf.org/html/rfc3986#section-2.3
这是以下集合中的任何字符:
[A-Za-z0-9_.\-~]
Run Code Online (Sandbox Code Playgroud)
mgu*_*utt 14
我通过请求我的网站(apache)和我德语键盘上的所有可用字符作为URL参数来测试它:
http://example.com/?^1234567890ß´qwertzuiopü+asdfghjklöä#<yxcvbnm,.-°!"§$%&/()=? `QWERTZUIOPÜ*ASDFGHJKLÖÄ\'>YXCVBNM;:_²³{[]}\|µ@€~
Run Code Online (Sandbox Code Playgroud)
这些没有编码:
^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,.-!/()=?`*;:_{}[]\|~
Run Code Online (Sandbox Code Playgroud)
之后不编码urlencode():
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_
Run Code Online (Sandbox Code Playgroud)
之后不编码rawurlencode():
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~
Run Code Online (Sandbox Code Playgroud)
注意:在PHP 5.3.0之前rawurlencode()编码~因为RFC 1738.但这已被RFC 3986取代,因此现在可以安全使用.但我不明白为什么例如{}编码通过rawurlencode()因为RFC 3986中没有提到它们.
我做的另一项测试是关于邮件文本中的自动链接.我测试了Mozilla Thunderbird,aol.com,outlook.com,gmail.com,gmx.de和yahoo.de,他们完全链接了包含这些字符的URL:
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~+#,%&=*;:@
Run Code Online (Sandbox Code Playgroud)
当然,它?也是相关联的,但只有使用过一次.
有些人现在建议只使用rawurlencode()字符,但你有没有听说有人打开这些网站有问题?
星号
http://wayback.archive.org/web/*/http://google.com
冒号
https://en.wikipedia.org/wiki/Wikipedia:About
另外
https://plus.google.com/+google
在Sign,Colon,逗号和感叹号
https://www.google.com/maps/place/USA/@36.2218457,...
因为这些字符应该可以在没有问题的情况下进行编码.当然你不应该&;因为编码序列而使用&.同样的原因是有效的,%因为它一般用于编码字符.并且=它为参数名称赋值.
最后我会说这可以使用这些未编码的:
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~!+,*:@
Run Code Online (Sandbox Code Playgroud)
但是如果您希望随机生成的URL不应该使用.!,因为那些标记了句子的结尾,而某些邮件应用程序不会自动链接该URL的最后一个字符.例:
Visit http://example.com/foo=bar! !
Run Code Online (Sandbox Code Playgroud)
Cyk*_*ker 10
RFC3986定义了可以在 URI 中使用的两组字符:
保留字符::/?#[]@!$&'()*+,;=
保留 = gen-delims / sub-delims
gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
子delims =“!” / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
保留字符的目的是提供一组可与 URI 中的其他数据区分开来的定界字符。在用相应的百分比编码的八位字节替换保留字符方面不同的 URI 是不等价的。
无保留字符:A-Za-z0-9-_.~
未保留 = ALPHA / DIGIT / "-" / "." / "_" / "~"
URI 中允许但没有保留用途的字符称为未保留。
这个答案讨论了URL 片段部分中可能包含的字符而不被转义。我发布了一个单独的答案,因为这部分与这里的其他优秀答案略有不同(并且可以结合使用)。
#片段部分不会发送到服务器,而是本例中后面的字符:
RFC 3986中的相关规范是:
fragment = *( pchar / "/" / "?" )
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
Run Code Online (Sandbox Code Playgroud)
这也引用了RFC 2234中的规则
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
DIGIT = %x30-39 ; 0-9
Run Code Online (Sandbox Code Playgroud)
所以完整的列表,不包括转义符 ( pct-encoded) 是:
A-Z a-z 0-9 - . _ ~ ! $ & ' ( ) * + , ; = : @ / ?
为了您的方便,这里有一个 PCRE 表达式,它与一个有效的、未转义的片段相匹配:
/^[A-Za-z0-9\-._~!$&'()*+,;=:@\/?]*$/
Run Code Online (Sandbox Code Playgroud)
算起来,有:
26 + 26 + 10 + 19 = 81 个代码点
您可以使用 Base 81 在这里有效地编码数据。