4

我正在使用 HTML5 文件 API 来组装多部分表单数据,以通过 XHR 提交到 Web 服务。我在 FF 中完成了所有工作,它在文件 API 的实现中包含了一个非常方便的 getAsBinary() 方法。这是一笔非常甜蜜的交易。它基本上去了:

var const;  // constructor
const += headers;
const += field_data;

for(var i = 0; i < files.length; i++)
{
   const += files[i].getAsBinary();
}

sendData(const);

像魅力一样工作。

不过,要让它在 Chrome 中工作,我必须创建一个 FileReader 对象,它的处理方式略有不同。我基本上必须去:

var const;  // constructor
const += headers;
const += field_data;

var reader = new FileReader();

for(var i = 0; i < files.length; i++)
{
    reader.onload = (function(file)
    {
       const += file.target.result;   // const is not in scope in this anonymous function!
    }
    reader.readAsBinaryString(files[i]);
}

sendData(const);

这不起作用,主要有两个原因。首先,读取是异步发生的,所以当它到达 sendData() 函数时,文件数据并没有写入 const 变量。其次, const 变量超出了 reader.onload 处理程序的范围。然而,我重新编写代码,我似乎遇到了这些障碍之一,我正在努力想出一种优雅的方式来处理它。

有什么建议么?

4

2 回答 2

3

你要做的是让阅读器“加载”处理程序都检查它们是否是最后一个运行的处理程序。发生这种情况时,该处理程序可以调用“sendData()”。

var const;  // constructor
const += headers;
const += field_data;

var reader;
var finished = 0;
for(var i = 0; i < files.length; i++)
{
    reader = new FileReader();
    reader.onload = function(file)
    {
       const += file.target.result;
       if (++finished === files.length)
         sendData(const);
    };
    reader.readAsBinaryString(files[i]);
}

(我不完全了解累积的“const”事物如何正确变成多部分 MIME blob 的详细信息,但我认为您会这样做:-) 另外,这可能很重要:我认为您可能需要制作每个文件都有一个新的“FileReader”实例。我是这样编码的(实际上我只是编辑了它),但这可能是不正确的,因为我对 API 及其语义不太熟悉。

于 2011-03-19T14:44:58.573 回答
1

你考虑过xhr.send(FormData)吗?在这里查看我的回复:从 chrome 扩展上传到 php $_FILE

您可以将文件附加到 FormData 对象并通过 xhr 发送。浏览器为您构建多部分请求。我相信这在 FF4 中可用,并且已经在 Chrome 中使用了一段时间。

于 2011-05-18T17:18:44.387 回答