commons-fileupload结合XMLHttpRequest实现有进度条上传功能

之前找了很多关于更新文件上传进度条的资料,其大部分都是不断向后台获取数据实现更新的!
现在,我们使用commons-fileupload结合XMLHttpRequest实现,客户端Ajax更新上传进度,免去不断向服务器端获取数据,而影响效率。

这里使用Ext.MessageBox,实现最终效果
[img]http://dl.iteye.com/upload/picture/pic/78186/fccf04d6-d7d7-3604-8e5a-a57342643c89.jpg[/img]

首先是通过使用Extjs官方提供的Ext.ux.form.FileUploadField结合commons-fileupload实现文件上传,我以前做了一篇关于实现这个功能的详细说明,这里就重复。如有需要,请看[url]http://jayklin.iteye.com/blog/841602[/url]

在这一篇中,主要想探讨一下如何commons-fileupload和XMLHttpRequest协同工作,实现上传进度显示。

据我所知,XMLHttpRequest.send()方法只能向服务端发送文本信息,而对于二进制文件,需要做编码处理(没有深入研究!)。所以,如果直接用这个方法实现上传,可能需要的工作量会很大。但我们可以利用它实现客户端的上传进度条的更新!

在XMLHttpRequest中,有个onreadystatechange事件句柄。每次 readyState 属性改变的时候调用的事件句柄函数。当 readyState 为 3 时,它也可能调用多次。ps:readyState有5个状态:[table]
|0| Uninitialized| 初始化状态。XMLHttpRequest 对象已创建或已被 abort() 方法重置。
|1| Open| open() 方法已调用,但是 send() 方法未调用。请求还没有被发送。
|2| Sent| Send() 方法已调用,HTTP 请求已发送到 Web 服务器。未接收到响应。
|3| Receiving| 所有响应头部都已经接收到。响应体开始接收但未完成。
|4| Loaded| HTTP 响应已经完全接收。
[/table]
所以可以利用当readyState=3时,多次调用onreadychange事件实现进度条更新。

而主要实现,请看代码:
upload: function(id, params){
var file = this._files[id],
name = this.getName(id),
size = this.getSize(id);

if (!file){
throw new Error('file with passed id was not added, or already uploaded or cancelled');
}

var xhr = this._xhrs[id] = new XMLHttpRequest();
var self = this;

xhr.upload.onprogress = function(e){
if (e.lengthComputable){
self._options.onProgress(id, name, e.loaded, e.total);
}
};

xhr.onreadystatechange = function(){
// the request was aborted/cancelled
if (!self._files[id]){
return;
}
if (xhr.readyState == 4){

self._options.onProgress(id, name, size, size);

if (xhr.status == 200){
var response;

try {
response = eval("(" + xhr.responseText + ")");
} catch(err){
response = {};
}

self._options.onComplete(id, name, response);

} else {
self._options.onComplete(id, name, {});
}

self._files[id] = null;
self._xhrs[id] = null;
}
};

// build query string
var queryString = '?qqfile=' + encodeURIComponent(name);
for (var key in params){
queryString += '&' + key + '=' + encodeURIComponent(params[key]);
}

xhr.open("POST", this._options.action + queryString, true);
xhr.send(file);
}

上面是定义一个upload方法。当执行send()方法后,readyState变为3。发送文件过程中不断调用xhr.upload.onprogress
而在Ext.form.FormPanel的beforeaction这个事件响应的时候,执行以下代码:
var xhrhandler = new uploadprogress.UploadHandlerXhr({
action: "do-nothing.htm",
onProgress: function(id, fileName, loaded, total){
// is only called for xhr upload
this._updateProgress(id, loaded, total);
},
onComplete: function(id, fileName, result){
},
_updateProgress: function(id, loaded, total){
if(loaded == total){
Ext.MessageBox.hide();
}else{
var i = loaded/total;
Ext.MessageBox.updateProgress(i, Math.round(100*i)+'% completed from '+uploadprogress.formatSize(total));
}
}

});

var id = xhrhandler.add(files[0]);
xhrhandler.upload(id,{});


以上便能实现在客户端更新上传文件进度。附件fileuploadprogress源文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值