uniapp 实现腾讯云 COS 存储(跨平台文件管理)
·
uniapp 实现腾讯云 COS 存储全攻略(跨平台文件管理)
引言
腾讯云对象存储(COS)提供高可用、低成本的存储方案,本文将手把手教你如何在 uniapp 中实现 图片/视频/文件 的上传、下载、删除全流程,支持 App/H5/小程序 全端运行。
一、技术选型对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| 直传 COS | 简单快速 | 需暴露永久密钥 |
| 临时密钥签名 | 安全性高 | 需开发后端接口 |
| 客户端签名 | 无需后端 | 仅限简单场景 |
推荐方案:临时密钥签名(兼顾安全与便捷)
二、完整实现步骤
1. 准备工作
1.1 注册腾讯云账号
- 访问 COS 控制台
- 创建存储桶(Bucket),记录以下信息:
- 地域:如
ap-guangzhou - 存储桶名称:如
example-1250000000
- 地域:如
1.2 安装 COS SDK
npm install cos-js-sdk-v5 --save
2. 初始化 COS 客户端
// utils/cos.js
import COS from 'cos-js-sdk-v5';
// 获取临时密钥(需通过后端接口)
async function getTempCredentials() {
// 实际开发中应通过云函数或自有服务获取
return {
TmpSecretId: 'AKIDxxxxxxxx',
TmpSecretKey: 'xxxxxxxx',
XCosSecurityToken: 'xxxxxxxx',
ExpiredTime: 1720000000
};
}
export async function createCOSClient() {
const credentials = await getTempCredentials();
return new COS({
getAuthorization: function (options, callback) {
callback({
TmpSecretId: credentials.TmpSecretId,
TmpSecretKey: credentials.TmpSecretKey,
XCosSecurityToken: credentials.XCosSecurityToken,
ExpiredTime: credentials.ExpiredTime
});
}
});
}
3. 核心功能实现
3.1 文件上传(分片上传示例)
async function uploadFile(filePath) {
const client = await createCOSClient();
return new Promise((resolve, reject) => {
client.sliceUploadFile({
Bucket: 'example-1250000000',
Region: 'ap-guangzhou',
Key: `images/${Date.now()}_${filePath.name}`, // 文件路径规则
Body: filePath,
onProgress: function(info) {
const percent = parseInt(info.percent * 100);
uni.showLoading({ title: `上传中 ${percent}%` });
}
}, (err, data) => {
uni.hideLoading();
if (err) return reject(err);
resolve(data.Location); // 返回文件访问URL
});
});
}
// 使用示例
uni.chooseImage({
success: async (res) => {
const filePath = res.tempFilePaths[0];
try {
const url = await uploadFile(filePath);
console.log('上传成功:', url);
} catch (err) {
uni.showToast({ title: '上传失败', icon: 'none' });
}
}
});
3.2 文件下载
async function downloadFile(fileUrl) {
const client = await createCOSClient();
return new Promise((resolve, reject) => {
client.getObjectUrl({
Bucket: 'example-1250000000',
Region: 'ap-guangzhou',
Key: getKeyFromUrl(fileUrl), // 从URL解析文件Key
Sign: true, // 生成带签名的临时URL
Expires: 60 // 有效期60秒
}, (err, data) => {
if (err) return reject(err);
// 跳转下载
uni.downloadFile({
url: data.Url,
success: (res) => {
if (res.statusCode === 200) {
uni.saveFileToPhotosAlbum({
filePath: res.tempFilePath
});
}
}
});
});
});
}
3.3 文件删除
async function deleteFile(fileKey) {
const client = await createCOSClient();
return new Promise((resolve, reject) => {
client.deleteObject({
Bucket: 'example-1250000000',
Region: 'ap-guangzhou',
Key: fileKey
}, (err, data) => {
if (err) return reject(err);
resolve(data);
});
});
}
4. 跨平台适配处理
4.1 H5 端特殊配置
// 配置CORS规则(需在COS控制台设置)
{
"AllowedOrigin": ["*"],
"AllowedMethod": ["PUT", "GET", "POST", "DELETE"],
"AllowedHeader": ["*"]
}
4.2 小程序端限制处理
// 小程序需使用chooseMessageFile代替chooseImage
uni.chooseMessageFile({
count: 1,
type: 'file',
success: (res) => {
// 处理文件上传
}
});
三、性能优化技巧
1. 大文件上传优化
// 使用分片上传(默认已启用)
client.sliceUploadFile({
// ...
SliceSize: 1024 * 1024 * 5, // 每片5MB
Threads: 3 // 并发线程数
});
2. 断点续传实现
// 记录上传进度到本地存储
uni.setStorageSync(`upload_${fileKey}`, progress);
// 初始化时检查续传状态
const savedProgress = uni.getStorageSync(`upload_${fileKey}`);
if (savedProgress) {
// 恢复上传
}
3. 图片压缩处理
// 使用uni-app内置压缩
uni.compressImage({
src: filePath,
quality: 80,
success: (res) => {
uploadFile(res.tempFilePath);
}
});
四、常见问题解决
Q1: 上传报错 “No Permission”
- 检查存储桶权限策略
- 确认临时密钥有效性
- 验证文件路径是否包含特殊字符
Q2: 小程序无法选择文件
- 添加文件类型白名单:
{ "pages": ["pages/index/index"], "permission": { "scope.writePhotosAlbum": { "desc": "需要您的授权才能保存文件" } }, "requiredPrivateInfos": ["chooseFile"] }
Q3: 下载文件无法打开
- 检查文件MIME类型
- 添加Content-Disposition头:
client.getObject({ // ... ResponseHeaderOverrides: { 'Content-Disposition': `attachment; filename="${encodeURIComponent(fileName)}"` } });
五、扩展功能建议
- 文件管理:实现文件夹分类、文件重命名
- 访问控制:设置私有读/公开读权限
- 图片处理:集成COS的图片处理参数(如?imageMogr2)
- 日志监控:通过CAM接口记录操作日志
总结
通过本文教程,你已掌握在UniApp中实现腾讯云COS存储的核心技术。完整流程可总结为:
- 准备COS存储资源
- 安全获取临时凭证
- 实现上传/下载/删除基础功能
- 优化性能与跨平台兼容性
💡 提示:生产环境建议将COS操作封装为独立模块,通过Promise链式调用管理异步流程。
参考文档
更多推荐
所有评论(0)