您的当前位置:首页正文

基于jquery ajax的多文件上传进度条过程解析

2020-11-27 来源:帮我找美食网

这篇文章主要介绍了基于jquery ajax的多文件上传进度条过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

效果图

前端代码,基于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="https://www.gxlcms.com/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>

后端代码,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"});
 }
 });
 }
});
显示全文