如果没有给出字符集,应该使用什么来解码multipart / form-data的默认编码? RFC2388声明:
4.5表单数据中的文本字符集
多部分/表格数据的每个部分应该具有内容 - 类型。在字段元素是文本的情况下,字符集 文本的参数表示使用的字符编码。
例如,带有文本字段的表单,用户在其中输入“Joe owes” < eu> 100',其中< eu>是欧元符号可能返回表单数据 为:
--AaB03x content-disposition: form-data; name="field1" content-type: text/plain;charset=windows-1250 content-transfer-encoding: quoted-printable>> Joe owes =80100. --AaB03x
在我的情况下,charset没有设置,我不知道如何解码该text / plain部分中的数据。因为我不想强制执行不是标准行为的事情,所以我在问这个案例中的预期行为是什么。 RFC似乎没有解释这一点,所以我有点迷失。
谢谢!
答案 0 :(得分:8)
这显然在HTML5中有所改变(见http://dev.w3.org/html5/spec-preview/constraints.html#multipart-form-data)。
生成的multipart / form-data资源中与非文件字段对应的部分不得指定Content-Type标头。
那么指定的字符集在哪里?据我所知,编码算法中唯一的位置是名为 _charset _ 的表单数据集条目。
如果您的表单没有名为 _charset _ 的隐藏输入,会发生什么?我在Chrome 28中对此进行了测试,发送了一个用UTF-8编码的表格和ISO-8859-1中的一个表格并检查发送的标题和有效负载,我没有看到任何地方都有字符集(即使文本编码肯定会发生变化)。如果我在表单中包含空 _charset _ 字段,Chrome会使用正确的字符集类型填充该字段。我想任何服务器端代码都必须查找 _charset _ 字段来解决它?
我在编写使用 FormData 对象的XMLHttpRequest.send的Chrome扩展程序时遇到了此问题,always gets encoded in UTF-8 no matter what the source document encoding is。
让请求实体体是运行multipart / form-data编码算法的结果,数据作为表单数据集,并使用utf-8作为显式字符编码。
令mime类型为“multipart / form-data;”的串联,U + 0020 SPACE字符,“boundary =”,以及multipart / form-data编码算法生成的multipart / form-data边界字符串
正如我之前发现的那样,在POST请求中的任何地方都没有指定charset = utf-8,除非你在表单中包含一个空的 _charset _ 字段,在这种情况下会自动填充“ UTF-8" 。
这是我对事物状况的理解。我欢迎对我的假设进行任何更正!
答案 1 :(得分:6)
HTTP 1.1的默认字符集是ISO-8859-1(Latin1),我猜这也适用于此。
3.7.1规范化和文本默认值
- 剪断 -
“charset”参数与某些媒体类型一起用于定义数据的字符集(第3.4节)。当发送方未提供显式字符集参数时,“文本”类型的媒体子类型被定义为在通过HTTP接收时具有默认字符集值“ISO-8859-1”。除“ISO-8859-1”或其子集之外的字符集中的数据必须用适当的字符集值标记。有关兼容性问题,请参见第3.4.1节。
答案 2 :(得分:2)
感谢@owlman的详细解释。
这里还有一些信息:
上传请求有效负载片段:
------WebKitFormBoundarydZAwJIasnBbGaUqM
Content-Disposition: form-data; name="file"; filename="xxx.txt"
Content-Type: text/plain
如果" xxx.txt"使用UTF-8编码有一些UNICODE字符,Resin(从4.0.40开始)无法正确解码,但Jetty(9.x)可以。
我认为Resin行为的原因是Content-type没有指定任何编码,因此Resin使用" ISO8859-1"解码文件名,这可能导致乱码。
我做了一些谷歌搜索:
似乎Resin的行为符合Servlet Spec 2.3
我无法从http://www.caucho.com/resin-4.0/reference.xtp找到任何设置 这可以改变Resin的这种行为。