博主在最近的工做中,接觸到了使用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