必须在HTTP查询字符串中转义哪些字符?

时间:2010-02-24 00:07:30

标签: html http url query-string

此问题涉及网址的查询字符串部分中的字符,这些字符显示在?标记字符之后。

Wikipedia,某些字符保持原样,其他字符编码(通常带有%转义序列。)

我一直在尝试将其跟踪到实际规格,以便我了解维基百科页面中每个项目符号背后的理由。

矛盾示例1:

HTML specification表示将空格编码为+,并将其余部分推迟到RFC1738。但是,这个RFC说~是不安全的,而且“[a] ll不安全的字符必须始终在URL中编码”。这似乎与维基百科相矛盾。

实际上,IE8在它生成的查询字符串中对~进行编码,而FF3则保留原样。

矛盾示例2:

维基百科指出,所有未提及的字符都必须进行编码。维基百科中未提及!。但RFC1738指出!是一个“特殊”字符,“可能会被用于未编码”。这似乎与维基百科相矛盾,维基百科说它必须编码。

实际上,IE8在它生成的查询字符串中对!进行编码,而FF3则保留原样。

据我所知,这可能是为了对那些在维基百科和规范之间存在疑问的字符进行编码。甚至可能编码所有不是[A-Za-z0-9]的东西。我只想知道实际的标准。

结论

维基百科上描述的算法精确编码那些不是RFC3986 unreserved characters的字符。也就是说,它编码除字母数字和-._~以外的所有字符。作为一种特殊情况,根据RFC3986,空间编码为+而不是%20

某些应用程序使用较旧的RFC。相比之下,RFC2396 unreserved characters是字母数字和!'()*-._~

为了进行比较,HTML5 working draft algorithm对除字母数字和*-._以外的所有字符进行编码。空间的特殊情况编码仍为+。值得注意的差异是*未编码且~已编码。 (从技术上讲,*的处理与RFC3986兼容,即使*位于reserved,因为它位于sub-delims生产中允许的query中。)

1 个答案:

答案 0 :(得分:41)

答案在于RFC 3986文档,特别是Section 3.4

  

查询组件由第一个问题指示     标记(“?”)字符并以数字符号(“#”)字符结束     或者在URI的末尾。

     

...

     

字符斜杠(“/”)和问号(“?”)可能代表数据     在查询组件中。

从技术上讲,RFC 3976-3.4将查询组件定义为:

query       = *( pchar / "/" / "?" )

此语法表示查询可以包含pchar以及/?中的所有字符。 pchar指的是路径字符的另一个规范。有用的是,RFC 3986的Appendix A列出了相关的ABNF定义,最值得注意的是:

query         = *( pchar / "/" / "?" )
pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded   = "%" HEXDIG HEXDIG
sub-delims    = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

因此,除了所有字母数字和百分比编码字符之外,查询还可以合法地包含以下未编码的字符:

/ ? : @ - . _ ~ ! $ & ' ( ) * + , ; =

当然,您可能需要记住'='和'&'通常在查询中具有特殊意义。