当前位置: 首页 > Web前端 > HTML5

Nodejs文件上传,监控上传进度

时间:2023-04-05 21:57:59 HTML5

前言如果文件上传加上进度条,会有更好的用户体验(尤其是中大文件)。本文使用Nodejs配合前端来完成这个功能。在前端,我们使用FormData作为发送数据的载体。文章来自我的博客,会不定时更新。欢迎关注效果前端的HTML部分和Js部分//获取输入文件的dom对象constinputFile=document.querySelector('#file');//监听change事件inputFile.addEventListener('change',function(){//使用formData加载文件constformData=newFormData();formData.append('file',this.files[0]);//上传文件upload(formData);})接下来我们实现上传方法。XMLHttpRequest的使用方式constupload=(formData)=>{constxhr=newXMLHttpRequest();//监听文件上传进度xhr.upload.addEventListener('progress',function(e){if(e.lengthComputable){//获取进度constprogress=Math.round((e.loaded*100)/e.total);document.querySelector('#progress').setAttribute('value',progress);}},false);//监听上传完成事件xhr.addEventListener('load',()=>{console.log('?上传完成')},false);xhr.open('post','http://127.0.0.1:3000/upload');xhr.send(formData);}使用jQuery的ajax上传jQuery目前的使用量还是很大的,那么如何使用jQuery的ajax来监控文件上传的进度:constupload=(formData)=>{$.ajax({type:'post',url:'http://127.0.0.1:3000/upload',data:formData,//没有数据处理和内容处理processData:false,contentType:false,//监控xhrxhr:function(){constxhr=$.ajaxSettings.xhr();如果(xhr.upload){xhr.upload.addEventListener('progress',e=>{const{loaded,total}=e;varprogress=(loaded/total)*100;document.querySelector('#progress').setAttribute('value',进度);},错误);返回xhr;}},success:function(response){console.log('上传成功');}});}使用axios上传和监控进度axios用量很大,使用它监控文件上传比较简单,代码如下:constupload=async(formData)=>{letconfig={//注意设置contentType为multipart/form-dataheaders:{'Content-Type':'multipart/form-data'},//监听onUploadProgress事件onUploadProgress:e=>{const{loaded,total}=e;//使用本地进度事件if(e.lengthComputable){letprogress=loaded/total*100;document.querySelector('#progress').setAttribute('value',pr食人魔);}}};const{status}=awaitaxios.post('http://127.0.0.1:3000/upload',formData,config);if(res.status===200){console.log('上传完成?');}}Nodejs部分这部分比较简单,其实就是一个简单的文件上传,我们使用Koa来实现。环境搭建及依赖包安装这里使用koa2,安装如下依赖包:koa@koa/router:koa的路由@koa/cors:用于跨域koa-body:解析body数据nodemon:用于启动服务,with热更新代码部分constKoa=require('koa');constRouter=require('@koa/router');constkoaBody=require('koa-body');constpath=require('path');constfs=require('fs');constcors=require('@koa/cors');constapp=newKoa();constrouter=newRouter();router.all('/upload',asyncctx=>{//处理文件上传constres=awaitdealFile(ctx);res&&(ctx.body={status:200,msg:'complete'});});//中间件部分app.use(cors());app.use(koaBody({multipart:true,formidable:{maxFileSize:2000*1024*1024//最大2G}}));app.use(router.routes());app.use(router.allowedMethods());应用列表n(3000);出于性能考虑,dealFile方法处理上传的文件。毫无疑问,stream是用来操作文件的。我们需要监听文件流的结束事件。由于在事件回调中无法返回response,会报404,所以我们需要使用Promise来封装它,然后使用async,awaitconstdealFile=ctx=>{const{file}=ctx.request.files;constreader=fs.createReadStream(file.path);constwriter=fs.createWriteStream(//文件上传到path.resolve(__dirname,'./image',file.name));returnnewPromise((resove,reject)=>{reader.pipe(writer);reader.on('end',()=>{resolve(true);});reader.on('error',err=>{抛出错误;})});};这一切都在这里完成。这里注意:前端监控文件进度,后端没有做任何特殊处理,后端只写文件流。