现在文件上传控件有很多,比如JQuery的jQuery File Upload等等。功能必须说,非常强大,官方文档写的也很清楚。要说缺点也只有一个,加载的文件很多(举例的这个光js就有4个,这对服务器来说是负担),通常在web开发中不需要这么多功能,本这对前端开发的优化,在加上现在html5的普及,自己写一个适合自己的控件非常有必要。
废话不多说,直接上代码
前端代码,其中已经有了注释了
<body>
<form id="upload">
<input type="file" id="files">
<input type="submit" name="submit">
</form>
<table>
<tr><td>文件名</td><td>上传进度</td></tr>
</table>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="upload.js"></script>
<script type="text/javascript">
//执行upload函数就开始上传了,假如要自动上传就改成$('input[type=file]').change(function(){//xhrData = upload({这里是各种参数});//});$('form').submit(function(){//注意 第一个是input file表单xhrData = upload($('#files'),{//上传地址url:'http://localhost/test/index.php',//准备上传触发函数 第一个基本没用 第二个是文件信息 第三个是文件的keyonStart:function(event,file,fileKey){var tpl = '<tr class="'+fileKey+'"><td>'+file.name+'</td><td>'+0+'</td><td><button class="abortBtn">中断上传</button></td></tr>';$('table').append(tpl);},//进度条显示 第一个参数存储了上传进度 第二个是文件信息 第三个存储了文件的keyprogress:function(event,file,key){if (event.lengthComputable) {var complete = Math.floor(event.loaded / event.total * 100);var progress = $('.'+key);progress.find('td:eq(1)').html(complete);}else{alert('无法确定上传文件的大小');}},//额外的参数 $_POST['name'] = 'testFile';data:{name:'testFile',id:'123',source:'ok'},//大小验证 size是大小 单位字节 后面的是超过大小的触发函数 文件信息 文件key//maxSize:{size:1000000,error:function(file,key){// alert('文件太大');// }},//文件类型验证 type是允许上传的类型数组 后面是不允许的文件上传时候 的触发函数 文件信息 文件key//fileType:{type:['jpg','iso','doc','doc'],error:function(file,key){// alert('文件类型不允许'+type);//}},//文件完成上传的触发函数 response是服务器响应内容(TEXT) file是文件信息 key是文件keycomplete:function(response,file,key){alert(response);},//文件上传失败触发函数error:function(file,key){alert('上传失败');},//中断按钮 这个必须被key元素包裹abortBtn:'.abortBtn',//当中断发生之后触发onAbort:function(file,key){alert(file.name+'已经停止上传')},});//假如input是在form里面需要return false;return false;});</script></body>
var upload = function(input){
if(window.FormData)
{
if(input.val() == '' || input.val() == 'undefined')
return false;
var files = input[0].files;//保存要上传的文件
var formData = new FormData();//文件上传通道
var fileReader = new FileReader();
var getFileType = function(filename){
var extStart = filename.lastIndexOf(".")+1;
return filename.substring(extStart,filename.length).toUpperCase();
};
var clearInput = function(){
input.val('');
};
var getKey = function(){//获得一个key 10位数字 这样可以保证几率比较小了 假如还想要几率小 可以计算md5
return Math.floor(Math.random()*10000000000);
};
var key = getKey();//保存文件的唯一key
var url = input.attr('data-url')||arguments[1].url;//上传地址
var progress = arguments[1].progress;//上传进度条
var complete = arguments[1].complete;//上传完成
var error = arguments[1].error;//上传失败
var maxSize = arguments[1].maxSize;//文件大小 单位字节 过滤器
var fileType = arguments[1].fileType;//文件类型 过滤器
var data = arguments[1].data;//额外数据
var onStart = arguments[1].onStart;//准备上传
var abortBtn = arguments[1].abortBtn;//中断上传按钮
var onAbort = arguments[1].onAbort;//中断函数
//文件类型验证
var type = getFileType(files[0].name);//获得文件类型
var typeAllow = false;
if(typeof fileType == 'object')
{
var arrayType = fileType.type;
$.each(arrayType,function(index,value){
if(value.toUpperCase() == type)
{
typeAllow = true;
return false;//相当于break
}
});
if(!typeAllow)
{
fileType.error(files[0],key);
return false;
}
}
//文件大小验证
if(typeof maxSize == 'number')
{
if(files[0].size >= maxSize)
{
maxSize.error(files[0],key);
return false;
}
}
else if(typeof maxSize == 'object')
{
if(files[0].size >= maxSize.size)
{
maxSize.error(files[0],key);
return false;
}
}
//将文件加入到上传通道
formData.append(input.attr('name')||'files', files[0]);
var xhr = new XMLHttpRequest();
//附加额外的数据
if(data != '' && data != 'undefined')
{
$.each(data,function(index,value){
formData.append(index,value);
});
}
//开始上传
xhr.open('POST',url,true);
xhr.onload = function(){
if(xhr.status == 200 && xhr.readyState == 4)
{
if(typeof complete == 'function')
complete(xhr.response,files[0],key);
//clearInput();
}
else
{
if(typeof error == 'function')
error(files[0],key);
}
};
xhr.upload.onprogress = function(event){
progress(event,files[0],key);
};
xhr.onloadstart = function(event){
onStart(event,files[0],key);
};
xhr.send(formData);
//添加中断
$('.'+key).find(abortBtn).click(function(){
xhr.abort();
onAbort(files[0],key);
});
return {key:key,xhr:xhr};
}
else
{
alert('浏览器版本过低');
return null;
}
}
暂时input元素中不支持multiple属性,我尝试过,js没办法获取到多个文件的信息,只能获取到一个,假如有知道的请给我留言,我随时改进
以上代码在chrome中测试通过
后台获取方式和正常的一样,对文件大小没有限制,假如有限制也是服务器软件或者后台语言的限制,在初始化参数中你可以设立上传的大小限制,