前端部分使用element框架前端
<el-upload class='avatar-uploader' action='actionUrl' :http-request="httpRequest" :show-file-list='false' :on-success='handleSuccess'> </el-upload>
這裏使用element的上傳組件,node
on-success 上傳成功的回調,ios
show-file-list 是否顯示上傳列表,axios
action爲組件必選參數,要填寫上傳地址,這裏隨便寫了一個字符串,由於上傳方法我要在httpRequest方法中從新寫後端
http-request 自定義上傳方法api
async httpRequest (options) { this.fileReader = new FileReader() let file = options.file let filename = file.name if (file) { this.fileReader.readAsDataURL(file) // 讀文件 } this.fileReader.onload = () => { // 文件讀取後的操做 let base64Str = this.fileReader.result //獲得base64串 uploadImg({ imgData: base64Str, name: filename }).then(res => { // 成功後方法 }) } }
這裏新建了fileReader對象,使用readAsDataURL 異步讀取文件,讀取後在onload方法中獲得base64字符串,服務器
upload方法爲一個上傳方法,和項目中其餘axios封裝方法同樣,接收一個上傳的數據對象,並在一個管理全部請求的文件中寫好請求的url,method,app
後端方法 使用nodejs的 eggjs框架框架
在router中配置一個地址,對應一個controllerdom
router.post(`${domain}/api/uploadImg`, controller.Controller.uploadImg);
在controller文件中 寫一個uploadImg方法,
async uploadImg() { const { imgData, name } = ctx.request.body; if (!imgData) { ctx.response.body = { msg: '圖片不能爲空' } return; } if (!name) { ctx.response.body = { msg: '名稱不能爲空' } return; } const info = await ctx.service.Service.uploadImg(imgData, name) ctx.response.body = { code: info.code, data: info.data, msg: info.msg } }
主要仍是service方法,
這裏imgData爲接收的文件內容,上傳時給的是base64格式,name爲上傳時帶來的文件名稱,
使用fs模塊的writeFile方法,將buffer對象中的內容寫入文件中,文件生成的地址爲配置的路徑加上上傳的文件名
async uploadImg(imgData, name) { const { ctx } = this; const url = ctx.app.config.poster; // config中配置的文件上傳路徑,注意要包含兩個路徑,一個url.dir爲服務器路徑 相似 「/文件夾/文件夾」,一個url.url爲域名 用於返回給前端訪問 try { var base64Data = imgData.replace(/^data:image\/\w+;base64,/, ""); var dataBuffer = new Buffer(base64Data, 'base64'); // 新建一個buffer對象,設置爲base64格式 fs.writeFile(`${url.dir}${name}`, dataBuffer, function(err) { if(err){ console.log(err) }else{ console.log('success') } }); return { data: `${url.url}${name}`, msg: '添加圖片成功' } } catch (error) { } }
至此,文件就會在服務器的指定目錄中,並返回一個url地址,前端能夠保存這個地址連接,此方法也能夠用於富文本中的圖片上傳