腾讯 COS Web端 临时秘钥上传 单文件+多文件 实现

使用 vue + php 实现

实现思路

后端生成临时秘钥 , 前端通过接口获取临时秘钥上传

php composer.json 增加sdk 

"require": {

        "qcloud_sts/qcloud-sts-sdk": "3.0.*"

    }

php 生成临时签名方法

public function getCosTemporarilyInfo(){

        $bucket = env("Tencent.COSBucketName");

        $region = env("Tencent.Region"); // cos存储 所在园区

        $cacheTime = 1800; // 根据自己的需要 设置缓存时间

        $sts = new Sts();  // 安装 腾讯cos 临时签名 sdk

        $config = [

                'secretId' => env('Tencent.TENCENTCLOUD_SECRET_ID'),

                'secretKey' => env('Tencent.TENCENTCLOUD_SECRET_KEY'),

                'bucket' =>  $bucket,

                'region' => $region, //  bucket 所在园区

                'durationSeconds' => $cacheTime, // 密钥有效期

                'allowPrefix' => ['myapp/*'], // 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)

                // 密钥的权限列表。简单上传和分片需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923

                'allowActions' => [

                    // 简单上传

                    "name/cos:PutObject",

                    'name/cos:PostObject',

                    // 分片上传

                    'name/cos:InitiateMultipartUpload',

                    'name/cos:ListMultipartUploads',

                    'name/cos:ListParts',

                    'name/cos:UploadPart',

                    'name/cos:CompleteMultipartUpload'

                ]

        ];

        // 获取临时密钥,计算签名

        return $sts->getTempKeys($config);

}


前端实现:  例如新建一个 utils/cos.js,项目内全局使用:

import COS from 'cos-js-sdk-v5';

const cos = new COS({

    // 其他配置项可参考下方 初始化配置项

    // getAuthorization 必选参数

    getAuthorization: function (options, callback) {

        // 初始化时不会调用,只有调用 cos 方法(例如 cos.putObject)时才会进入

        // 异步获取临时密钥

        // 服务端 JS 示例:https://github.com/tencentyun/cos-js-sdk-v5/blob/master/server/

        // 服务端其他语言参考 COS STS SDK :https://github.com/tencentyun/qcloud-cos-sts-sdk

        // STS 详细文档指引看:https://cloud.tencent.com/document/product/436/14048

        const stsUrl = 'http://example.com/server/sts'; // stsUrl 替换成您自己的后端服务

        fetch(stsUrl)

          .then(response => response.json())

          .then(data => {

            if (!data || !data.credentials) {

              return console.error('credentials invalid:\n' + JSON.stringify(data, null, 2))

            }

            // 检查credentials格式

            const { credentials } = data;

            console.log(credentials);

            callback({

              TmpSecretId: credentials.tmpSecretId,

              TmpSecretKey: credentials.tmpSecretKey,

              SecurityToken: credentials.sessionToken,

              // 建议返回服务器时间作为签名的开始时间,避免客户端本地时间偏差过大导致签名错误

              StartTime: data.startTime, // 时间戳,单位秒,如:1580000000

              ExpiredTime: data.expiredTime, // 时间戳,单位秒,如:1580000000

              ScopeLimit: true, // 细粒度控制权限需要设为 true,会限制密钥只在相同请求时重复使用

            });

          })

          .catch(error => {

            console.error('获取临时密钥失败', error);

          });

    }

});

export default cos;


页面使用-单文件

import cos from 'utils/cos';

let taskId;

// 上传文件,file为选择的文件

async function upload(file) {

  try {

    const data = await cos.uploadFile({

      Bucket: 'examplebucket-1250000000', // 填写自己的 bucket,必须字段

      Region: 'COS_REGION',    // 存储桶所在地域,必须字段

      Key: '1.jpg',            // 存储在桶里的对象键(例如1.jpg,a/b/test.txt),必须字段

      Body: file, // 上传文件对象

      SliceSize: 1024 * 1024 * 5,  // 触发分块上传的阈值,超过5MB 使用分块上传,小于5MB使用简单上传。可自行设置,非必须

      onProgress: function(progressData) {

        console.log('上传进度:', progressData);

      },

      onTaskReady: function(id) { // 非必须

        taskId = id;

      },

    });

    console.log('上传成功', data);

  } catch (e) {

    console.error('上传失败', e);

  }

}

// 监听上传队列

cos.on('update-list', data => {

    console.log(data);

});

// 暂停上传任务

cos.pauseTask(taskId);

// 重启上传任务

cos.restartTask(taskId);

// 取消上传任务

cos.cancelTask(taskId)


页面使用-多文件

    let arrFileList = []

                for(let i = 0;i<this.fileData.length;i++){

                    let extension = this.fileData[i].name.lastIndexOf('.')

                    extension = extension !== -1 ? this.fileData[i].name.substring(extension + 1) : '';

                    let uniqueKey = this.generateUniqueKey();

                    let key = 'myapp/'+ this.type + '/' + this.getYmd() + '/' + uniqueKey +'.' + extension;

                    // key = 'myapp/image/' + (i+1) +'.'+extension;

                    let fileInfo = {

                        Bucket: this.Bucket, // 填入您自己的存储桶,必须字段

                        Region: this.Region,  // 存储桶所在地域,例如ap-beijing,必须字段

                        Key: key,  // 存储在桶里的对象键(例如1.jpg,a/b/test.txt),必须字段

                        Body: this.fileData[i], // 必须,上传文件对象,可以是input[type="file"]标签选择本地文件后得到的file对象

                        file_mime:this.fileData[i].type,

                        title:this.fileData[i].name,

                        type:this.typeMap[this.type],

                        onTaskReady: function(uniqueKey) {

                            // taskId可通过队列操作来取消上传cos.cancelTask(taskId)、停止上传cos.pauseTask(taskId)、重新开始上传cos.restartTask(taskId)

                            console.log(uniqueKey);

                        },

                    };

                    arrFileList.push(fileInfo);

                }

          //批量上传文件

                cos.uploadFiles({

                    files: arrFileList,

                    SliceSize: 1024 * 1024 * 10,    // 设置大于10MB采用分块上传

                }, function (err, data) {

                    if(data.files.length >0){

                        for(let i=0;i<data.files.length;i++){

                            if(data.files[i].data){

                                let file = {

                                    'title':data.files[i].options.title,

                                    'file_id':'',

                                    'file_url':'https://'+data.files[i].data.Location,

                                    'file_mime':data.files[i].options.file_mime,

                                    'type':data.files[i].options.type

                                };

                                succ_files.push(file);


                            }

                        }

                    }


                    if(succ_files.length >0){

                        batchAdd({file_arr:succ_files}).then((res) => {

                            if (res.code == 200) {

                             this.$message.success(res.msg)

                            } else {

                                this.$message.error(res.msg)

                            }

                        })

                    }else{

                        this.$message.error('上传失败请稍后重试')

                    }

                });

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容