当前位置: 首页 > 后端技术 > Node.js

Koa2的文件上传和下载

时间:2023-04-03 13:28:35 Node.js

前言上传和下载在web应用中是比较常见的,无论是图片还是其他文件。在Koa中,有很多中间件可以帮助我们快速实现功能。文件上传在前端上传文件,我们都是通过表单上传的,上传的文件不能像普通参数一样通过服务端的ctx.request.body获取到。我们可以使用koa-body中间件来处理文件上传,它可以将请求体放入ctx.request中。//app.jsconstkoa=require('koa');constapp=newkoa();constkoaBody=require('koa-body');app.use(koaBody({multipart:true,formidable:{maxFileSize:200*1024*1024//设置最大上传文件大小限制,默认为2M}}));app.listen(3001,()=>{console.log('koaislisteningin3001');})使用中间件之后,就可以在ctx.request.body.files中获取到上传的文件内容。需要注意的是设置了maxFileSize,否则一旦上传的文件超过默认限制就会报错。接收到文件后,我们需要将文件保存到目录中,并返回一个url给前端。node中的流程是创建可读流constreader=fs.createReadStream(file.path)创建可写流constwriter=fs.createWriteStream('upload/newpath.txt')将可读流写入可写流通过管道reader.pipe(writer)constrouter=require('koa-router')();constfs=require('fs');router.post('/upload',async(ctx){constfile=ctx.request.body.files.file;//获取上传的文件constreader=fs.createReadStream(file.path);//创建可读流constext=file.name.split('.').pop();//获取上传的文件扩展名constupStream=fs.createWriteStream(`upload/${Math.random().toString()}.${ext}`);//创建可写流reader.pipe(upStream);//通过管道将可读流写入可写流returnctx.body='uploadsuccessful';})该方法适用于上传图片、文本文件、压缩文件等文件下载koa-send是一个中间件用于静态文件服务,可用于实现文件下载功能。constrouter=require('koa-router')();constsend=require('koa-send');router.post('/download/:name',async(ctx){constname=ctx.params.name;constpath=`upload/${name}`;ctx.attachment(path);awaitsend(ctx,path);})前端下载有两种方式:window.open和表单提交。这里使用了一个更简单的window.open。立即下载这里window.open默认是打开一个新窗口,flash一下然后关闭。用户体验不好。你可以添加第二个参数window.open('/download/1.png','_self');这样就会直接在当前窗口下载。不过这是用url替换当前页面,会触发beforeunload等页面事件。如果你的页面监听了这个事件,做了一些操作,就会产生影响。那么你也可以使用一个隐藏的iframe窗口来达到同样的效果。立即下载批量下载批量下载和单次下载没有区别,只是多执行几次下载。这真的没问题。如果把这么多文件打包成一个压缩包,然后只下载这个压缩包,岂不是更好的体验?Filepackagingarchiver是Node.js中一个可以实现跨平台打包的模块,支持zip和tar两种格式。constrouter=require('koa-router')();constsend=require('koa-send');constarchiver=require('archiver');router.post('/downloadAll',async(ctx){//待打包文件列表constlist=[{name:'1.txt'},{name:'2.txt'}];constzipName='1.zip';constzipStream=fs.createWriteStream(zipName);constzip=archiver('zip');zip.pipe(zipStream);for(leti=0;i