腾讯云 - 对象存储
这里主要也是做一个归纳整理,项目中接入了对象存储,选择了腾讯云。目前项目是用 uniapp
开发的,所以这里主要还是围绕 :
- 如何创建存储桶
- 小程序怎么引入
- 引入后如何使用
针对小程序相关的图片、视频、文件上传进行说明。
创建存储桶
首先,登录 腾讯云
后,从 控制台
中进入,找到 对象存储
,进入下图页面。
概览 -> 创建存储桶
选择区域,填写名称,勾选对应的访问权限
- 区域: 选择离自己城市最近的区域
- 名称: 自行填写
- 权限: 如果想要在公共地方能访问到,需要勾选公有读相关的,否则别人访问不了。
存储桶配置
- cors 跨域
- 防盗链
这里暂时省略
下载SDK
点击此处 腾讯云SDK 进行选择自己项目对应的SDK。由于这里我是在小程序中使用,所以这里选择了小程序的SDK进行下载,选择快速下载地址,直接获取对应的js文件
SDK引入
把下载好的文件,放入 utils
中
utils
└── cos-wx-sdk-v5.min.js
封装方法
配置信息
文件路径:
utils
└── upload.js
准备好 Bucket
和 Region
,以及创建一个 cos对象
。上传方式为 putObject
javascript
// 引入SDK
var COS = require('./cos-wx-sdk-v5.min');
// 存储桶信息
const config = {
Bucket: '', // 存储桶的名称,命名规则为 BucketName-APPID,此处填写的存储桶名称必须为此
Region: '', // 存储桶所在地域 例如ap-beijing,必须字段
};
// 存储桶相关秘钥
var cos = new COS({
SecretId: '',
SecretKey: '',
SimpleUploadMethod: 'putObject'
})
对象存储方法
🏷️ 参数
属性名 | 说明 | 类型 | 必填 |
---|---|---|---|
filePath | 文件地址 | string | 是 |
fileName | 文件名称 | string | 是 |
dirPath | 文件存储目录(这个需要在存储桶中先创建好) | string | 是 |
javascript
export function UploadFile(filePath,fileName,dirPath) {
return new Promise(function(resolve, reject) {
let percent = null;
// 调用 cos.postObject 方法
cos.postObject({
Bucket: config.Bucket, /* 必须 */
Region: config.Region, /* 必须 */
Key: `/${dirPath}/${fileName}`, /* 必须 */
FilePath: filePath,
onProgress: function (info) {
// 上传进度
percent = info.percent;
console.log("[cos.postObject-seccess]",JSON.stringify(info));
}
}, function(err, data) {
console.log("[cos.postObject-err]",err || data);
// data.headers.location 是上传后返回的完整路径 https://..., 开启版本号之后就不用这个了
// let encodedUrl = encodeURI(data.headers.location);
// console.log(encodedUrl);
let completeUrl = '';
if(data.VersionId != '' || data.VersionId != null) {
// 这里是因为同名文件会被覆盖,所以开启了版本号
completeUrl = `https://${data.Location}?versionId=${data.VersionId}`;
} else {
completeUrl = `https://${data.Location}`
}
let result = {
uploadUrl: completeUrl,
statusCode: data.statusCode,
progress: percent,
}
resolve(result)
});
})
}
传入数组或者单个变量判断
javascript
export async function handleUploadOSSImages(images,fileType) {
if (!Array.isArray(images)) {
// 处理单个变量
if(images.startsWith('http://tmp')) {
let filePath = images;
let fileName = filePath.substr(filePath.lastIndexOf('/') + 1);
let result = await UploadFile(filePath,fileName,fileType);
if(result.statusCode === 200) {
return result.uploadUrl;
}
}
return images
} else {
// 处理数组
let results = await Promise.all(images.map(async (image) => {
if(image.startsWith('http://tmp')) {
let filePath = image;
let fileName = filePath.substr(filePath.lastIndexOf('/') + 1);
let result = await UploadFile(filePath,fileName,fileType);
if(result.statusCode === 200) {
return result.uploadUrl;
}
}
return image
}));
return results;
}
}
页面中使用
因为避免浪费上传流量,以及占用存储空间。我这里对图片、视频等文件上传时,会先把上传后的本地缓存地址存储在绑定的变量中,当用户最后点击确定时,在对文件进行上传进对象存储,然后返回的地址与表单数据一起返回给后端接口。
这样会避免用户在上传之后,突然需要换一张,或者又不传了,不会一直都在调用对象存储。
javascript
import { UploadFile, handleUploadOSSImages } from '@/utils/upload.js';
export default {
data() {
return {
shopInfo: {
shopHead: "", //店铺头像
Carousel: [], // 轮播图数组
video: '', // 视频
},
}
},
methods: {
async handleSubmit() {
...
let that = this;
uni.showModal({
title: '提示',
content: '是否保存当前修改?',
async success(res) {
if (res.confirm) {
// 当用户点击确认时,调用上传对象存储方法
// upload_img, upload_video 存储桶中的文件夹名称
that.shopInfo.shopHead = await handleUploadOSSImages(that.shopInfo.shopHead,'upload_img');
// 还可以这样写
// let shopHead = await handleUploadOSSImages(that.shopInfo.shopHead,'upload_img');
// let Carousel = await handleUploadOSSImages(that.shopInfo.Carousel,'upload_img');
// let videoUrl = '';
// if(that.shopInfo.video) {
// videoUrl = await handleUploadOSSImages(that.shopInfo.video,'upload_video');
// }
// 后端接口交互
...
}
}
});
},
},
}
上述的例子,调用的是 handleUploadOSSImages
方法。因为一个表单页,有时候上传的图片文件不一定是单个字符串的,有时候也可能是数组,比如轮播图这样的。所以专门封装了一个方法用于判断是否为数组,且在方法中引入了 UploadFile
对象存储的方法,所以使用的时候只要用这一个即可。
如果单纯使用 UploadFile
方法,用法也是一致的。
javascript
import { UploadFile } from '@/utils/upload.js';
export default {
data() {
return {
shopInfo: {
shopHead: "", //店铺头像
Carousel: [], // 轮播图数组
video: '', // 视频
},
}
},
methods: {
async handleSubmit() {
...
let that = this;
uni.showModal({
title: '提示',
content: '是否保存当前修改?',
async success(res) {
if (res.confirm) {
let shopHead = await UploadFile(that.shopInfo.shopHead,'upload_img');
let videoUrl = '';
if(that.shopInfo.video) {
videoUrl = await UploadFile(that.shopInfo.video,'upload_video');
}
// 如果是轮播图数据,需要先遍历轮播图,再循环调用 UploadFile 方法
// 后端接口交互
...
}
}
});
},
},
}