Koa 2框架中接收文件,实现文件上传
文件上传这个操作是非常非常常用的,如果是使用JS直接写一个文件上传的代码的代码量是巨大的,且不容易理解,这里我也是在网上查了很久,可以使用
koa-multer
插件来实现文件上传
传统的文件上传
-
我过去的做法是先将然后文件全部转码成Base64的一长串字符串,将这一长串字符串传给后端,后端再根据字符串,使用
Buffer.from
逆解析,最终将图片保存在服务器上,我自己理解的这样的作法有以下的几点不好。- 因为是将整个Base64字符串传递给后端,就会造成一个接口传递的数据量是500k上下甚至1M,极其的消耗性能
- 需要做逆解析,使用path模块保存图片,等等操作,代码量极其的繁琐。
-
但是我还是写出来了,代码量过于庞大,这样写和脑溢血没有区别:
const router = require('koa-router')() const fs = require('fs') const { resolve } = require('path') // 获取目录,目的是方便后期存储 router.get('/getDir', async ctx => { let objPath = resolve(__dirname, '../static') let dir = fs.readdirSync(objPath) ctx.body = { code: 200, message: '请求成功', result: dir } }) router.post('/getImgs', async ctx => { let imgComponents = [] let objPath = resolve(__dirname, '../static') fs.readdirSync(objPath).map(item => { let json = {} json.name = item let newPath = resolve(objPath, item) let anser = fs.readdirSync(newPath) json.url = anser imgComponents.push(json) }) // map和forEach的区别 都是遍历数组元素 map会直接影响本身 imgComponents.map(item => { item.url.map(function (items) { this.items = 'http://127.0.0.1:666/' + items }) }) ctx.body = { code: 200, message: '请求成功', result: imgComponents, } }) // 上传的关键性代码 router.post('/uploadImgs', async ctx => { let { filename, files } = ctx.request.body // console.log(filename, files) try { files.map(item => { let extend = '.' + item.imgname.split(';')[0].split('/')[1] let img = Buffer.from(item.imgsrc, 'base64') let imgname = `${Date.now()}${extend}` let imgpostiton = resolve(__dirname, `../static/${filename}/${imgname}`) fs.writeFileSync(imgpostiton, img) }) } catch { ctx.body = { code: 0, message: '添加失败' } } ctx.body = { code: 200, message: '请求成功' } }) // 删除 router.post('/delImg', async ctx => { let { dir, filename } = ctx.request.body // console.log(dir, filename) let objdir = resolve(__dirname, `../static/${dir}/${filename}`) // console.log(objdir) try { fs.unlinkSync(objdir) } catch { ctx.body = { code: 0, message: '删除失败' } } ctx.body = { code: 200, message: '操作成功' } }) module.exports = router.routes()
使用koa-multer
插件实现
现在我们上传文件一边前后台都会使用插件,如前台我们使用element-UI,后台使用koa-multer
-
前台传递给后台的数据类型是file - (binary)
因为是file的二进制数据流,所以使用Koa框架的时候是没有办法直接在
ctx.request.body
中获取的,就需要使用koa-multer
插件注入到路由中,在路由的时候完成保存图片的操作1. 配置 multer 中间键 const multer = require('koa-multer') let storage = multer.diskStorage({ //文件保存路径 这个路由是以项目文件夹 也就是和入口文件(如app.js同一个层级的) destination: function (req, file, cb) { cb(null, 'static/base/') }, //修改文件名称 filename: function (req, file, cb) { let fileFormat = (file.originalname).split("."); //以点分割成数组,数组的最后一项就是后缀名 cb(null, 'Jimmy'+Date.now() + "." + fileFormat[fileFormat.length - 1]); } }) let upload = multer({ storage: storage, limits: { fileSize: 1024*1024/2 // 限制512KB } }); module.exports = upload 2. 在路由中使用 const router = require('koa-router')() const upload = require('../common/uploadConfig') // 引入我们的中间键 // 在路由的时候注入,之后只要这个路由一走,就会自动的将我们的图片上传到服务器,并且保存到我们 upload 中间键配置的保存文件目录下 router.post('/gallery',upload.single('file'),async ctx=>{ console.log('new data',ctx.req.file.filename) ctx.body = {code:200,result:'请求成功',filename:ctx.req.file.filename} }) module.exports = router.routes()