效果图
前端代码,基于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"}); } }); } });