URL中允许的字符

时间:2009-12-06 22:10:17

标签: url

有没有人知道可以在GET中使用的完整字符列表而不进行编码?目前我正在使用A-Z a-z和0-9 ......但我希望找到完整列表。

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

10 个答案:

答案 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,...

因为这些字符应该可以在没有问题的情况下使用。当然,由于&;之类的编码序列,您不应该使用&amp;。同样的原因对%有效,因为它通常用于编码字符。 =,因为它为参数名称赋值。

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

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)

如果您想给用户一种特殊的体验,可以使用pushState在浏览器的网址中添加各种字符:

enter image description here

var u="";var tt=168;
for(var i=0; i< 250;i++){
 var x = i+250*tt;
console.log(x);
 var c = String.fromCharCode(x);
 u+=c; 
}
history.pushState({},"",250*tt+u);