最近在做用uni-app做项目的时候,需要把所有的文件资源全部存储cos里,这样就涉及到了小程序端以及H5 ,所以写了这个轮子,方便调用所以造了这个轮子
再讲一下为什么需要把资源上传到cos,如果我们不将资源放到cos 那么就是存储到自己的服务器上,可是我们在获取资源的时候,这样对服务器的内存以及硬盘消耗都是十分大的,反观我们存储到cos 上再用cdn进行资源缓存,使得图片加载极快, 这样就成了一个比较好的解决方案

下载链接:https://github.com/tencentyun/cos-wx-sdk-v5/tree/master/demo/lib

在这里插入图片描述

下载链接:https://github.com/tencentyun/cos-js-sdk-v5/tree/master/dist

在这里插入图片描述

两个核心文件准备好了,那我们就好开始造轮子了

我把微信的js sdk 命名为cos.js 网站H5的cos 命名为h5cos.js,再新建一个js文件,我的命名为upload.js 用来编写上传逻辑

以下为upload.js 代码
// #ifdef MP
//在小程序中引入小程序的sdk
var COS = require('./cos');
// #endif
// #ifdef H5
//在H5中引入小程序的sdk
var COS = require('./h5cos')
// #endif
var config = {
	Bucket: '****',//可在腾讯云对象存储中自己查看创建的
	Region: '****',//可在腾讯云中自己查看自己查看创建的
	baseUrl:“你的主域名”
}
//此函数是用来向后端请求获取cos的临时密钥的。
function getCosToken(type) {
	return new Promise(function(resolve, reject) {
		uni.request({
			url: config.baseUrl + '/api/auth/cos, // 步骤二提供的签名接口
			header: {
				'x-token': store.getters.Token
			},
			data: {
				bucket: config.cos.Bucket,
				region: config.cos.Region,
			},
			success: function(result) {
				var data = result.data.data;
				resolve(data)
			},
			fail: function(res) {
				reject(res)
			}
		})
	})
};

//此函数是用来返回 初始化COS对象所需要的参数
function param(key, file, backfun) {
	return {
		Bucket: config.cos.Bucket, // Bucket 格式:test-1250000000
		Region: config.cos.Region,
		Key: key,
		FilePath: file, //小程序中主要使用FilePath
		Body: file, //H5中使用 Body
		onTaskReady: function(tid) {
			// 准备上传
		},
		onTaskStart: function(info) {
			//开始上传
		},
		onProgress: function(progressData) {
			//上传进度回调
			backfun(progressData)
		}
	}
}

//此函数是用来处理上传结果的
//@resback 成功之后的回调函数 
//@errorback 错误之后的回调
function back(err, data, resback,errorback) {
	if (err != null) {
		errorback(err.error)
	} else {
		data.Location = "https://" + data.Location
		resback(data)
	}
}

//此函数用于初始化Cos对象 以及上传文件
function putObject(file, type, filename, backfun, resback,errorback) {
	getCosToken(type).then(function(data) {
		var credentials = data.Credentials
		//console.log(credentials)
		var cos = new COS({
			getAuthorization: function(options, callback) {
				callback({
					//以下返回数据请先console.log 打印查看
					TmpSecretId: credentials.TmpSecretId,
					TmpSecretKey: credentials.TmpSecretKey,
					XCosSecurityToken: credentials.Token,
					StartTime: data.StartTime,
					ExpiredTime: data.ExpiredTime,
				})
			}
		});
		let key = type + "/" + filename
		// #ifdef MP
		//小程序需要调用postObject 上传
		cos.postObject(param(key, file, backfun), function(err, data) {
			back(err, data, resback,errorback)
		});
		// #endif
		// #ifdef H5
		//H5需要调用putObject 上传
		cos.putObject(param(key, file, backfun), function(err, data) {
			back(err, data, resback,errorback)
		});
		// #endif
	}).catch(err=>{
		errorback(err.error)
	})
}

//对外的上传接口轮子
//@file:获取到的文件path
//@key:上传到对象存储的文件名
//@dir:上传对象存储的目录
//@speedback:上传进度回调
//@resback:上传成功回调
//@errorback:上传错误回调
export function upload(file, key, dir, speedback, resback,errorback) {
	putObject(file, key, dir, speedback, resback,errorback)
}

我们在其他文件只需要导入 upload 函数即可实现上传文件,自此前端的轮子已经造好了

GO 后端返回临时密钥,可查看官方文档

var secretID, secretKey = "**", "**"

// Cos 获取Cos上传的临时密钥
func Cos(c *gin.Context) {
	var path = c.Query("type")
	if path == "" {
		rmsg.Error(c, errors.New("文件类型不能为空"))
		return
	}
	appid := "***"
	bucket := "***"
	region := "***"
	client := sts.NewClient(
		secretID,
		secretKey,
		nil,
	)
	opt := &sts.CredentialOptions{
		DurationSeconds: int64(time.Hour.Seconds()),
		Region:          region,
		Policy: &sts.CredentialPolicy{
			Statement: []sts.CredentialPolicyStatement{
				{
					Action: []string{
						"name/cos:PutObject",
						"name/cos:PostObject",
						"name/cos:InitiateMultipartUpload",
						"name/cos:ListMultipartUploads",
						"name/cos:ListParts",
						"name/cos:UploadPart",
						"name/cos:CompleteMultipartUpload",
					},
					Effect: "allow",
					Resource: []string{
						"qcs::cos:" + region + ":uid/" + appid + ":" + bucket + "/" + path + "/*",
					},
				},
			},
		},
	}
	if res, err := client.GetCredential(opt); err != nil {
		rmsg.Error(c, err)
	} else {
		rmsg.Success(c, "cos 临时密钥初始化成功", res)
	}
}