HTTP GET请求字符串的正确编码是什么?

20

HTTP标准或其他标准是否定义了在使用%XX编码之前应该使用哪种编码处理特殊字符?如果没有定义,是否有一种方法来定义使用的编码方式?似乎大多数浏览器会使用UTF-8发送数据。

3个回答

26
HTTP标准或其他标准并没有规定在使用%XX编码之前特殊字符应该使用哪种编码。但是,另一个标准IRI可能会发挥作用。一旦解码,URI明确是字节序列。这些字节映射到Unicode字符并未由URI标准或http:-scheme URIs的HTTP标准指定。对于查询参数:Web浏览器将使用原始页面的编码来创建表单提交GET URL,因此,如果您有一个使用ISO-8859-1编码的页面,并在搜索框中输入“é”,则会得到“?search=%E9”,但是,如果您在以UTF-8编码的页面上执行相同操作,则会得到“?search=%C3%E9”。如果您没有使用特定字符集来提供表单页面,则浏览器会猜测,这是不需要的,因为它会使无法猜测提交的格式。对于URL的其他部分,浏览器不会自动生成它们,但是如果您在链接中提供非ASCII字符,则通常会将它们编码为UTF-8。这不是可靠的,因为它取决于浏览器和区域设置,因此最好现在不要使用它。

适当允许非ASCII字符的链接标准是IRI。 IRI通过UTF-8-%编码大多数URL来转换为URI,但主机名使用Punycode进行转换。为了兼容性,最好不要依赖浏览器理解链接中的IRIs。相反,自己对路径和参数字符进行UTF-8然后%编码。在现代浏览器的地址栏中,它们仍将显示为正确的字符;不幸的是,根据语言设置,IE不会在所有情况下显示已解码字符的IRI形式。

希腊伽玛字符的Wiki IRI为:

http://en.wikipedia.org/wiki/Γ

编码为URI后,它是:

http://en.wikipedia.org/wiki/%CE%93

你从哪里了解到浏览器会使用接收到的表单编码发送数据?当我更改内容字符集信息时,我的Firefox和Chrome确实似乎是这样工作的。 - JtR
这只是一种一直被遵循的行为,早在Netscape时代就已经存在了。根据规范,提交编码应该由accept-charset控制,并在多部分表单数据子标头中与服务器通信,但实际上IE会危险地错误地获取accept-charset,而且没有浏览器发送表单数据子标头,因此我们被困在依赖表单编码的情况下。哦,好吧,总有一天每个人都会使用UTF-8,一切都会正常工作。一个世纪... - bobince

2
根据RFC 2616
   CHAR           = <any US-ASCII character (octets 0 - 127)>

并且

 token          = 1*<any CHAR except CTLs or separators>
   separators     = "(" | ")" | "<" | ">" | "@"
                  | "," | ";" | ":" | "\" | <">
                  | "/" | "[" | "]" | "?" | "="
                  | "{" | "}" | SP | HT

URIs是带有不同特定分隔符的“token”。因此,理论上只应该有US-ASCII。实际上,由于ISO-8859-1扩展到US-ASCII在HTTP规范的许多其他位置中使用,因此发现支持ISO-8859-1而不仅仅是US-ASCII的HTTP实现并不罕见,但严格来说这不符合标准的HTTP。

1
据我所知,目前没有办法定义它,尽管我一直认为它是ASCII,因为DNS就是这样的(尽管本地化DNS正在到来,带来了所有相关问题)。
注意:UTF8“兼容”ASCII,除非您尝试使用扩展字符。这可能在某种程度上解释了为什么某些浏览器可能会发送其GET数据UTF8编码的原因。
编辑:根据您的评论,似乎您完全不知道%编码的工作原理,因此请看以下说明。
给定以下字符串查询字符串,“?foo = Hello World!”,“Hello World!”部分需要进行URL编码。这个过程是任何“特殊”的字符都会被取出其ASCII值并转换为以“%”为前缀的十六进制数。因此,上述字符串将转换为“?foo = Hello%20World%21”。

我的意思是请求参数中的特殊字符,例如在http://foo/page.php?name=%12%34foo中。 - JtR
我认为ISO-8859也与ASCII兼容,除非您使用ASCII中缺失的内容。我的Firefox似乎至少会将iso-8859-1作为请求中默认的accept-charset参数发送。在更改了about:config中的默认编码后,它仍然以UTF-8发送get请求。 - JtR
Accept-Charset 只影响返回页面的编码,而不影响请求本身。我所指的是 GET 查询中的每个字符,而不仅仅是主机名或其他部分。 - Matthew Scharley
你是怎么得出我不知道URI转义如何工作的结论的? - JtR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接