vant-ui上传文件组件,base64数据流上传ali-oss

使用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 });
        },

问题解决了

猜你喜欢

转载自blog.csdn.net/YL971129/article/details/113926092