有没有人知道可以在GET中使用的完整字符列表而不进行编码?目前我正在使用A-Z a-z和0-9 ......但我希望找到完整列表。
我也感兴趣的是,是否有针对中文,阿拉伯语网址的增加发布的规范(显然这将对我的问题产生重大影响)
答案 0 :(得分:162)
来自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
答案 1 :(得分:41)
URI中允许的字符是保留的或未保留的(或百分比字符作为百分比编码的一部分)
http://en.wikipedia.org/wiki/Percent-encoding#Types_of_URI_characters
如果需要保留其特殊含义,则表示这些是RFC 3986 无保留字符(第2.3节)以及保留字符(第2.2节)。还有一个百分比字符作为百分比编码的一部分。
答案 2 :(得分:21)
66个未保留字符的完整列表位于RFC3986中,此处为:http://tools.ietf.org/html/rfc3986#section-2.3
这是以下正则表达集中的任何字符:
[A-Za-z0-9_.\-~]
答案 3 :(得分:12)
来自here
因此,只有字母数字,特殊字符
$-_.+!*'(),
用于他们的保留字符 保留的目的可以在URL中以未编码的方式使用。
答案 4 :(得分:11)
我通过请求我的德语键盘上所有可用字符作为URL参数请求我的网站(apache)来测试它:
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,...
因为这些字符应该可以在没有问题的情况下使用。当然,由于&;
之类的编码序列,您不应该使用&
。同样的原因对%
有效,因为它通常用于编码字符。 =
,因为它为参数名称赋值。
最后我会说使用这些未编码的确定可以:
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~!+,*:@
但是,如果您希望随机生成的网址不应使用.!
,因为这些标记了句子的结尾,而某些邮件应用程序不会自动链接网址的最后一个字符。例如:
Visit http://example.com/foo=bar! !
答案 5 :(得分:7)
这些列在RFC3986中。请参阅Collected ABNF for URI以查看允许的位置以及用于解析/验证的regex。
答案 6 :(得分:3)
即将发生的变化是针对中国,阿拉伯语域名而非URI。国际化的URI称为IRI,在RFC 3987中定义。但是,我已经说过,我建议不要自己做,而是依靠现有的,经过测试的库,因为有很多URI编码/解码的选择,以及规范认为安全的东西,而不是实际使用的安全(浏览器)
答案 7 :(得分:3)
RFC3986定义了可在URI中使用的两组字符:
保留字符::/?#[]@!$&'()*+,;=
reserved = gen-delims / sub-delims
gen-delims =&#34;:&#34; /&#34; /&#34; /&#34;?&#34; /&#34;#&#34; /&#34; [&#34; /&#34;]&#34; /&#34; @&#34;
sub-delims =&#34;!&#34; /&#34; $&#34; /&#34;&amp;&#34; /&#34;&#39;&#34; /&#34;(&#34; /&#34;)&#34; /&#34; *&#34; /&#34; +&#34; /&#34;,&#34; /&#34;;&#34; /&#34; =&#34;
保留字符的目的是提供一组与URI中的其他数据可区分的分隔字符。保留字符替换与其对应的百分比编码八位字节不同的URI不等效。
未保留字符:A-Za-z0-9-_.~
未保留= ALPHA / DIGIT /&#34; - &#34; /&#34;。&#34; /&#34; _&#34; /&#34;〜&#34;
URI中允许但没有保留目的的字符称为未保留字符。
答案 8 :(得分:1)
这个答案讨论了characters may be included inside a URL fragment part without being escaped。我发布了一个单独的答案,因为这部分与此处的其他优秀答案略有不同(并且可以结合使用)。
片段部分不会发送到服务器,而是在此示例中 #
后面的字符:
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-encoded
) 的完整列表是:
A-Z
a-z
0-9
-
.
_
~
!
$
{{ 1}} &
'
(
)
*
+
,
;
=
{{ 1}} :
@
为了您的方便,这里有一个 PCRE 表达式匹配一个有效的、未转义的片段:
/
算起来,有:
26 + 26 + 10 + 19 = 81 个代码点
您可以在这里使用 base 81 来有效地编码数据。
答案 9 :(得分:0)