什么字符必须转义HTTP查询string?

这个问题涉及URL的查询string部分中的字符,它出现在? 标记字符。

根据维基百科 ,某些字符保持不变 ,其他字符被编码(通常使用%转义序列)。

我一直在试图追踪到实际的规格,所以我理解维基百科页面中的每一个重点的理由。

矛盾例1:

HTML规范说将空间编码为+然后将其余部分推迟到RFC1738 。 但是,这个RFC表示~是不安全的,而且“不安全的字符必须始终在URL中进行编码”。 这似乎与维基百科矛盾。

实际上,IE8在它生成的查询string中编码~ ,而FF3保持原样。

矛盾例2:

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

实际上,IE8编码! 在它生成的查询string中,而FF3保持原样。

我明白,这个道德可能会被编码在维基百科和规范之间的疑问字符。 也许甚至会编码一切不是[A-ZA-Z0-9]的东西。 我只想知道这方面的实际标准。

结论

维基百科上描述的algorithm精确地对那些不是RFC3986非保留字符的字符进行编码。 也就是说,它编码除了字母数字和-._~以外的所有字符。 作为特殊情况,空间被编码为+而不是每个RFC3986的%20

某些应用程序使用较旧的RFC。 为了比较, RFC2396未保留的字符是字母数字和!'()*-._~

为了比较, HTML5工作草案algorithm对除字母数字和*-._之外的所有字符进行编码。 编码空间的特殊情况仍然是+ 。 值得注意的区别是*不是编码,而是编码。 (从技术上讲, *处理与RFC3986兼容,即使*因为处于query生产允许的sub-delims而被reserved )。

答案在于RFC 3986文档,具体是第3.4节 。

查询组件由第一个问号(“?”)字符表示,并以数字符号(“#”)字符结尾或由URI结尾。

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

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

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

这个语法意味着查询可以包含来自pchar所有字符以及/?pchar是指path字符的另一个规范。 有用的是,RFC 3986的附录A列出了相关的ABNF定义,最显着的是:

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

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

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

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