• 腾讯云-对象存储服务(COS)的使用总结-JavaScript篇


    简介

    对象存储(Cloud Object Storage,COS)是腾讯云提供的一种存储海量文件的分布式存储服务,具有高扩展性、低成本、可靠安全等优点。通过控制台、API、SDK 和工具等多样化方式,用户可简单、快速地接入 COS,进行任意格式文件的上传、下载和管理,实现海量数据存储和管理。同时遍布全国范围的 CDN/EdgeOne 节点可以对文件下载进行加速。

    前言

    前几天,我们分享了关于服务器端腾讯云-对象存储服务(COS)的使用总结为了安全起见,配置放在服务器端,通过服务器端生成临时密钥供客户端使用,一般在30分钟左右的有效时长,可以看出,服务器端只是起到一个配角作用,今天,我们主要讲一下主角对对象存储服务的API调用,也就是图片中的1,4,5的操作。
    在这里插入图片描述

    引入库

    package.json里添加如下的库

      "dependencies": {
        "cos-js-sdk-v5": "^1.4.20"
      }
    
    • 1
    • 2
    • 3

    具体使用

    我们书写工具类upFile.js,包含了上传图片和视频到腾讯云COS的功能

    import modal from '@/utils/modal.js';
    import request from '@/utils/request';
    import COS from 'cos-js-sdk-v5';
    const cosSessionKey = 'cos_session'
    
    /**获取cos临时密钥等信息*/
    function getCosInfo() {
    	return new Promise((resolve, rejct) => {
    		request({
    			url: '/system/cos/get',
    			method: 'get',
    		}).then(res => {
    			var data = res.data
    			if (data) {
    				uni.setStorageSync(cosSessionKey, data);
    				resolve(data);
    			}
    		})
    	})
    }
    
    var cos = new COS({
    	SimpleUploadMethod: 'putObject',
    	getAuthorization: function(options, callback) {
    		var cosData = uni.getStorageSync(cosSessionKey);
    		callback({
    			TmpSecretId: cosData.secretId,
    			TmpSecretKey: cosData.secretKey,
    			// v1.2.0之前版本的 SDK 使用 XCosSecurityToken 而不是 SecurityToken
    			SecurityToken: cosData.sessionToken,
    			// 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
    			StartTime: cosData.startTime, // 时间戳,单位秒,如:1580000000
    			ExpiredTime: cosData.expiredTime, // 时间戳,单位秒,如:1580000900
    		});
    
    	}
    });
    
    // 上传文件到腾讯云
    const cosUpLoadFile = async (params) => {
    	let uploadFile = '';
    	await uniChooseImage().then(res => {
    		uploadFile = res
    	})
    	return cosUploadFile(uploadFile, params);
    };
    
    // 选择图片
    const uniChooseImage = () => {
    	return new Promise((resolve, rejct) => {
    		uni.chooseImage({
    			// 从本地相册选择图片或使用相机拍照。
    			count: 1, //默认选择1张图片
    			sizeType: ['original', 'compressed'], //original 原图,compressed 压缩图,默认二者都有
    			success: res1 => {
    				resolve(res1.tempFiles[0]);
    			}
    		});
    	});
    }
    
    const cosUploadFile = async (file, params) => {
    	var cosData = uni.getStorageSync(cosSessionKey);
    	if (!cosData || !cosData.bucket) { //如果cos信息不存在
    		//等待获取到cosData
    		await getCosInfo().then(res => {
    			cosData = res
    		});
    	}
    	let promise = new Promise((resolve, rejct) => {
    		modal.loading("上传中...")
    		cos.uploadFile({
    			/* 填入您自己的存储桶,必须字段 */
    			Bucket: cosData.bucket,
    			/* 存储桶所在地域,例如ap-beijing,必须字段 */
    			Region: cosData.region,
    			/* 存储在桶里的对象键(例如1.jpg,a/b/test.txt),必须字段 */
    			Key: params.uploadKey,
    			/* 必须,上传文件对象,可以是input[type="file"]标签选择本地文件后得到的file对象 */
    			Body: file,
    			/* 触发分块上传的阈值,超过5MB使用分块上传,非必须 */
    			SliceSize: 1024 * 1024 * 5,
    			onTaskReady: function(taskId) {
    				/* 非必须 */
    				console.log(taskId);
    			},
    			onProgress: function(progressData) {
    				/* 非必须 */
    				console.log(JSON.stringify(progressData));
    			},
    			onFileFinish: function(err, data, options) {
    				/* 非必须 */
    				console.log(options.Key + '上传' + (err ? '失败' : '完成'));
    			},
    			// 支持自定义headers 非必须
    			Headers: {
    				'x-cos-meta-test': 123
    			},
    		}, function(err, data) {
    			if (data && data.statusCode == 200) {
    				let datas = {
    					imgUrl: 'https://' + data.Location,
    					imgKey: params.uploadKey
    				}
    				resolve(datas);
    			} else if (err && err.statusCode == 403) {
    				if ("Request has expired" == err.message) {
    					console.log("失效Request has expired!重新获取cos信息");
    					uni.removeStorageSync(cosSessionKey);
    					cosUploadFile(file, params).then(res => {
    						resolve(res);
    					});
    				}
    			} else {
    				modal.msg(err ? err.message : "上传失败!");
    			}
    			uni.hideLoading();
    		});
    	});
    	return promise;
    }
    
    const cosDeleteFile = async (params) => {
    	var cosData = uni.getStorageSync(cosSessionKey);
    	if (!cosData || !cosData.bucket) { //如果cos信息不存在
    		//等待获取到cosData
    		await getCosInfo().then(res => {
    			cosData = res
    		});
    	}
    	console.log(params.uploadKey);
    	cos.deleteObject({
    		/* 填入您自己的存储桶,必须字段 */
    		Bucket: cosData.bucket,
    		/* 存储桶所在地域,例如ap-beijing,必须字段 */
    		Region: cosData.region,
    		Key: params.uploadKey,
    	}, function(err, data) {
    		console.log("deleteObject");
    		console.log(err || data);
    		if (err && err.statusCode == 403) {
    			if ("Request has expired" == err.message) {
    				console.log("失效Request has expired!重新获取cos信息");
    				uni.removeStorageSync(cosSessionKey);
    				cosDeleteFile(params);
    			}
    		}
    	});
    }
    
    export default {
    	cosUpLoadFile,
    	cosDeleteFile
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154

    先发起上传图片请求,看下本地有没有临时密钥,如果没有则,通过发送请求https://*****.com/system/cos/get从服务器获取,获取结果如下:

    {
      "code": 200,
      "msg": "处理成功",
      "time": 1693467116217,
      "data": {
        "bucket": "gamioo2010-12********2",
        "region": "ap-shanghai",
        "secretId": "AKIDdPg4NmRr****************************************EXdXdkWNIn2z",
        "secretKey": "g7drx*********************************tiW5EM=",
        "sessionToken": "EJn8gbXdS6r579C9RTOaGmR22S**************************FFB6uFy61jg",
        "startTime": 1693467116,
        "expiredTime": 1693467176
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    然后把这份临时密钥数据存到local Storage, 供后续的cos 存/取/删除对象使用,直到使用COS服务返回Request has expired 错误码后,那么再次通过/system/cos/get请求向服务器获取一次临时密钥,
    具体使用,身份证图片上传:

    	import upFile from '@/utils/upFile.js';
    			uploadKey(imgName) {
    				return "idCard/" + this.userInfo.id + '/' + imgName + '.jpg';
    			},
    			uploadIdImg(imgName) {
    				upFile.cosUpLoadFile({
    					uploadKey: this.uploadKey(imgName),
    				}).then(res => {
    					console.log(res);
    					if ('front' == imgName) {
    						this.formData.front = res.imgUrl;
    					} else {
    						this.formData.back = res.imgUrl;
    					}
    				})
    			},
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    那么,如何往cos服务存对象的呢?
    本质发了个put 的URL请求,这串url 的组成规则实际上为 https://[bucket].[region].myqcloud.com/{key}
    例如:

    https://gamioo2010-1***********.cos.ap-shanghai.myqcloud.com/idCard/11/back.jpg
    
    • 1

    正常情况下,会返回对象的存储地址,接下去就可以做后续的逻辑处理:

    {
        "imgUrl": "https://gamioo2010-***********.cos.ap-shanghai.myqcloud.com/idCard/11/front.jpg",
        "imgKey": "idCard/11/front.jpg"
    }
    
    • 1
    • 2
    • 3
    • 4

    如果返回Request has expired,

    PUT https://gamioo2010-***********.cos.ap-shanghai.myqcloud.com/idCard/11/back.jpg 403 (Forbidden)
    {"loaded":130736,"total":130736,"speed":274079.66,"percent":1}
     cos,postobject-err] AccessDenied: Request has expired
    at http://localhost:3200/node modules/.vite/deps/cos-js-sdk-v5.js?v=b340976d:9468:31
    at xhr.onload (htto://1ocalost:3200/node modules/vite/dens/cos-s-Sdk-V5.1S?V-b340976d:2469:15
    
    • 1
    • 2
    • 3
    • 4
    • 5

    则重新发起获取临时密钥的请求,直到完成该过程。

    总结

    本文主要列举了客户端在拿到临时密钥后,如何进行后续的COS操作,本文暂时只举例了存储的操作,至于其他的COS接口调用,调用方法类似,我们不再赘述。

    参考链接:
    对象存储快速入门
    上传对象

  • 相关阅读:
    个人简介网页设计作业 静态HTML个人介绍网页作业 DW个人网站模板下载 WEB静态大学生简单网页 个人网页作品代码 个人网页制作 学生个人网页
    如何检验下载的大模型checkpoint文件是否正确的解决方案
    方形图片 圆形图片 各种形状
    MySQL事务隔离级别
    MySQL使用CASE WHEN统计SQL语句代替子查询SQL统计,CASE WHEN常用写法,根据不同的条件对数据进行分类、分组和聚合
    香橙派Zero3安装miniconda3(问题多多,已全部解决)
    技术分享 | ClickHouse 冷热存储分离方案线上实践
    设计模式之【观察者模式】
    滴滴 OrangeFS 数据湖存储关键技术揭秘!
    Docker安装入门教程
  • 原文地址:https://blog.csdn.net/jiangguilong2000/article/details/132603206