文件上传(OSS)


title: Koa 2框架中接收文件,实现文件上传
date: 2020-11-22
sidebar: auto
categories:

  • 文件上传
  • 小技巧
    tags:
  • koa

Koa 2框架中接收文件,实现文件上传

文件上传这个操作是非常非常常用的,如果是使用JS直接写一个文件上传的代码的代码量是巨大的,且不容易理解,这里我也是在网上查了很久,可以使用koa-multer插件来实现文件上传

传统的文件上传

  • 我过去的做法是先将然后文件全部转码成Base64的一长串字符串,将这一长串字符串传给后端,后端再根据字符串,使用Buffer.from逆解析,最终将图片保存在服务器上,我自己理解的这样的作法有以下的几点不好。

    1. 因为是将整个Base64字符串传递给后端,就会造成一个接口传递的数据量是500k上下甚至1M,极其的消耗性能
    2. 需要做逆解析,使用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()
    

文件上传在有了插件之后开发真的是方便多了,站在巨人的肩膀上编程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值