记录:uniapp 上传文件到COS

527 阅读1分钟

安装cos-wx-sdk-v5

npm i cos-wx-sdk-v5

封装上传方法

新建upload.js文件

添加以下代码

    import COS from 'cos-wx-sdk-v5';
    import { getCosToken } from '@/api/upload.js'; // 调用后台获取临时验证信息的接口
    import { v4 as uuid } from 'uuid'; // 用来生成随机编码 非必须

    const Bucket = ''; /* 填入您自己的存储桶,必须字段 */
    const Region = ''; /* 存储桶所在地域,例如ap-beijing,必须字段 */

    export async function uploadToCOS(prefix, filePath) {
        const cosCredential = uni.getStorageSync('cosCredential');
        const cos = new COS({
            getAuthorization: async function(options, callback) {
                if (
                    !cosCredential ||
                    cosCredential.expiredTime < Date.now() / 1000
                ) {
                    try {
                        const cosToken = await getCosToken();
                        uni.setStorageSync('cosCredential', cosToken)
                    } catch (error) {
                        throw new Error('Failed to get COS token');
                    }
                }

                const {
                    secretId: TmpSecretId,
                    secretKey: TmpSecretKey,
                    sessionToken: XCosSecurityToken,
                    startTime: StartTime,
                    expiredTime: ExpiredTime,
                } = uni.getStorageSync('cosCredential');

                callback({
                    TmpSecretId,
                    TmpSecretKey,
                    XCosSecurityToken,
                    StartTime,
                    ExpiredTime,
                });
            },
        })
        
        let fileName = filePath.substr(filePath.lastIndexOf('/') + 1);
        const key = `${prefix}${fileName}`;

        return new Promise(function(resolve, reject) {
            cos.postObject({
                Bucket: Bucket,
                /* 必须 */
                Region: Region,
                /* 必须 */
                Key: key,
                /* 必须 */
                FilePath: filePath,
                onProgress: function(info) {
                    console.log(JSON.stringify(info));
                }
            }, function(err, data) {
                    console.log("[cos.postObject-err]", err || data);
                    resolve(key)
            });
        })
    }

页面使用uview upload

<template>
    <u-upload 
        :file-list="fileList1"
        :previewFullImage="true" 
        multiple
        accept="all"
        name="1" 
        @delete="deletePic" 
        @after-read="afterRead" 
    />
</template>

<script>
    import { uploadToCOS } from './upload.js'
    import { getUrlByKey } from '@/api/upload.js' // 后台提供的根据key获取资源url接口
    
    export default {
        data() {
            fileList1: []
        },
        methods: {
            deletePic(event) {
                this[`fileList${event.name}`].splice(event.index, 1)
            },
            async afterRead(event) {
                // 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
                let lists = [].concat(event.file)
                let fileListLen = this[`fileList${event.name}`].length
                lists.map((item) => {
                    this[`fileList${event.name}`].push({
                        ...item,
                        status: 'uploading',
                        message: '上传中',
                    })
                })
                for (let i = 0; i < lists.length; i++) {
                    const result = await this.uploadFilePromise(lists[i].url)
                    const url = await getUrlByKey(result)
                    let item = this[`fileList${event.name}`][fileListLen]
                    this[`fileList${event.name}`].splice(
                        fileListLen,
                        1,
                        Object.assign(item, {
                            status: 'success',
                            message: '',
                            url: url,
                            cosKey: result
                        })
                    )
                    fileListLen++
                }
            },
            uploadFilePromise(filePath) {
                const prefix = 'xxxx'
                return new Promise((resolve, reject) => {
                    uploadToCOS(prefix, filePath).then(res => {
                        resolve(res)
                    })
                })
            },
        }
    }
</script>