我的应用程序有一个上传组件,它成功地使用了 iFrame 中较旧的表单上传方法。我有一个 Ajax 投票,每 1000 毫秒返回一次上传进度。
我正在做功能检测并允许有能力的浏览器通过 xhr2 上传。理论上,我可以访问客户端的进度;无需轮询,进度条更新更流畅优雅!在批量上传结束时,我需要重定向到显示所有上传文件列表的页面。
您可以通过 xhr2 两种方式上传文件:每个文件都是自己上传的,或者您制作一个包含所有文件的“formData”对象。每个都有优点和缺点,我想我正在尝试两全其美,这可能是不可能的。对我来说,“两全其美”将满足以下要求:
- 能够随时显示单个文件的进度和文件名
- 发送包裹时能够显示“总进度”栏
- 在服务器端捕获文件的“包”,并在整个包完成后发回重定向。
这是单文件传输的示例代码。我可以轻松满足标准#1,并且可以通过一些努力为标准#2 编写代码。#3 有点问题,因为客户端只是将一堆单独的文件作为单独的传输发送。
function uploadFile(file) {
xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
//domNode.bar is a cached jQuery object
domNode.bar.css('width', (evt.loaded / evt.total) * 100 + "%");
console.log('my current filename is: ' + file.name;
}
else {
// No data to calculate on
}
}, false);
xhr.addEventListener("load", function() {
console.log("finished upload");
}, false);
xhr.open("post", remoteURL, true);
// Set appropriate headers
xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.setRequestHeader("X-File-Name", file.name);
xhr.setRequestHeader("X-File-Size", file.size);
xhr.setRequestHeader("X-File-Type", file.type);
// Send the file
xhr.send(file);
}
}
这是作为 formData 发送的示例代码。我现在根本无法满足标准#1……。我可以很容易地满足标准#2 和#3:
function uploadFile(form) {
xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
console.log(evt);
domNode.bar.css('width', (evt.loaded / evt.total) * 100 + "%");
// no longer have access to the file object
}
else {
// No data to calculate on
}
}, false);
xhr.addEventListener("load", function() {
console.log(xhr);
}, false);
xhr.open("post", remoteURL, true);
// Set appropriate headers
xhr.setRequestHeader("Content-Type", "multipart/form-data");
// Send the form
xhr.send(form);
}
}
// just assume that I've used formData.append to build a valid form object,
// which I have; and that this is triggered by a click event or something
uploadFile(form);
我并非完全没有选择,但在我继续实施之前,我只是想检查一下我没有遗漏任何东西。以下是我看到的选项:
继续只使用 Ajax 调用来取得进展。不太流畅,这与我们的设计目标背道而驰,但好处是我不需要使用 iFrame 进行上传,因为我有 xhr2 API。当流关闭时,我也会得到单个重定向。
迭代文件并在客户端进行一些繁重的工作以取得进展;除了单个文件进度条,我还可以创建一个算法来跟踪总进度。同时,我向服务器发送一个文件计数,并使用这个计数来推迟重定向 URL,直到最后一个文件到达,然后我可以发送它。
有什么想法吗?