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

简介

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

前言

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

引入库

package.json里添加如下的库

javascript 复制代码
  "dependencies": {
    "cos-js-sdk-v5": "^1.4.20"
  }

具体使用

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

javascript 复制代码
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
}

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

yaml 复制代码
{
  "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
  }
}

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

具体使用,身份证图片上传:

javascript 复制代码
	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;
					}
				})
			},

那么,如何往cos服务存对象的呢?

本质发了个put 的URL请求,这串url 的组成规则实际上为 https://[bucket].[region].myqcloud.com/{key}

例如:

bash 复制代码
https://gamioo2010-1***********.cos.ap-shanghai.myqcloud.com/idCard/11/back.jpg

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

bash 复制代码
{
    "imgUrl": "https://gamioo2010-***********.cos.ap-shanghai.myqcloud.com/idCard/11/front.jpg",
    "imgKey": "idCard/11/front.jpg"
}

如果返回Request has expired,

bash 复制代码
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

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

总结

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

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

相关推荐
前端青山44 分钟前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
从兄2 小时前
vue 使用docx-preview 预览替换文档内的特定变量
javascript·vue.js·ecmascript
清灵xmf3 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
薛一半4 小时前
PC端查看历史消息,鼠标向上滚动加载数据时页面停留在上次查看的位置
前端·javascript·vue.js
过期的H2O24 小时前
【H2O2|全栈】JS进阶知识(四)Ajax
开发语言·javascript·ajax
MarcoPage4 小时前
第十九课 Vue组件中的方法
前端·javascript·vue.js
你好龙卷风!!!5 小时前
vue3 怎么判断数据列是否包某一列名
前端·javascript·vue.js
shenweihong7 小时前
javascript实现md5算法(支持微信小程序),可分多次计算
javascript·算法·微信小程序
巧克力小猫猿7 小时前
基于ant组件库挑选框组件-封装滚动刷新的分页挑选框
前端·javascript·vue.js
嚣张农民7 小时前
一文简单看懂Promise实现原理
前端·javascript·面试