浏览器在发送请求时如何决定使用哪个字符集?以及我们应该如何处理它?

Posted

技术标签:

【中文标题】浏览器在发送请求时如何决定使用哪个字符集?以及我们应该如何处理它?【英文标题】:How do browsers decide which character set to use when sending requests? And how should we deal with it? 【发布时间】:2014-11-04 10:01:14 【问题描述】:

tl;dr: 当浏览器/用户代理提交表单时,它被提交为 UTF-8(在我的测试中),但在 HTTP 请求中不包含该信息。用户代理如何决定使用 UTF-8?以及应用程序代码(接收请求的代码)应该如何决定使用哪个字符集来解码传入的数据?


在过去的几天里,我一直在互联网上进行挖掘,以了解数据从浏览器发送到网络服务器时是如何编码的。事实证明,这件事并非无关紧要,因为这件事没有明确的标准。

RFC2616 (HTTP) 主要基于 ISO-8859-1 和 US-ASCII。但是存在扩展以允许其他字符集(如 RFC2047)。 edit: RFC2616 已被 RFC7231 淘汰,RFC7231 删除了有关 ISO-8859-1 的注释(请参阅 @987654323 @)

请求正文

本质上,当用户代理发送一个包含正文的请求时,问题似乎很明确:使用包含charset 参数的Content-Type 标头。例如:

Content-Type: text/plain; charset=utf-8

使用 javascript 很容易做到这一点。但是今天,我遇到了在使用 html 表单元素时无法指定字符集的问题。在搜索中,我遇到了this SO question,但在我看来,答案是错误的。它声称使用accept-charset 属性。但是从the reference 开始,此标头用于告诉服务器客户端/用户代理可以接受什么字符集。反之亦然。

相关的FORM属性enctype指定提交文档的内容类型。但它只允许三个值,如果它们不按原样使用,用户代理(在本例中为 Chrome)默认为application/x-www-form-urlencoded。您不能指定字符集,我认为这很好,因为 UA 的工作是为您编码。

但是结果,到达服务器的请求完全没有任何关于所使用字符集的信息。那么应用程序代码应该如何决定使用哪种编码?

另一个问题是:用户代理如何在提交表单时决定使用哪个字符集?在我所有的测试中,他们将其提交为 UTF-8。但这从何而来?嗅探网络流量并没有告诉我这可能来自哪里。虽然,原始网页包含一个元标记,说明该页面采用 UTF-8 格式。是这样吗?

假设 UA 使用的字符集与它刚刚从服务器接收到的字符集相同。但是,如果它从应用程序 A 请求的页面(以 UTF-8 格式)包含一个对应用程序 B 执行 POST 操作的表单怎么办。假设这是完全可能的(同源策略仅适用于 XHRIO 对吗?)...在在那种情况下,UA 没有关于编码的“先验”信息。 它如何决定选择哪种编码?

HTTP“序言”和标头

只是把这个记下来作为参考

URI 在 2005 年之后定义良好(请参阅 RFC3986),并且应该使用 UTF-8。在此之前,没有定义标准,有点猜测。

标题值在RFC5987 中定义良好。


参考资料:

超文本传输​​协议 (HTTP) 标头字段参数的字符集和语言编码 - RFC5987 在超文本传输​​协议 (HTTP) 中使用 Content-Disposition 标头字段附录 C - RFC6266 HTML 表单元素 (enctype) 统一资源标识符 (URI):通用语法 - RFC3986

【问题讨论】:

请不要再担心RFC2616了;几个月前它已经过时了。在这种特殊情况下,无论如何它都不是 HTTP 的一个方面——正如答案中所指出的,它是 HTML 表单提交过程的一个属性。 确实如此。我一直在查看“被淘汰”的引用,但不知何故错过了 rfc7231,这在section 5.3.3 中澄清了很多。在通过 RFC 游了一天之后,我一定是在某个时候分神了 :( 【参考方案1】:

4.10.22.5, Selecting a form submission encoding 部分描述了用户代理为 html 5 表单提交选择编码的过程。

如果表单上没有(有效的)accept-charset 元素,则默认为 UTF-8。

对于html 4 it is:

[accept-charset] 属性的默认值是保留字符串“UNKNOWN”。用户代理可以将此值解释为用于传输包含此 FORM 元素的文档的字符编码。

【讨论】:

以上是关于浏览器在发送请求时如何决定使用哪个字符集?以及我们应该如何处理它?的主要内容,如果未能解决你的问题,请参考以下文章

负载均衡的常用算法

ajax请求请求数据缓存问题分析以及解决方案

使用Restlet Client发送各种Get和Post请求

如何找出这个 IPN 请求发送到哪个文件?

Akka 如何决定哪个 Actor 获得线程?

Chrome 浏览器如何决定何时发送 OPTIONS?