文档直达:服务端签名后直传
没有采用JS客户端签名直传上是因为,此过程AccessKey ID和AcessKey Secret会暴露在前端页面,因此存在严重的安全隐患。所以查找阿里云决定使用服务端签名后直传的方案。
视频上传组件 el-upload:
<el-upload style="marginTop:-5px;" class="upload-demo" :action="ossParams.host || ''" :data="extraData" :before-upload="beforeUpload" :on-progress="handleUploadProgress" :on-success="handleUploadSuccess" :on-error="handleUploadError" :show-file-list="false" :disabled="uploadPercent > 0 && uploadPercent < 100" accept="video/*" > <el-button size="small" type="primary">{{ uploadPercent === 0 ? '点击上传' : uploadPercent === 100 ? '重新上传' : '视频上传中,请稍候...' }}</el-button> <div slot="tip" class="el-upload__tip"> 支持所有视频文件,且不超过1GB </div> </el-upload>视频上传进度条el-progress:
<el-progress v-if="showPro" v-show="uploadPercent > 0" :percentage="uploadPercent" :color="customColorMethod" ></el-progress>视频上传完成后显示的视频地址(可复制):
<el-form-item v-if="uploadPercent === 100"> <span style="font-size:12px;font-weight:500">视频地址 : </span> <el-link id="videoLink" :data-clipboard-text="'阿里云oss地址' + extraData.key" type="info" @click=" () => { this.$message.success('复制视频地址成功') } " >{{ '阿里云oss地址' + extraData.key }}<i class="el-icon-document-copy el-icon--right"></i> </el-link> </el-form-item>效果如下:
1、el-upload组件
1)上传的地址:action="ossParams.host || ''"
主要是获取上传阿里云的加密策略policy和签名signature,以及上传自己要上传到阿里云的地址,当然还有自己阿里云accessid。
2)上传时附带的额外参数:data="extraData" 参数如下:
extraData: { key: '', policy: '', OSSAccessKeyId: '', success_action_status: '200', //让服务端返回200,不然,默认会返回204 callback: '', signature: '' }3)上传前通过:before-upload="beforeUpload"进行校验:
beforeUpload(file) { if (file.size > 1024 * 1024 * 1024) { this.$message.error('上传视频大小不能超过1G') return false } const expire = this.ossParams.expire * 1000 if (expire < Date.now() - 1000 * 60) { this.$message.error('token有效期已过期,请刷新页面重试') return false } this.uploadPercent = 0 try { const { policy, accessid, dir, callback, signature } = this.ossParams const md5 = crypto.createHash('md5') const nameHash = md5 .update(file.name.split('.')[0] + new Date().getTime().toString()) .digest('hex') this.extraData.key = dir + nameHash + get_suffix(file.name) this.extraData.policy = policy this.extraData.OSSAccessKeyId = accessid this.extraData.callback = callback this.extraData.signature = signature return true } catch (err) { console.log(err) this.$message.error(err.message) return false } },4)上传时:on-progress="handleUploadProgress"
handleUploadProgress(event) { this.uploadPercent = parseInt(event.percent) },5)上传成功:on-success="handleUploadSuccess"
handleUploadSuccess(response, file, fileList) { this.$message.success('视频上传成功') this.$nextTick(() => { const clipboard = new ClipboardJS('#videoLink') }) console.log(response, file, fileList) this.uploadPercent === 100 ? (this.showPro = false) : (this.showPro = true) },6)上传失败:on-error="handleUploadError"
handleUploadError(err) { this.$message.error('视频上传失败 ' + err.toString()) this.uploadPercent = 0 },2、el-progress组件 1)进度条百分比动态变色:color="customColorMethod"
customColorMethod(percentage) { if (percentage < 30) { return '#909399' } else if (percentage < 70) { return '#e6a23c' } else { return '#67c23a' } }