首先,文件上傳那些事兒,從頭補一下https://cloud.tencent.com/developer/article/1004961前端
一開始沒有明確需求,覺得須要先把文件寫到後端,而後再上傳騰訊雲。因此研究了下koa-body怎麼用文件流讀寫文件到後端。web
而後在獲取ctx.request.body.files.file時怎麼都獲取不到element-ui
感謝https://www.jianshu.com/p/34d0e1a5ac70後端
嚴正提醒:api
新版本的koa-body經過ctx.request.files獲取上傳的文件
舊版本的koa-body經過ctx.request.body.files獲取上傳的文件koa
因爲須要在後端請求一個須要當前圖片寬高的接口,而formData中的file並雖然有name、size信息,可是並無圖片的寬高信息async
因而在前端獲取寬高,並傳送給後端。post
這裏我用的element-ui,前端代碼以下ui
<template> <el-upload class="upload-demo" action="/api/uploadFile" :on-preview="handlePreview" :on-remove="handleRemove" :before-upload="getWidth" :file-list="fileList" list-type="picture" :data="pictureUpload" > <el-button size="small" type="primary">點擊上傳</el-button> <div slot="tip" class="el-upload__tip">只能上傳jpg/png文件,且不超過500kb</div> </el-upload> </template>
使用fileReader()獲取上傳圖片的寬高 https://www.haorooms.com/post/js_webapi_filereaderthis
<script> export default { name: "upload", data(){ return { pictureUpload: { width: 0, height: 0 } } }, methods: { handleRemove(file, fileList) { console.log(file, fileList); }, handlePreview(file) { console.log(file); }, getWidth(file) { // 獲取文件尺寸 let _this = this; return new Promise(function(resolve, reject) { let reader = new FileReader() reader.readAsDataURL(file) reader.onload = function(theFile) { let image = new Image() image.src = theFile.target.result image.onload = function() { console.log(`${this.width}*${this.height}`) console.log(this.width,this.height) console.log(_this.fileList) _this.pictureUpload.width = this.width; _this.pictureUpload.height = this.height; resolve(file); } } }) } } } </script>
後端的代碼以下
var info = require('../config/info') var Uploader = require('../modules/cos-uploader') var JsonProxy = require('../modules/cos-uploader') var fs = require("fs") var path = require("path") const crypto = require('crypto'); let jprxClient = new JsonProxy({env: 'beta'}); async function uploadFile (ctx, next) { let file = ctx.request.files.file;// 獲取上傳文件 let userInfo = { "account": "122333221", "loginkey": "aaaaaaaaaaaaaaaaaa", } // 請求cosPath的參數 let hash = crypto.createHash('sha1'); let buffer = fs.readFileSync(file.path); hash.update(buffer); let sha1 = hash.digest('hex'); let opts = { "authCtx": userInfo, "photoInfo": { "name": file.name, "size": file.size, "sha": sha1, "width": ctx.request.body.width, "height": ctx.request.body.height } }; console.log('opts__________________',opts) let cosPath = ''; // 接口請求省略 // 上傳騰訊雲 let localPath = file.path; let groupId = "temp"; let remotePath = _getRemotePath(localPath, groupId); let uploader = new Uploader({ // AppId: info.cos.AppId, SecretId: info.cos.SecretId, SecretKey: info.cos.SecretKey }); let uploadOptions = { bucket: info.cos.Bucket+ '-' + info.cos.AppId, region: info.cos.Region, remotePath: remotePath, localPath: localPath }; console.log('uploadOptions', uploadOptions); let uploadResult = await uploader.up(uploadOptions); console.log('upLoadResult____________________',uploadResult); if(uploadResult.statusCode == 200) { let opts = { "authCtx": userInfo, "sha": sha1 }; console.log('callBackOpts____________________________',opts) // 請求接口省略 ctx.body = { location: uploadResult.Location, status: 0, message: 'success' } }else { ctx.body = { status: -1, message: uploadResult } } } // 可獲取cosPath後不須要 function _getRemotePath(filePath, groupId) { var groupId = groupId || 'common_group_id'; var hash = crypto.createHmac('sha256', 'useforalbums').update(fs.readFileSync(filePath)).digest('hex'); return `albumgroup_${global._ENV === 'production' ? 'production' : 'beta'}/${groupId}/${hash}`; } module.exports = { uploadFile, };