腾讯云COS使用笔记


这篇文章,主要是用腾讯云COS和阿里云OSS做对比,选择更适合自己的方案

(1)阿里云对象存储遗留的问题

1)如何方便快速的把整个站点上传到OSS,并且文件目录结构不变。

2)如何在浏览器端直接使用JavaScript调用对象存储接口,使得可以直接在Web上上传文件到对象存储服务器,而不需要经过服务端中转。

3)如何在浏览器中使用JavaScript调用对象存储的接口,直接显示存储中的图片或下载文件。

这样,基本上是把对象存储当成一个文件服务器,方便上传、管理、下载、查看文件目录。但在阿里云对象存储中,能使用JavaScript的有Node.jsBrowser.js,但均需要npm安装或打包,不易于浏览器端直接使用。

(2)腾讯云COS操作笔记

1)上传文件夹

2)JavaScript上传对象1

首先,得做一个sts授权接口,提供给js端调用,该接口是基于ThinkPHP5框架编写的

$sts = new \STS();
// 配置参数
$config = array(
    'url' => 'https://sts.tencentcloudapi.com/',
    'domain' => 'sts.tencentcloudapi.com',
    'proxy' => '',
    'secretId' => 'xxxxxxxxxxxxxxxxxxx', // 固定密钥
    'secretKey' => 'xxxxxxxxxxxxxxxx', // 固定密钥
    'bucket' => 'cq-xxxxxxx', // 换成你的 bucket
    'region' => 'ap-chongqing', // 换成 bucket 所在园区
    'durationSeconds' => 1800, // 密钥有效期
    'allowPrefix' => '*', // 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的目录,例子:* 或者 a/* 或者 a.jpg
    // 密钥的权限列表。简单上传和分片需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
    'allowActions' => array (
        // 所有 action 请看文档 https://cloud.tencent.com/document/product/436/31923
        // 简单上传
        'name/cos:PutObject',
        'name/cos:PostObject',
        // 分片上传
        'name/cos:InitiateMultipartUpload',
        'name/cos:ListMultipartUploads',
        'name/cos:ListParts',
        'name/cos:UploadPart',
        'name/cos:CompleteMultipartUpload',
        // 获取列表
        'name/cos:GetBucket',
    )
);
// 获取临时密钥,计算签名
$tempKeys = $sts->getTempKeys($config);

// 返回数据给前端
header('Content-Type: application/json');
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Headers: origin,accept,content-type');
return json($tempKeys);

js端先获取该接口参数,经过授权后,才可上传文件

HTML关键代码

<input id="file-selector" type="file">
var Bucket = 'cq-xxxx';
var Region = 'ap-chongqing';

// 初始化实例
var cos = new COS({
    getAuthorization: function (options, callback) {
        var url = 'https://xxxx.cn/sts.html';
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.onload = function (e) {
            try {
                var data = JSON.parse(e.target.responseText);
            } catch (e) {
            }
            callback({
                TmpSecretId: data.credentials && data.credentials.tmpSecretId,
                TmpSecretKey: data.credentials && data.credentials.tmpSecretKey,
                XCosSecurityToken: data.credentials && data.credentials.sessionToken,
                ExpiredTime: data.expiredTime,
            });
        };
        xhr.send();
    }
});

// 监听选文件
document.getElementById('file-selector').onchange = function () {
    var file = this.files[0];
    if (!file) return;

    // 小文件上传
    cos.putObject({
        Bucket: Bucket,
        Region: Region,
        Key: 'images/' + file.name,
        StorageClass: 'STANDARD',
        Body: file, // 上传文件对象
        onProgress: function(progressData) {
            console.log(JSON.stringify(progressData));
        }
    }, function(err, data) {
        console.log(err || data);
    });
};

3)使用LayUI的上传控件上传文件 关键代码

//绑定文件域
upload.render({
    elem: '#test1',
    exts:'jpg|png|gif|bmp|jpeg',
    auto: false,
    size: 4096,
    choose: function(obj){
        /**
         * index 得到文件索引
         * file 得到文件对象
         * result 得到文件base64编码,比如图片
         */
        obj.preview(function(index, file, result){
            cos.putObject({
                Bucket: Bucket,
                Region: Region,
                Key: 'images/' + file.name,
                StorageClass: 'STANDARD',
                Body: file,
                onProgress: function(progressData) {
                    console.log(JSON.stringify(progressData));
                    element.progress('demo', (progressData.percent * 100).toFixed(2) + '%' );
                }
            }, function(err, data) {
                if(data && data.statusCode){
                    layer.msg("上传成功",{icon:1});
                }
                if(err){
                    console.log(err);
                    layer.msg("上传失败",{icon:2});
                }
            });
        });
    }
});

效果图:

4)获取文件列表及下载文件

var filedomain = 'http://cq.file.cos.com';
function renderList(il){
    var d = document.getElementById('imglist');
    var _html = '';
    for (var i = 0; i < il.length; i++) {
        _html += '<img src="'+ filedomain + il[i].Key +'">';
    }
    d.innerHTML = _html;
}

cos.getBucket({
    Bucket: Bucket,
    Region: Region,
    Prefix: 'images/', // 这里传入列出的文件前缀
    }, function (err, data) {
        console.log(err || data.Contents);
        if(data && data.Contents){
            renderList(data.Contents);
        }        
    }
);

5)实现效果

https://hello.fe80.cn/pages/store/cos/upload.html,不保证长期维护

6)腾讯云对象存储支持IPv6方案 2021/07/31

目前只有北京、上海、广州、南京地域COS支持IPv6直接访问。

*.cos-dualstack.ap-beijing.myqcloud.com.[2402:4e00:21:1008::9]
*.cos-dualstack.ap-shanghai.myqcloud.com.[2402:4e00:32:1000::55]
*.cos-dualstack.ap-guangzhou.myqcloud.com.[2402:4e00:40:2::20]
*.cos-dualstack.ap-nanjing.myqcloud.com.[2402:4e00:a0:1b::58]
*.cos-dualstack.ap-chongqing.myqcloud.com.
*.cos-dualstack.ap-chengdu.myqcloud.com.
*.cos-dualstack.ap-hongkong.myqcloud.com.
*.cos-dualstack.ap-singapore.myqcloud.com

遇到问题:

(1)获取文件列表时,总是出现403状态码,后面检查为sts没有授权,需要修改PHP代码对获取文件列表GetBucket授权。

$sts = new \STS();
// 配置参数
$config = array(
    // ...
    'allowActions' => array (
        // 所有 action 请看文档 https://cloud.tencent.com/document/product/436/31923
        // ...
        // 获取列表
        'name/cos:GetBucket',
    )
);
// 获取临时密钥,计算签名
$tempKeys = $sts->getTempKeys($config);

总结:

(1)对比阿里OSS来说,腾讯COS作为文件(图片)服务器来说更为方便,主要为COS可以使用JavaScript方便的获取文件列表及下载文件,阿里的较为麻烦(需要使用后端语言再调用接口,暂时没实现功能)。

(2)经测试:从贵州贵阳到百度云存储香港节点访问时延为72ms,速度为500KB/s;到阿里云香港节点云存储IPV6网络时延电信为300±ms/移动为120±ms,访问速度较慢;到腾讯云香港节点云存储访问为46ms,速度为3MB/s以上。故:若域名没有备案,需要部署静态网站,使用腾讯云存储访问效果最佳。[2021/06/07]

参考文档: