前端使用elementUI框架,后端使用thinkjs,上传图片至ali-oss系统

2020/07/05 16:38
阅读数 1.2K

博主在最近的工作中,接触到了使用thinkjs框架作为后台架构的网店后台Node服务,因为其使用的qiniu上传图片接口不符合需求,需要改为ali-oss接口,一路遇到不少坑,在此做一下记录总结。

首先是elementUI前端部分

上传至后台,需要将flie文件,转为FormData对象后传至后台,因使用的组件库为element,其upload的组件中,action为必传(博主此项传空),同时将auto-uploadfalse(意思为不自动上传),然后上传操作在on-change事件中完成,回调完毕后重显DOM。具体代码片段如下:

<el-form-item
  label="印花图片"
  prop="url"
  v-if="infoForm.url"
  class="image-uploader-diy new-height"
>
  <img v-if="infoForm.url" :src="infoForm.url" class="image-show" />
  <el-button
    class="dele-list-pic"
    type="primary"
    @click="delePicList"
  >
    <i class="fa fa-trash-o"></i>
  </el-button>
</el-form-item>
<el-form-item label="印花图片" prop="url" v-else>
  <el-upload
    name="file"
    class="upload-demo"
    action=""
    :on-change="handleOnChangeUpload"
    list-type="picture-card"
    :auto-upload="false"
  >
    <el-button size="small" type="primary">点击上传</el-button>
    <div slot="tip" class="el-upload__tip">
      只能上传jpg/png文件,且不超过500kb
    </div>
  </el-upload>
</el-form-item>

博主是通过infoForm.url的有无,来判断是显示上传区域还是图片。

用于上传的onChange事件如下:

handleOnChangeUpload(file) {
  let formData = new FormData() // new一个FormData实例
  formData.append('file', file.raw)
  // 配置请求头
  let config = {
    headers: {
      'Content-Type': 'multipart/form-data',
    },
  }
  // 发送axios的POST请求
  this.axios
    .post(this.root + 'goods/uploadImageToAliOss', formData, config)
    .then((response) => {
      this.infoForm.url = response.data.data
    })
}

后台Node部分

由于后台是使用了thinkjs作为架构搭建,其官方文档上,对于FormData数据的接收并不需要通过babel-parse插件或者multer插件来作接收,只需要简单地调用一下this.file(参数),参数为你所传递的file名字。

file接收了,那就要上传至OSS系统中,博主这里使用了ali-oss插件,只要简单安装导入const OSS = require('ali-oss')后便可以使用。

图片file文件的读取,借助了fs库和path,将文件转为blob类型后,通过OSS的put方法将图片上传至OSS系统中,具体示例代码如下:

// 上传图片到OSS接口 start
async uploadImageToAliOssAction() {
  const file = this.file('file')
  let file_re = this.readFileAsBuffer(file)
  let client = new OSS({
    region: '这里填region',
    //云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,部署在服务端使用RAM子账号或STS,部署在客户端使用STS。
    accessKeyId: '这里填accessKeyId',
    accessKeySecret: '这里填accessKeySecret',
    bucket: '这里填bucket',
  })
  const imgName = think.uuid('v4') // uuid.v4生成文件名(thinkjs自带,若为纯node服务则安装'UUID'插件,使用UUID.v4()即可生成)
  const imgType = file.type.substr(6, 4) // 取图片类型
  const filePath = `goodsMask/${imgName}.${imgType}` // 图片存储的路径
  // 想要成功上传base64数据到OSS,必须通过put接口传转换后的buffer文件
  let response = await client.put(filePath, file_re)
  if (response.res.status == 200) {
    return this.success(response.url) // 返回OSS的图片地址到前端
  }
}
//将文件转为blob类型
readFileAsBuffer(file) {
  let filePath = path.resolve(file.path) // 读取路径
  let data = fs.readFileSync(filePath) // 读取文件
  let base64File = new Buffer.from(data, 'base64') // base64转buffer
  return base64File
}
// 上传图片到OSS接口 end

至此,完整的上传过程就完成了,是不是感觉很简单,但是菜鸟博主花了好久才摸索出来。。。
最后一点,使用ali-oss插件,在后台中使用不了new OSS.Buffer()将文件转Buffer类型,博主起初直接使用了new Buffer()去转,结果控制台报错,查了一下,原来是安全性问题,后边换成了new Buffer.form()
Buffer

参考资料:
elementUI的Upload组件
ali-oss的Node配置介绍
Buffer介绍


展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部