【问题标题】:encoding gets messed up when including file input in form在表单中包含文件输入时,编码会变得混乱
【发布时间】:2011-07-14 06:20:46
【问题描述】:

当我在表单中包含文件输入时,表单元素的输入编码被弄乱了。我正在使用 jquery 和 servlet 后端(和 ajax 调用),但我不明白这应该与它有什么关系。 HTML 页面编码设置为 UTF-8,我指定 servlet 请求的字符编码也使用 utf8。当我从表单中删除文件输入时,编码就可以了。

当我调查请求的标头时,我在 firebug 中看到以下有效负载:

...
------WebKitFormBoundaryMxjJWBwBmPLxN623
Content-Disposition: form-data; name="createActivityTitleInputId"

æøåæøåæøåæøå
...

输入的内容应该是æøåæøåæøå,不知道webkitformboundary的东西是什么……?

如果有人能帮我解决这个问题,我将不胜感激。

谢谢:)

----- 编辑------

所以我做了一个小测试项目来尝试缩小问题的范围。当我不使用 ajax 发布表单时,一切正常。但是,如果我使用 jQuery 表单插件提交表单,则编码失败...

form.ajaxSubmit({ 
        dataType: 'json',
        data: data,
        type: 'POST',
        success: function(response) {
            successfunction(response);
        }
    });

有人使用过这个插件吗?

【问题讨论】:

  • 可能是个愚蠢的问题,但您的<form> enctype 设置为?
  • 没关系,我在问题中看到了form-data
  • 你用什么来解析multipart/form-data请求? Apache Commons FileUpload,我猜?边界的东西只是 RFC2388 的一部分,对我来说看起来不错。提交的输入显然错误地编码为 ISO-8859-1 而不是 UTF-8。然而,尚不清楚是客户端错误地执行了此操作(尝试不同的浏览器),还是只是您自己将提取的 UTF-8 字符打印到错误使用 ISO-8859-1 的某些输出中。

标签: jquery servlets encoding file-upload


【解决方案1】:

当我调查请求的标头时,我在 bugzilla 中看到以下有效负载:

你是说萤火虫吗?您是否正在查看 Firebug 中网络日志中的“帖子”选项卡?

因为如果是这样,它的作用就是查看整个表单提交上传,并尝试将其解码(包括任何上传文件的字节内容)为 UTF-8。如果失败,它将回退到区域设置默认编码,通常是 Windows 代码页 1252(类似于 ISO-8859-1),以显示表单提交内容。

这不会改变表单的实际提交方式!这只是 Firebug 的可视化。 Firebug 实际上并不知道使用什么字符编码来编码表单内容,它只是猜测。一般来说,表单提交不携带任何信息让服务器(或 Firebug)知道正在使用什么编码。

因此,如果您提交的表单没有上传文件,或者上传的文件内容本身是有效的 UTF-8 序列(包括任何仅 ASCII 的文件),Firebug 会将整个表单提交显示为 UTF- 8 等将发布的内容显示为您期望的字符。另一方面,如果文件字节中的序列不是有效的 UTF-8 序列(对于任何二进制文件,例如图像,这很可能确实如此),Firebug 将尝试将字节解码为UTF-8,失败,回退到 cp1252。

这将为您显示“æøåæøåæøåæøå”,即使实际服务器会将其读取为 UTF-8并得到“æøåæøåæøå”。 Firebug 不知道文本表单提交值(字符)和文件上传提交内容(字节)之间的区别;它们也可能表示字符,但如果是这样,则不能保证上传的文件将使用相同的编码作为形式)。

我不知道 webkitformboundary 的东西是什么...?

在 MIME multipart/ 结构中,有一个分割每个子部分的边界字符串。在multipart/form-data 中,每个子部分都是一个表单字段。边界字符串总是以换行符开头,然后是--,但随后会选择一个任意字符串作为边界,通常涉及随机字符序列,不太可能出现在子部分本身的数据中。

边界字符串可以是任何东西,并在Content-Type: multipart/form-data;boundary= 参数中指定。 WebKit 浏览器总是使用以----WebKitFormBoundary 开头的边界字符串。

【讨论】:

  • mean firebug off course :) 当从表单中删除文件输入时,firebug 中的显示工作正常。此外,我不需要上传任何文件以使编码变得混乱。当文件输入的内容发生变化时,使用ajax完成文件上传..
  • 另外,后端的 servlet 将收到编码错误的内容(获取 æøåæøåæøåæøå)
  • 哦,你使用的是“ajaxSubmit”?一般来说,使用直接 AJAX 提交文件上传字段是不可能的。查看 ajaxSubmit 的代码,它所做的只是提交到 iframe 目标,而不是使用 AJAX 做任何事情。当文件上传字段存在时,这是一个完全不同的代码路径。 (它也看起来有点像一个错误的代码路径,但这是一个不相关的问题。)
  • 无论哪种方式,您都可以通过使用 Wireshark 之类的东西来更好地了解提交的内容,它会向您显示单独的字节,而不是尝试执行字符解码步骤。这应该让您看到实际上使用的是什么编码,因此前端和/或后端是否做错了什么。
【解决方案2】:

【讨论】:

    【解决方案3】:

    好的...所以我做了一个解决方法。我没有使用 ajaxsubmit 发布表单,而是使用 jquery ajax 功能并将每个表单元素值手动添加到 ajax 请求的数据部分。这似乎可以解决问题。

    $.ajax({
            type: 'POST',
            url: action,
            data: params,
            dataType: 'json', 
            success: function(response, textStatus, XMLHttpRequest) {
                successfunction(response);
            }
        });
    

    【讨论】:

      猜你喜欢
      • 2013-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-25
      • 1970-01-01
      • 2014-12-30
      相关资源
      最近更新 更多