写一个基于HTML5的文件异步上传控件

现在文件上传控件有很多,比如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>


upload.js代码

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中测试通过

后台获取方式和正常的一样,对文件大小没有限制,假如有限制也是服务器软件或者后台语言的限制,在初始化参数中你可以设立上传的大小限制,


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Uploader是非常强大的异步文件上传组件,支持ajax、iframe、flash三套方案,实现浏览器的全兼容,调用非常简单,内置多套主题支持 和常用插件,比如验证、图片预览、进度条等,广泛应用于淘宝网,比如退款系统、爱逛街、二手、拍卖、我的淘宝、卖家中心、导购中心等。 Uploader的特性 支持ajax、flash、iframe三种方案,兼容所有浏览器。(iframe不推荐使用) 多主题支持,可以自己定制主题 丰富的插件支持 支持多选批量上传 支持上传进度显示 支持取消上传 支持图片预览(使用flash上传不支持) 支持上传验证 1.4的改进 详细的changlog请看README.md。 1.4相对于1.3,功能上增强不多,但接口做了大量的改进,不兼容旧版的uploader,用起来比以前爽多了,同时提供更大的定制空间。 Uploader继承于RichBase,跟kissy的其他官方组件在API上保持一致。 如果你的应用是基于kissy1.3,请使用Uploader1.4。 demo汇总 简单demo:js配置上传组件 简单demo:属性配置上传组件 上传验证控制的demo 组件全部事件演示 渲染默认队列数据的demo 队列全部方法演示 只使用flash上传的demo 只使用iframe上传的demo 常用方法控制 组件内置的主题 图片上传主题 主题 作者 源码 截图 imageUploader 明河 源码 refundUploader 明河 源码 loveUploader 苏河/明河 源码 singleImageUploader 溪夏/明河 源码 文件上传主题 主题 作者 源码 截图 default 明河 源码 daogouUploader 溪夏/明河 源码   Uploader的使用请看使用指南,里面有详细的说明,这里不再累述。 标签:Uploader
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值