后端为 Koa2 框架项目
前端为 Vue3 项目,使用 Axios 作为网络请求库。js-file-download。
效果演示
Kapture 2022-04-08 at 14.12.44
后端
routes/download.js
1 2 3 4 5 6 7 8 9 10 11 12 13
| router.get('/file', async (ctx, next) => { const file = fs.createReadStream( path.join(__dirname, `../public/template/测试文件.txt`) )
ctx.set({ 'Content-Disposition': `attachment;filename=${encodeURIComponent( '文件.txt' )}`, }) ctx.body = file })
|
前端
首先一个普普通通的按钮,定义一个点击事件。
1 2 3 4 5 6
| <template> <!-- 一个普通的点击事件 --> <button @click="downloadFile"> 点我下载 </button> </template>
|
如果你用最简单的那种,a标签形式src放上下载路径。然后后端直接静态文件路径。也是可以的。
a标签的下载有新标签页的开启或闪烁,体验不太好,所以更推荐使用下面这种。
事件响应里面,这样写!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <script setup> const downloadFile = async () => { const file_res = await axios.get('http://localhost:3000/download/file', { responseType: 'blob' }) // contentDisposition 中存储的是文件名信息。 const contentDisposition = file_res.headers['content-disposition'] // 解决中文乱码问题 const filename = decodeURI( contentDisposition.slice( contentDisposition.search('filename=') + 'filename='.length ) ) fileDownload(file_res.data, filename) } </script>
|
这样就好了,很简单。
哦对了,写完上面的,你可能会发现 file_res.headers
中没有 content-disposition
变量。
这个是由于koa2 端的默认跨域规则导致的。你需要在 koa2
的跨域配置进行一些修改。
我这边使用的是 koa2-cors
库 https://github.com/zadzbw/koa2-cors#exposeHeaders
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| app.use( cors({ origin: function (ctx) { if (ctx.url === '/test') { return false } return '*' }, exposeHeaders: [ 'WWW-Authenticate', 'Server-Authorization', 'Content-Disposition', ], maxAge: 5, credentials: true, allowMethods: ['GET', 'POST', 'DELETE', 'PATCH', 'PUT', 'OPTIONS'], allowHeaders: ['Content-Type', 'Authorization', 'Accept'], }) )
|
示例仓库地址:koa2端 vue端
相关参考