当在表单中包含文件输入时,编码变得混乱

时间:2011-03-12 23:23:57

标签: jquery servlets encoding file-upload

当我在表单中包含文件输入时,我遇到了来自表单元素的输入编码问题。我正在使用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);
        }
    });

任何人都有使用此插件的经验吗?

3 个答案:

答案 0 :(得分:3)

  

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

你是说Firebug吗?您是否正在查看Firebug中的Net登录中的“帖子”选项卡?

因为如果是这样,它的作用是查看整个表单提交上传,并尝试解码它 - 包括任何上传文件的字节内容 - 如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开头的边界字符串。

答案 1 :(得分:1)

答案 2 :(得分:0)

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

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