代码改变世界

基于jquery ajax的多文件上传进度条

2018-02-09 16:02  muamaker  阅读(1871)  评论(0编辑  收藏  举报

效果图

前端代码,基于jquery

 

<!DOCTYPE html>
<html>
  <head>
    <title>主页</title>
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
  	<style type="text/css">
  			*{
  				padding: 0;
  				margin: 0;
  			}
  			table{
  				width: 600px;
  				text-align: center;
  			}
  	</style>
  </head>
  <body>

    	<input type="file" id="imgsend" name="file" value="发送图片" multiple="multiple" /> 
			<table border="1" cellspacing="0" cellpadding="0">
				<thead>
					<tr>
						<td>名称</td>
						<td>大小</td>
						<td>进度</td>
						<td>结果</td>
					</tr>
				</thead>
				<tbody>
					<!-- <tr>
					 		<td>xxx</td>
					 		<td>100</td>
					 		<td class="per">100%</td>
					 		<td class="result">成功</td>
					 </tr>-->
				</tbody>
			</table>
  </body>
  <script type="text/javascript" src="/javascripts/jquery.js"> </script>
  
  <script type="text/javascript">
  	
  ;(function($){
  	 $.fn.extend({
				uploadFile:function(option){
					var that = this;
					var defau = {
						type:"post",
						cache:false,
						url:"",
						data:{},
						processData:false,
						contentType:false,
						success:function(){},
						error:function(){},
						progress:function(){},
						sendBefore:function(){},
						filter:[],  //可以接受的文件后缀
						upName:true //是否对文件名称转化大写比对
						
					}
					option = $.extend(true, defau, option);
					
				 var	fileP = that.attr("name") || "file";  //传给后端得 file对应字段
					console.log(fileP)
					var files = that[0].files;
					
					option.sendBefore(files);  //发送之前
					
					for(var i = 0,len = files.length; i < len; i++ ){
						 var fs = files[i];
						 var fnameArr = fs.name.split('.');
						 var fNmae = fnameArr.pop();
						 var str = '';
						 if(option.upName){
						 		fNmae = fNmae.toUpperCase();
						 }else{
						 		fNmae = fNmae.toLowerCase();
						 }
						 if(option.filter.length > 0 && option.filter.indexOf(fNmae) !== -1){
								option.error("文件后缀不符",i);	 
								continue;
						 }
						 fileUpload(files[i],i);
						
					}
					
					//开始文件上传
					function fileUpload(file,index){
						 var fd = new FormData();
						 fd.append(fileP,file);
						 
						 //追加其他参数
						 for(var i in option.data){
						 		fd.append(i,option.data[i]);
						 }
						 
						 $.ajax({
						 	url: option.url,
						 	type: option.type,
						  data: fd,
						  cache: option.cache,
						  processData: option.processData,
						  contentType: option.contentType,
						 	success:function(data){
						 		option.success(data,index);
						 		
						 	},
						 	error:function(error){
						 		console.log(error);
						 		option.error(error,index);
						 	},
						 	xhr: function(){
							    var xhr = $.ajaxSettings.xhr();
							    if(onprogress && xhr.upload) {
							     xhr.upload.addEventListener("progress" , onprogress, false);
							     return xhr;
							    }
			   			} 
						 });
						 
						function onprogress(evt){
							var loaded = evt.loaded;     //已经上传大小情况 
						  var tot = evt.total;      //附件总大小 
						  var per = Math.floor(100*loaded/tot);  //已经上传的百分比 
							file.loaded = loaded;
							file.total = tot;
							file.percent = per + '%';
							file.index = index;
							option.progress(file);
						} 
					}
					return that;
				}
  	 });
  	
  })($,window);

	//发送图片
	
	var $table = $("table tbody");
	
	$("#imgsend").on('change',function(){
		var that = this;
		
		 $(that).uploadFile({
		 	url:"/api/file",
		 	data:{},
		 	filter:[],  //后缀文件筛选
		 	sendBefore:function(files){
		 		  //开始之前
		 		  console.log(files);
		 		  var str = '';
		 		  for(var i = 0; i < files.length; i++){
		 		  	var item = files[i];
		 		  	str += '<tr>'+
						 		'<td>'+ item.name +'</td>'+
						 		'<td>'+ FormatSize (item.size) +'</td>'+
						 		'<td class="per">0</td>'+
						 		'<td class="result"></td>'+
					 		'</tr>';
		 		  }
		 		  
		 		  $table.html(str);
		 		  
		 	},
		 	success:function(data,index){
		 		  //某个文件传完
		 		var $tr =  $table.find('tr').eq(index);
		 		$tr.find('.result').html("成功");
		 	},
		 	error:function(err,index){
		 		//某个文件报错
		 		$tr.find('.result').html("失败");
		 	},
		 	progress:function(file){
		 		//某个文件的上传进度
		 		
		 		// file.loaded  已经上传的
		 		// flie.total  总量
		 		// file.percent  百分比
		 		// file.index   第多少个文件
		 		var $tr =  $table.find('tr').eq(file.index);
		 		$tr.find('.per').html(file.percent);
		 		console.log(file.name + ":第" + file.index + '个:' + file.percent);
		 	}
		 	});
	});
	
		
	//文件大小格式化
function FormatSize (fileSize) {  
    var arrUnit = ["B", "K", "M", "G", "T", "P"],  
        baseStep = 1024,  
        unitCount = arrUnit.length,  
        unitIndex = 0;                    
    while(fileSize >= baseStep && unitIndex < unitCount - 1){  
        unitIndex++;  
        fileSize /= baseStep;  
    }  
    fileSize = fileSize.toFixed(2);  
    return fileSize + " " + arrUnit[unitIndex];  
}  
	
  </script>
 
</html>

  

  2、后端代码,nodejs+express

const multiparty = require('multiparty');
var fs =require("fs");

router.post('/api/file', function(req, res, next) {
	//生成multiparty对象,并配置上传目标路径
    const form = new multiparty.Form()
    // //设置编辑
    form.encoding = 'utf-8'
    // //设置文件存储路径
    form.uploadDir = "./public/static/files/"
    // //设置单文件大小限制
    //form.maxFilesSize = 2 * 1024 * 1024
    // form.maxFields = 1000;  设置所以文件的大小总和
    // 上传完成后处理

    
    form.parse(req, (err, fields, files) => {
      if (err) {
      	console.log("parse:",err);
        res.json({"success":"error"});
      } else {
        const inputFile = files.file[0];
        const uploadedPath = inputFile.path
        const imgtype = inputFile.originalFilename;
        const inPath = `./public/static/files/${imgtype}`; //重命名的路径
        // 判断是否存在./dist/static/files文件
        fs.stat('./public/static/files', (err, stats) => {
          if (JSON.stringify(stats) === undefined) {
            fs.mkdirSync('./public/static', 0777)
            fs.mkdirSync('./public/static/files', 0777)
          }
          storeFiles(uploadedPath, fields, inPath)
        });
      }
    });
    
    function storeFiles(uploadedPath, fields, inPath) {
      //重命名为真实文件名
      fs.rename(uploadedPath, inPath,  (err) => {
        if (err) {
        	console.log("rename:",err);
         	res.json({"success":"error"});
        } else {
					res.json({"success":"hahha"});
        }
      });
    }
  
});