创建您自己版本的输入[type=file]

Creating your own version of input[type=file]

本文关键字:type file 输入 自己 版本 创建      更新时间:2023-09-26

我有一个有趣的问题,我正在努力解决,不知道你们谁能帮我一下。

我正在构建一个小工具,允许用户将文件拖放到CMS中。虽然我已经得到了拖放部分工作良好(使用新的HTML5 api),但我被困在文件上传应该如何工作方面,特别是因为我的约束是我不能修改任何服务器的功能。我看过所有其他的例子,它们都有相对简单的用例,它们只是发送文件数据,而不必将所有内容转换为multipart/form-data等。

目前,服务器有一个简单的表单,看起来有点像这样:

Name: [ input=text ]
File: [ input=file ]
Caption: [ textarea ]

当用户点击"保存"按钮时,会发出内容类型为multipart/form-data的POST调用。

最初我认为我可以用我自己的隐藏控件替换当前的输入控件(使用相同的"name"属性),并且只是将base64编码的数据作为"值",但是CMS期望传递一个"文件名",这通常是由input=file处理的。例如,最后一个帖子看起来像这样:

Content-Disposition: form-data; name="image_0"; filename="assets.jpg" 
Content-Type: image/jpeg
<Some binary image data here>

我是不是完全走错路了?我应该只使用XHR对象吗?

欢呼

我算出来了。

以下是我所做的和我的参考:

  • 使用jQuery.ajax发送multipart/formdata
  • https://developer.mozilla.org/En/Using_XMLHttpRequest Using_FormData_objects
  • https://developer.mozilla.org/en/DOM/File

我不得不使用FormData对象(在Firefox 4+, Safari 5+和Google Chrome中可用),当然还有FileReader对象。

下面是实现(使用jQuery):

// The file object needs to come from the "drop" event and is read by the "FileReader" object with the readAsBinaryString() function.
// var file = null;
var data = new FormData();
$("#main_form input:not([type=file])").each(function(){
    data.append($(this).attr("name"), $(this).val());
});
data.append("image_0", file);
$.ajax({
    url: $("#main_form").attr("action"),
    type: "POST",
    data: data,
    processData: false,
    contentType: false
});

目前IE不是一个问题,但很快就会(因为我需要将这个扩展移植到IE)。对于IE来说,是否有更好的方法来做到这一点?

我可能搞错了,但我相信没有办法将文件上传ajax化。你的选择要么是像Flash或Java这样的插件,要么是一个时髦的基于框架的解决方案,其中上传发生在一个单独的框架中。我认为你在那里找到的任何"AJAX"文件上传控件都使用了这些方法之一。

最简单的方法显然是将整个表单发布到服务器,但这对我来说太2005了。