1.0 前言
文件下载这个功能在日常开发过程中会经常用到,这里我们一起学习 在 Koa 中如何做文件下载。
2.0 源码实现文件下载
本质上浏览器下载是把文件流放到 body 中,然后修改 Content-disposition 请求头,源代码如下:
// router.js
router.get('/download/:name', async (ctx) => {
const name = ctx.params.name
const filePath = path.resolve(process.cwd(), `static/upload/${name}`) // 获取文件目录
ctx.set('Content-disposition', 'attachment;filename='+name)
ctx.body = fs.createReadStream(filePath)
ctx.attachment(filePath)
})
现在我们在 static/upload 这个目录下,放了一个 222.png 的图片,启动项目,浏览器访问 http://localhost:300/222.png ,就会触发浏览器的下载。
大家可以看到,几行代码就实现了下载功能,那这么常见的功能,社区肯定也有对应的中间件,最常用的 就是 koa-send,接下里我们讲讲 koa-send 的使用
3.0 koa-send
3.0.1 安装
npm i koa-send --save
3.0.2 文件下载
// router.js
const send = require('koa-send')
router.post('/download/:name', async (ctx){
const name = ctx.params.name
const path = `static/upload/${name}`
ctx.attachment(path)
await send(ctx, path)
})
这样访问 http://localhost:300/222.png 也会触发下载,这个中间件用起来还是非常简单的。
4.0 批量下载
有时候我们文件比较多,比如,图片太多,希望打包后下载。
archiver
是一个在 Node.js 中能跨平台实现打包功能的模块,支持 zip 和 tar 格式。
router.get('/downloadAll', async (ctx) => {
// 将要打包的文件列表
const zipName = '1.zip'
const zipStream = fs.createWriteStream('1.zip')
const zip = archiver('zip')
zip.pipe(zipStream)
zip.directory('static/upload/', false) // 添加整个文件夹到压缩包
await zip.finalize()
ctx.attachment(zipName)
await send(ctx, zipName)
})
浏览器访问 http://localhost:3000/1.zip ,会把 upload 目录下的文件打包下载
5.0 小结
这节我们一起学习在 Koa 中文件下载的几种方式,大家可以对着Demo 跑起来,看看效果 Demo 地址。