Skip to content
On this page
🎨 作者:Jacinda 📔 阅读量:

腾讯云 - 对象存储

这里主要也是做一个归纳整理,项目中接入了对象存储,选择了腾讯云。目前项目是用 uniapp 开发的,所以这里主要还是围绕 :

  • 如何创建存储桶
  • 小程序怎么引入
  • 引入后如何使用

针对小程序相关的图片、视频、文件上传进行说明。

创建存储桶

首先,登录 腾讯云 后,从 控制台 中进入,找到 对象存储,进入下图页面。

  • 概览 -> 创建存储桶

    图 0

  • 选择区域,填写名称,勾选对应的访问权限

    • 区域: 选择离自己城市最近的区域
    • 名称: 自行填写
    • 权限: 如果想要在公共地方能访问到,需要勾选公有读相关的,否则别人访问不了。

    图 1

存储桶配置

  • cors 跨域
  • 防盗链

这里暂时省略

下载SDK

点击此处 腾讯云SDK 进行选择自己项目对应的SDK。由于这里我是在小程序中使用,所以这里选择了小程序的SDK进行下载,选择快速下载地址,直接获取对应的js文件

图 2

SDK引入

把下载好的文件,放入 utils

utils
└── cos-wx-sdk-v5.min.js

封装方法

配置信息

文件路径:

utils
└── upload.js

准备好 BucketRegion,以及创建一个 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 方法
                        // 后端接口交互
                        ...
                    }
                }
            });
        },
    },
}