一个multipart/form-data的HTTP POST请求中如何指定字符编码?

18
HTML 5 规范描述了一种算法(algorithm),用于选择在多部分表单提交(例如 UTF-8)中要使用的字符编码。但是,不清楚所选编码应如何传递到服务器,以便可以在接收端正确解码内容。
通常,通过将“charset”参数附加到请求头Content-Type的值来表示字符编码。然而,这个参数似乎没有为multipart/form-data MIME类型定义。

https://www.rfc-editor.org/rfc/rfc7578#section-8

每个多部分表单提交中的部分都可以提供自己的Content-Type头; 然而,RFC 7578指出,“实际上,许多广泛部署的实现并没有在每个部分中提供charset参数,而是依赖于multipart / form-data实例的‘默认字符集’概念”。
RFC 7578建议使用隐藏的“_charset_”表单字段来实现此目的。 然而,Safari(9.1)和Chrome(51)似乎都没有填充此字段,也没有提供任何每个部分的编码信息。
我查看了两个浏览器生成的请求头,没有看到任何明显的字符编码信息。 有人知道这些浏览器如何将此信息传达给服务器吗?
1个回答

11

HTML 5使用RFC 2388(已被RFC 7578取代),但HTML 5 明确地从非文件字段中删除了Content-Type头,而RFC则没有:

与非文件字段相对应的生成的multipart/form-data资源的部分不得指定Content-Type头。它们的名称和值必须使用上面选择的字符编码进行编码(特别是字段名不能转换为RFC 2388建议的7位安全编码)。

RFC旨在允许 multipart/form-data 在除HTML之外的其他上下文中使用(尽管HTML是最常见的用途)。在那些其他情况下,允许使用Content-Type。只是在HTML 5中不允许,但在HTML 4中允许。

没有Content-Type头,如果存在隐藏的_charset_表单字段,则HTML 5 <form>提交者可以通过它来明确地说明使用的字符集。

根据您提供的HTML 5算法规范,选定的字符集必须从<form>元素的accept-charset属性中选择,否则如果HTML本身与ASCII兼容,则使用HTML本身使用的字符集,否则使用UTF-8。这在算法规范中明确说明,也在RFC 7578第5.1.2节中关于HTML 5时明确说明。

因此,Web浏览器没有必要显式声明字符集,因为表单提交的接收者应该通过创建<form>的方式知道将要使用哪些字符集,因此在解析提交时可以检查这些字符集。如果接收方想知道使用的特定字符集,则需要在<form>中包含一个隐藏的_charset_字段。


1
网页浏览器实际上没有必要明确声明字符集,因为表单提交的接收者应该根据<form>的创建方式知道期望的字符集。这实际上是我的问题的基础。服务器如何知道表单是如何创建的?表单声明本身不会被提交到服务器 - 只有输入到表单中的数据。如果不是通过隐藏的_charset_参数,那么accept-charset属性的值如何传播到服务器? - Greg Brown
如果没有_charset_,HTML的编写者和表单接收者(如果他们不是同一个人)需要在服务器端协调。accept-charset应该只包含接收者准备处理的字符集。Web服务器应该配置为知道HTML提供的字符集。Web浏览器提交表单时只有两种方式可以传递字符集,即Content-Type_charset_,但HTML 5禁止使用Content-Type - Remy Lebeau
好的。这也是我得出的结论。感谢您详细的回复。 - Greg Brown

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