关于文件的上传和下载,网上很多文档,但是阅读下来有很多问题;
- 你只能所搜到后端怎么写
- 你只能所搜到前端下载有哪几种方法
- 真正全栈实践的时候容易出现各种bug。导致文件下载不下来或者说下载乱码。
此外egg后端的documents文件夹虽然可以很方便的下载文件,但是也有一些问题:
- 如果多项目集成使用nginx进行转发的时候,会找不到文件
- 项目更新的时候往往documents文件夹容易被忽略,容易出现一下难以预料的bug
此文章提供一个简单的全栈解决问题的思路;
本文后端采用egg.js框架,前端采用vue.js。(本质思路是后端返回前端文件的二进制数据流,前端再做处理)
Egg代码
// controller 代码
const Controller = require("egg").Controller;
const fs = require('fs');
class initDataController extends Controller {
async downloadTemplateFile({ }, { ctx }) {
try {
// 文件路径,egg的文件路径默认是从项目的文件夹开始的。
// 如果想动态的获取不同的文件,可以根据传递的参数在这里拼出路径
const filePath = 'docs/一车一档导入模板.xlsx'
this.ctx.attachment(filePath);
// 设置请求头
this.ctx.set('Content-Type', 'application/octet-stream');
// 把数据流赋予body
this.ctx.body = fs.createReadStream(filePath);
} catch (error) {
return { state: 0 }
}
}
}
module.exports = initDataController;
egg的router一定要用post
vue.js
// 安装插件 js-file-download
npm install js-file-download --save
// 文件模板下载
async fileDownload() {
// 公司内部基于axios封装了一个请求方法,用axios也是一样的
// 第二参数是请求api的参数,例子是获取固定的文件,就不需要传参
// 若根据参数动态的返回文件,传递对应的参数即可
let res = await this.$curl.post('api/ydyvehicle/downloadTemplateFile', {},{responseType: 'arraybuffer' })
// 使用插件,第二个参数是文件名
fileDownload(res, '一车一档导入模板.xlsx')
},