tl;dr: 当浏览器/用户代理提交表单时,它以UTF-8格式提交(在我的测试中),但不包括此信息在HTTP请求中。用户代理如何决定使用UTF-8?应用程序代码(接收请求的代码)如何决定使用哪个字符集来解码传入的数据?
在过去的几天里,我一直在搜索互联网,以找出从浏览器发送到Web服务器时数据的编码方式。事实证明这是一个非常复杂的问题,因为在这个问题上没有明确的标准。
RFC2616(HTTP)基本上是基于ISO-8859-1和US-ASCII。但是存在扩展允许使用其他字符集(例如RFC2047)。 编辑: RFC2616已被RFC7231取代,后者已删除了有关ISO-8859-1的注释(请参见附录B)。
请求主体
基本上,当用户代理发送包含主体的请求时,问题似乎已经很好地定义了:使用包括charset
参数的Content-Type
头。例如:
Content-Type: text/plain; charset=utf-8
这在JavaScript中很容易实现。但今天,我遇到了一个问题,当使用HTML表单元素时,无法指定字符集。在搜索中,我遇到了这个SO问题,但我认为答案是错误的。它声称使用
accept-charset
属性。但从参考文献中可以看出,此标头用于告诉服务器客户端/用户代理可接受的字符集,而不是反过来。
相关的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中得到了明确定义。
参考文献: