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

Jas*_*aty 51 html url http query-string

此问题涉及URL的查询字符串部分中的?字符,这些字符出现在标记字符之后.

根据维基百科,某些字符保持原样,其他字符编码(通常带有%转义序列).

我一直试图将其跟踪到实际规格,以便我理解维基百科页面中每个要点背后的理由.

矛盾例1:

HTML规范说来编码空间,+并按照其余RFC1738.但是,这个RFC说这~是不安全的,而且"[a] ll不安全的字符必须始终在URL中编码".这似乎与维基百科相矛盾.

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

矛盾示例2:

维基百科指出,它未提及的所有字符都必须进行编码.!在维基百科中没有提到.但是RFC1738声明这!是一个"特殊"字符并且"可以使用未编码的".这似乎与维基百科相矛盾,维基百科说它必须编码.

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

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

结论

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

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

为了比较,HTML5工作草案算法编码除字母数字和字母以外的所有字符*-._.空间的特殊情况编码仍然存在+.值得注意的差异*是未编码和~编码.(从技术上讲,这种处理*与RFC3986是兼容的,即使它*是在reserved因为它sub-delimsquery生产中允许的范围内.)

PJ *_*ing 45

答案在于RFC 3986文档,特别是第3.4节.

查询组件由第一个问号("?")字符表示,并以数字符号("#")字符或URI的末尾结束.

...

字符斜杠("/")和问号("?")可以表示查询组件中的数据.

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

query       = *( pchar / "/" / "?" )
Run Code Online (Sandbox Code Playgroud)

此语法意味着查询可以包括pchar以及/和的所有字符?.pchar指的是路径字符的另一种规范.有用的是,RFC 3986的附录A列出了相关的ABNF定义,最值得注意的是:

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

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

/ ? : @ - . _ ~ ! $ & ' ( ) * + , ; =
Run Code Online (Sandbox Code Playgroud)

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

  • 好吧,那么 PHP 用户需要在 `$_SERVER['QUERY_STRING']` 上使用符合规范的解析器,而不是依赖像 `$_GET` 这样的损坏的功能。 (3认同)
  • 注意:除了`=`和`&`之外,服务器端可能会限制PHP中其他合法未编码的查询字符串字符,如`.`(点),它将被`$ _GET`和`$中的`_`(下划线)替换_POST`.请参阅:http://stackoverflow.com/questions/68651/get-php-to-stop-replacing-characters-in-get-or-post-arrays(还有一个解决方法). (2认同)