最近在做用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)
}
}