浏览器在发送请求时如何决定使用哪个字符集?以及我们应该如何处理它?
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 元素的文档的字符编码。
【讨论】:
以上是关于浏览器在发送请求时如何决定使用哪个字符集?以及我们应该如何处理它?的主要内容,如果未能解决你的问题,请参考以下文章