通过element-ui的upload实现上传资源到七牛云功能的时候遇到了很多问题,现在和大家分享出来。
一、上传头像组件com_user_head_upload.vue:
class="avatar-uploader" :action="qiniu.actionPath" :show-file-list="false" :data="qiniu.postData" accept="image/*" :on-success="handleAvatarHeadSuccess" :before-upload="beforeAvatarHeadUpload" :on-change="imageCardOneChange" :file-list="headList"> + 点击上传
import {mapGetters,mapActions,mapMutations } from 'vuex'
import {qiniuTokenCreate} from "@/assets/js/qiniu/qiniuTokenCreate"
import { createUserHead } from '@/api/resource'
import { Message } from 'element-ui'
export default {
props: {
},
data () {
return {
headList:[],
// 头像上传
userHeadImg: '',
// 七牛云上传
qiniu:{
actionPath:'https://upload.qiniup.com/', // 放七牛云的地址
imageUrl: '',
postData:{
'token':'',
'domain':'',
}
},
}
},
computed:{
...mapGetters({
editor_id:'editor_id',
organization_id:'organization_id'
}),
},
methods: {
...mapActions([
'createUserHeadAction',
]),
...mapMutations([
'createUserHeadMutations',
'createImageListMutations',
]),
imageCardOneChange(file, fileList){
let timestamp = (new Date()).valueOf(); //时间戳
// 加上时间戳,防止,当所上传的文件已存在而报614错误的问题
this.qiniu.postData.key = timestamp + '/' + file.name
let str=file.name.substr(0,10)+"..."
fileList[0].name=str
//七牛koken
let token=qiniuTokenCreate('image')
this.qiniu.postData.token=token;
//设置资源访问地址
this.qiniu.postData.domain="http://image.i.haierzhongyou.com/"
},
handleAvatarHeadSuccess(res, file,fileList) {
let key=null
let resKey=res.key
if(resKey.indexOf(".png") != -1){
key=res.key.replace(".png","")
}else if(resKey.indexOf(".jpg") != -1){
key=res.key.replace(".jpg","")
}else if(resKey.indexOf(".gif") != -1){
key=res.key.replace(".gif","")
}else if(resKey.indexOf(".bmp") != -1){
key=res.key.replace(".bmp","")
}
// 返回的res.key为“1569572544743/4.png”时间戳加文件名的形式,下面两行为截取文件名
let keyIndex = key.lastIndexOf('\/')
key = key.substring(keyIndex + 1, key.length)
let url=this.qiniu.postData.domain+res.key
// let data={"name":key,"url":url,"f_size":file.size,"f_hash":res.hash,"organization_id":this.organization_id,"creator_id":this.editor_id}
let data={"name":key,"url":url,"f_size":file.size,"f_hash":res.hash,"organization_id":this.organization_id,"creator_id":this.editor_id}
createUserHead(data).then(rsp => {
if (rsp.data.status == true) {
this.createUserHeadMutations(rsp.data.data)
} else {
let fileId=file.uid
fileList.forEach((m,k)=>{
if(m.uid===fileId){
fileList.splice(k,1)
}
})
Message({
message: rsp.data.msg,
type: 'error',
duration: 5 * 1000
})
}
})
},
beforeAvatarHeadUpload(file) {
// const isLt2M = file.size / 1024 / 1024 < 2;
// if (!isLt2M) {
// this.$message.error('上传头像图片大小不能超过 2MB!');
// }
// return isLt2M;
},
},
created(){
//七牛koken
// let token=qiniuTokenCreate()
// this.qiniu.postData.token=token;
},
}
.avatar-uploader{
.el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
img{width:100%;}
}
.el-upload:hover {
border-color: #409EFF;
}
.message{float:left;margin-top:10px;width:100%;text-align:center;}
.haveUpImg{position:relative;
.mes{
position: absolute;
top: 0;
height: auto !important;
line-height: inherit;
left: 0;
width: 100%;
text-align: center;
color: #323232;
}
}
.avatar {
width: 178px;
height: 78px;
display: block;
}
.uploadDemoBox{line-height: 0.5}
}
1、data 是要传递的参数,这个参数就是upToken值,我们需要传递给七牛云的凭证,之后我们再说这个凭证怎么生成
2、 action 是要放七牛云的地址
其中还需要七牛云的配置文件,如下:
当头像改变时调用的方法,在这里可以对图片做些处理,同时给token赋值,qiniuTokenCreate('image')
中的image为七牛云存储空间的列表名,空间存储类型可到七牛云上看,如果为image就写image,如果为video就写video
handleAvatarHeadSuccess为上传成功后调用的函数,可以打印出file得到一个key,然后拼接上传成功后的图片地址,拼接方式大概为:let url=this.qiniu.postData.domain+res.key
二、qiniuTokenCreate.js代码:
import { genUpToken } from '@/assets/js/qiniu/qiniuToken'
// 获取当前时间
export const qiniuTokenCreate = (bucketName) => {
// 生成七牛云token
var token
var policy = {}
var bucketNames = bucketName// 存储空间列表名
var AK = '你的七牛云AK'
var SK = '你的七牛云SK'
var deadline = Math.round(new Date().getTime() / 1000) + 3600
policy.scope = bucketNames
policy.deadline = deadline
// policy.unique_names = false;
token = genUpToken(AK, SK, policy)
return token
}
三、token生成的文件qiniuToken.js:
/**
* Created by guohongjun on 2018/4/18.
* 用户相关api
*/
import CryptoJS from 'crypto-js'
/* utf.js - UTF-8 <=> UTF-16 convertion
*
* Copyright (C) 1999 Masanao Izumo
* Version: 1.0
* LastModified: Dec 25 1999
* This library is free. You can redistribute it and/or modify it.
*/
/*
* Interfaces:
* utf8 = utf16to8(utf16);
* utf16 = utf8to16(utf8);
*/
function utf16to8 (str) {
var out, i, len, c
out = ''
len = str.length
for (i = 0; i < len; i++) {
c = str.charCodeAt(i)
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i)
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F))
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F))
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F))
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
}
}
return out
}
// function utf8to16 (str) {
// var out, i, len, c
// var char2, char3
// out = ''
// len = str.length
// i = 0
// while (i < len) {
// c = str.charCodeAt(i++)
// switch (c >> 4) {
// case 0:
// case 1:
// case 2:
// case 3:
// case 4:
// case 5:
// case 6:
// case 7:
// // 0xxxxxxx
// out += str.charAt(i - 1)
// break
// case 12:
// case 13:
// // 110x xxxx 10xx xxxx
// char2 = str.charCodeAt(i++)
// out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F))
// break
// case 14:
// // 1110 xxxx 10xx xxxx 10xx xxxx
// char2 = str.charCodeAt(i++)
// char3 = str.charCodeAt(i++)
// out += String.fromCharCode(((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0))
// break
// }
// }
// return out
// }
/*
* Interfaces:
* b64 = base64encode(data);
* data = base64decode(b64);
*/
var base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'
// var base64DecodeChars = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
// 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
// 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
// 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1]
function base64encode (str) {
var out, i, len
var c1, c2, c3
len = str.length
i = 0
out = ''
while (i < len) {
c1 = str.charCodeAt(i++) & 0xff
if (i === len) {
out += base64EncodeChars.charAt(c1 >> 2)
out += base64EncodeChars.charAt((c1 & 0x3) << 4)
out += '=='
break
}
c2 = str.charCodeAt(i++)
if (i === len) {
out += base64EncodeChars.charAt(c1 >> 2)
out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4))
out += base64EncodeChars.charAt((c2 & 0xF) << 2)
out += '='
break
}
c3 = str.charCodeAt(i++)
out += base64EncodeChars.charAt(c1 >> 2)
out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4))
out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6))
out += base64EncodeChars.charAt(c3 & 0x3F)
}
return out
}
// function base64decode (str) {
// var c1, c2, c3, c4
// var i, len, out
// len = str.length
// i = 0
// out = ''
// while (i < len) {
// /* c1 */
// do {
// c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff]
// } while (i < len && c1 == -1)
// if (c1 == -1) break
// /* c2 */
// do {
// c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff]
// } while (i < len && c2 == -1)
// if (c2 == -1) break
// out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4))
// /* c3 */
// do {
// c3 = str.charCodeAt(i++) & 0xff
// if (c3 == 61) return out
// c3 = base64DecodeChars[c3]
// } while (i < len && c3 == -1)
// if (c3 == -1) break
// out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2))
// /* c4 */
// do {
// c4 = str.charCodeAt(i++) & 0xff
// if (c4 == 61) return out
// c4 = base64DecodeChars[c4]
// } while (i < len && c4 == -1)
// if (c4 == -1) break
// out += String.fromCharCode(((c3 & 0x03) << 6) | c4)
// }
// return out
// }
var safe64 = function (base64) {
base64 = base64.replace(/\+/g, '-')
base64 = base64.replace(/\//g, '_')
return base64
}
var genUpToken = function (accessKey, secretKey, putPolicy) {
// SETP 2
var put_policy = JSON.stringify(putPolicy)
// SETP 3
var encoded = base64encode(utf16to8(put_policy))
// SETP 4
var hash = CryptoJS.HmacSHA1(encoded, secretKey)
var encoded_signed = hash.toString(CryptoJS.enc.Base64)
// SETP 5
var upload_token = accessKey + ':' + safe64(encoded_signed) + ':' + encoded
return upload_token
}
export {
genUpToken
}
四、引用头像组件的Index.vue:
import userHeadUpload from '@/components/com_user_head_upload'
export default {
components: {
userHeadUpload
},
data () {
return {
},
}
},
computed:{
...mapGetters({
themeInfo: 'themeInfo'
}),
},
methods: {
},
mounted:function(){
}
}
五、总结
开发这个功能过程中遇到的问题大概是在配置token有一些问题,如bucketName写的不对,和存储空间类型不匹配,还有就是图片地址拼接不正确等等。
参考文章:https://blog.csdn.net/qq_36020836/article/details/80845880