URL中允许的字符

Mar*_*ark 180 url

有没有人知道在没有编码的情况下可以在GET中使用的完整字符列表?目前我正在使用AZ az和0-9 ......但我希望找到完整列表.

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

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)

  • @Tim斜杠是一个保留字符,因此,如果它被用于保留目的(描述路径,协议描述......),那么它不需要转义.否则就是这样. (5认同)
  • RFC 1738的通用语法规则在1998年被废弃. (4认同)
  • 你可以在这个答案的开头添加未保留的`A-Za-z0-9 _.-〜`列表和保留字符.`!*'();:@&= + $,/?#[]`它可以为人们节省时间 (4认同)
  • @Myles,STD 66(= RFC 3986)在其他答案中提到.答案的内容是否正确是一个不同的问题; 我认为任何答案都没有正确描述完整列表. (3认同)
  • @basZero我很抱歉你发现它令人困惑,但完整的答案并不简单.你的问题的答案是否定的,因为它是一个保留的字符,如下所述:`reserved = gen-delims/sub-delims gen-delims =":"/"/"/"?" /"#"/"["/"]"/"@"` (2认同)
  • @basZero 实际上,这是不正确的。“保留”并不意味着“不能使用”——斜线和冒号也是保留的,但它们几乎出现在所有 URL 中!相反,“保留”是指该字符在 URL 的某些部分具有特殊意义,因此不能随意使用。AFAICT,`@` 被允许作为“权限”组件(如`http://fred@example.com/index.html`)和路径段中的分隔符(一个规范的例子是`mailto:fred@example .com`,但看起来 `http://example.com/p@th/d@t@.html` 应该同样有效)。 (2认同)

Amb*_*ber 41

URI中允许的字符是保留的或未保留的(或百分比字符作为百分比编码的一部分)

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

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

  • 虽然此链接可能会回答这个问题,但最好在此处包含答案的基本部分并提供参考链接.如果链接的页面发生更改,则仅链接的答案可能会无效. (7认同)

sla*_*acy 23

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

这是以下集合中的任何字符:

[A-Za-z0-9_.\-~]
Run Code Online (Sandbox Code Playgroud)

  • 您也可以使用那些保留的内容。 (2认同)
  • 小心,您已将其编写为正则表达式字符类。确保将 `-` 转义或将其放在字符类的开头或结尾,因为 `[.-~]` 实际上包含从 46 到 126 的所有 ASCII 字符。 (2认同)

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

因为这些字符应该可以在没有问题的情况下进行编码.当然你不应该&;因为编码序列而使用&amp;.同样的原因是有效的,%因为它一般用于编码字符.并且=它为参数名称赋值.

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

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~!+,*:@
Run Code Online (Sandbox Code Playgroud)

但是如果您希望随机生成的URL不应该使用.!,因为那些标记了句子的结尾,而某些邮件应用程序不会自动链接该URL的最后一个字符.例:

Visit http://example.com/foo=bar! !
Run Code Online (Sandbox Code Playgroud)


Ada*_*Dev 12

这里开始

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


Cyk*_*ker 10

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

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

    保留 = gen-delims / sub-delims

    gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"

    子delims =“!” / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

    保留字符的目的是提供一组可与 URI 中的其他数据区分开来的定界字符。在用相应的百分比编码的八位字节替换保留字符方面不同的 URI 是不等价的。

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

    未保留 = ALPHA / DIGIT / "-" / "." / "_" / "~"

    URI 中允许但没有保留用途的字符称为未保留。


McD*_*ell 7

这些列在RFC3986中.请参阅Collected ABNF for URI 以查看允许的位置以及解析/验证的正则表达式.


Wil*_*ken 6

这个答案讨论了URL 片段部分中可能包含的字符而不被转义。我发布了一个单独的答案,因为这部分与这里的其他优秀答案略有不同(并且可以结合使用)。

#片段部分不会发送到服务器,而是本例中后面的字符:

https://example.com/#STUFF-这里

规格

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 在这里有效地编码数据。