我的应用程序上传了一个组件,它在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,直到最后一个文件到达,然后我可以发送它。
有什么想法吗?
答案 0 :(得分:1)
如果要在一个请求中发送所有文件,FormData是两者中唯一的选项。任何一个选项都可以覆盖1点和1点。 2.
由于您询问了其他API,我觉得提及我维护的跨浏览器上传工具是合理的:Fine Uploader。我的图书馆提供回调功能,让您轻松实现目标#1& #2。就#3而言,Fine Uploader在单独的请求中发送每个文件。但是,使用Fine Uploader的API来呈现“总进度”栏并不难。我在使用Fine Uploader的项目中做到了这一点。该库提供了一系列回调,并根据您指定的要点公开了一个对您有用的综合API。
请注意,Fine Uploader中的IE9及更早版本目前不提供上传进度,但您应该能够利用您的方法通过ajax调用显示进度。您的方法是一种可能的方法,但还有另一种可能的选项,计划在将来进一步审查:使用Apache / nginx的UploadProgress模块。请参阅功能请求#506。