HTTP 查询字符串中必须转义哪些字符?
Posted
技术标签:
【中文标题】HTTP 查询字符串中必须转义哪些字符?【英文标题】:What characters must be escaped in an HTTP query string? 【发布时间】:2021-11-14 13:10:52 【问题描述】:此问题涉及 URL 查询字符串部分中的字符,这些字符出现在 ?
标记字符之后。
根据Wikipedia,某些字符保持原样,而其他字符则被编码(通常使用%
转义序列)。
我一直在尝试将其追踪到实际规范,以便我了解该 Wikipedia 页面中每个要点背后的理由。
矛盾例子1:
html specification 表示将空间编码为+
,并将其余部分推迟到RFC1738。然而,这个 RFC 说 ~
是不安全的,而且“[a]ll 不安全的字符必须始终在 URL 中进行编码”。这似乎与***相矛盾。
实际上,IE8 在它生成的查询字符串中编码~
,而 FF3 保持原样。
矛盾例子2:
***声明它未提及的所有字符都必须进行编码。 !
未在***中提及。但是RFC1738 声明!
是一个“特殊”字符并且“可以未编码使用”。这似乎与***说它必须被编码相矛盾。
实际上,IE8 在它生成的查询字符串中编码!
,而 FF3 保持原样。
我知道这样做的寓意可能是对那些在 Wikipedia 和规范之间存在疑问的字符进行编码。甚至可能会编码所有不是 [A-Za-z0-9] 的东西。我只是想知道这方面的实际标准。
结论
***上描述的算法精确地编码那些不是RFC3986 unreserved characters 的字符。也就是说,它对除字母数字和-._~
之外的所有字符进行编码。作为一种特殊情况,根据 RFC3986,空格被编码为 +
而不是 %20
。
某些应用程序使用较旧的 RFC。作为比较,RFC2396 unreserved characters 是字母数字,!'()*-._~
。
为了比较,HTML5 working draft algorithm 对除字母数字和*-._
之外的所有字符进行编码。空间的特殊情况编码仍然是+
。显着的区别是*
未编码,~
已编码。 (从技术上讲,*
的这种处理与 RFC3986 兼容,即使 *
在 reserved
中,因为它在 sub-delims
中,而在 query
生产中是允许的。)
【问题讨论】:
***不是一个标准机构。如有疑问,请使用标准。 @John - 尽管使用 正确 标准很重要。在这种情况下是 3986,而不是旧的 1738。 What every web developer must know about URL encoding(“每个部分的保留字符不同”部分在此上下文中非常相关)。 【参考方案1】:答案在 RFC 3986 文档中,特别是 Section 3.4。
查询组件由第一个问题表示 标记 ("?") 字符并以数字符号 ("#") 字符结尾 或在 URI 的末尾。
...
字符斜线(“/”)和问号(“?”)可能代表数据 在查询组件中。
从技术上讲,RFC 3986-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 = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
因此,除了所有字母数字和百分比编码字符之外,查询还可以合法地包含以下未编码字符:
/ ? : @ - . _ ~ ! $ & ' ( ) * + , ; =
当然,您可能需要记住,“=”和“&”通常在查询中具有特殊意义。
【讨论】:
注意:除了=
和&
之外,服务器端可能会限制其他合法未编码的查询字符串字符,例如php中的.
(点),它将被_
(下划线)替换在$_GET
和$_POST
。请参阅:***.com/questions/68651/…(也有解决方法)。
好吧,那么 PHP 用户需要在 $_SERVER['QUERY_STRING']
上使用符合规范的解析器,而不是依赖像 $_GET
这样的损坏功能。以上是关于HTTP 查询字符串中必须转义哪些字符?的主要内容,如果未能解决你的问题,请参考以下文章