使用vant-ui组件上传图片,返回的是base64格式
<van-field name="uploader" label="作品封面">
<template #input>
<van-uploader :max-count='1' v-model="uploader" :after-read="afterRead"> </van-uploader>
</template>
</van-field>
此时直接上传base64格式的图片不会成功的,会得到以下信息:
Must provide Buffer/Blob/File for put.
我的解决方案是将base64 转 blob对象 转 arrayBuffer对象 转 buffer对象,然后上传得到的buffer对象,就好了,上代码:
afterRead(file) {
const fileN = file.content; //上面图片中有
const fileU = file.file.name; //上面图片中有
const base64 = fileN.split(',').pop();
const fileType = fileN.split(';').shift().split(':').pop();
const blob = this.toBlob(base64, fileType)
//blob转arrayBuffer
const reader = new FileReader();
reader.readAsArrayBuffer(blob);
reader.onload = function(event) {
const fileExtension = fileU.substring(fileU.lastIndexOf('.'));
//uuid是一个生成随机数的函数,下面贴
const objectKey = 'gt/' + uuid() + fileExtension;
//arrayBuffer转buffer
const buffer = new OSS.Buffer(event.target.result);
//client是ali-oss的相关配置
client.put(objectKey , buffer).then(result => {
console.log(result)
this.imageUrl = result.url;
console.log(this.imageUrl)
}).catch(err => {
console.log(err)
})
}
},
//转bolb对象
toBlob(urlData,fileType) {
let bytes = window.atob(urlData);
let n = bytes.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bytes.charCodeAt(n);
}
return new Blob([u8arr], { type: fileType });
},
最后看下result返回结果:
就成功了
function uuid() { //生成随机数
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid;
}
let client = new OSS({
region: 'xxx',
accessKeyId: 'xxxx',
accessKeySecret: 'xxxx',
bucket: 'xxx',
endpoint: 'xxx',
cname: true,
});
发现还有一个问题 new FileReader()是异步的,在onload事件外面无法得到执行结果,修改下代码,将FileReader()封装一个函数,返回一个Promise
完整代码:
afterRead(file) { //上传封面图片到ali-oss
const fileN = file.content;
const fileU = file.file.name;
const base64 = fileN.split(',').pop();
const fileType = fileN.split(';').shift().split(':').pop();
const blob = this.toBlob(base64, fileType)
this.readFile(blob).then(res => {
const fileExtension = fileU.substring(fileU.lastIndexOf('.'));
const objectKey = 'gt/' + uuid() + fileExtension;
const buffer = new OSS.Buffer(res.target.result);
client.put(objectKey, buffer).then(result => {
console.log(result)
this.imageUrl = result.url;
console.log(this.imageUrl)
}).catch(err => {
console.log(err)
})
})
},
readFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function(event) {
resolve(event)
}
})
},
toBlob(urlData, fileType) {
let bytes = window.atob(urlData);
let n = bytes.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bytes.charCodeAt(n);
}
return new Blob([u8arr], { type: fileType });
},
问题解决了