博主在最近的工做中,接触到了使用thinkjs框架做为后台架构的网店后台Node服务,由于其使用的qiniu上传图片接口不符合需求,须要改成ali-oss接口,一路遇到很多坑,在此作一下记录总结。javascript
首先是elementUI前端部分
上传至后台,须要将flie文件,转为FormData
对象后传至后台,因使用的组件库为element,其upload的组件中,action
为必传(博主此项传空),同时将auto-upload
传false
(意思为不自动上传),而后上传操做在on-change
事件中完成,回调完毕后重显DOM。具体代码片断以下:html
<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事件以下:java
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名字。node
file接收了,那就要上传至OSS系统中,博主这里使用了ali-oss
插件,只要简单安装导入const OSS = require('ali-oss')
后即可以使用。ios
图片file文件的读取,借助了fs
库和path
,将文件转为blob类型后,经过OSS的put方法将图片上传至OSS系统中,具体示例代码以下:axios
// 上传图片到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()
。
安全
参考资料:
elementUI的Upload组件
ali-oss的Node配置介绍
Buffer介绍
babel