前言
做过小程序的人大概都知道,由于小程序限制包的大小,所用的图片不会直接放在项目中,一般的处理方法都是上传到服务器利用http或者https请求的,虽然多了一些http的网络请求,但是能很好解决包大小的问题。我们项目是上传到腾讯云COS存储。
我们前端项目和小程序都用到了这种形式,vue项目用的是存储桶的形式,而小程序用的是直接上传到指定目录的形式,起始两种方式本质上实现的原理是一样的,使用方法也是大同小异。这里总结一下两种方式的不同实现供大家参考。
准备工作
首先你要知道腾讯云存储桶的一些必要信息,比如存储桶的名字、所属地域等。如果这些信息是由后台或者运维人员开通的,而恰好你本人不清楚的话,那么你可以咨询相关同事。但如果你有权限去查看这些信息的话,一样没有问题。
其次,为了安全考虑,一般每次上传,都要从后台获取一次临时密钥。密钥会包含一些key,token等信息。如果这些前提工作你都已经了解并清楚了,那么可以继续往下看~
我们将区分vue项目和小程序项目分开实现
VUE项目
1、一般前端项目我们依赖cos-js-sdk-v5
插件
npm i cos-js-sdk-v5 --save
2、引入模块
import COS from 'cos-js-sdk-v5'
3、存储桶可以POST上传或者PUT上传,PUT之前有些过一篇相关的,这次我们用POST上传实现。
上传对象到COS腾讯云时,需要携带临时签名。生成临时签名前需要先获取临时密钥
javascript
const urlObj = getUrlParams();
const cos = new COS({
getAuthorization: async function (options, callback) {
// 获取临时密钥
const url =`${baseUrl}/bgc-api/v1/annual/report/get-tmp-credential?oid=${ urlObj.oid || ''}`;
const xhr = new XMLHttpRequest();
let data = null;
let credentials = null;
xhr.open('GET', url, true);
xhr.onload = function (e) {
try {
data = JSON.parse(e.target.responseText);
credentials = data.data
} catch (e) {
//
}
if (!credentials) {
return console.error('credentials invalid:\n' + JSON.stringify(data, null, 2))
};
callback({
// 临时签名
TmpSecretId: credentials.tmpSecretId,
TmpSecretKey: credentials.tmpSecretKey,
SecurityToken: credentials.sessionToken,
StartTime: Math.floor(Date.now() / 1000), // 时间戳,单位秒,如:1580000000
ExpiredTime: Math.floor(credentials.expiredTime / 1000), // 时间戳,单位秒,如:1580000000
});
};
xhr.send();
}
});
// 上传文件
const upLoadFile = (ImageFile) => new Promise((resolve, reject) => {
cos.uploadFile({
Bucket: 'neststatic-1251316161', // 存储桶名称
Region: 'ap-nanjing', // 所属域名
Key: `bgc-applet/head_pic/${that.storeInfo.user_id}/year2023/${Math.floor(Math.random()*100000)}img.png`, // 路径
Body: ImageFile, // 文件
}, (err, data) => {
if (err) {
reject()
} else {
data.Location = `https://${data.Location}?timestamp=${Date.now()}`
resolve(data)
}
})
});
```js
```js
小程序项目
这里主要贴重要代码,与项目相关的删除
js
const prefix =
'https://' + config.Bucket + '.cos.' + config.Region + '.myqcloud.com'
// 上传文件
async function uploadFile(filePath, showLoad = true, cdnPath = 'head_pic', toWx = false) {//toWx是否上传到微信,上传到微信的时候,会加topng
if (showLoad)
wx.showLoading && wx.showLoading({
title: '上传中...',
})
// 这里给图片文件名开头加了个2位的随机数,不确定是否要上线
const random = Math.floor(Math.random()*100000);
// const Key = random + filePath.substr(filePath.lastIndexOf('/') + 1)// 这里指定上传的文件名
const Key = filePath.substr(filePath.lastIndexOf('/') + 1)// 这里指定上传的文件名
// 这里的就是获取的临时密钥和签名 与上述vue代码相同,不重复
const authData = await getAuthorization({ Method: 'POST', Pathname: '/' })
const res = await awx.uploadFile({
url: prefix,
name: 'file',
filePath: filePath,
formData: {
key: `/bgc-applet/${cdnPath}//${random}/` + Key,
success_action_status: 200,
Signature: authData.Authorization,
'x-cos-security-token': authData.XCosSecurityToken,
'Content-Type': '',
},
})
if (showLoad) wx.hideLoading && wx.hideLoading()
if (res.statusCode === 200) {
// return res.header.Location
if(toWx) {
return (
prefix +
`/bgc-applet/${cdnPath}//${random}/` +
encodeURIComponent(Key)
)
} else {
return (
prefix +
`/bgc-applet/${cdnPath}//${random}/` +
encodeURIComponent(Key) +
`?timestamp=${Date.now()}`
)
}
} else {
wx.showToast({
title: '上传失败',
icon: 'none',
duration: 1000,
})
return
}
}