简体中文
开发者使用uniCloud
的云存储,无需再像传统模式那样单独去购买存储空间、CDN映射、流量采购等;
云存储的上传方式有3种:
uniCloud.uploadFile
,或者使用uni ui的FilePicker组件,文件选择+上传均封装完毕。uniCloud.uploadFile
注意:
uniCloud.uploadFile
。请不要混淆。uni.uploadFile
的API,那个API用于连接非uniCloud的上传使用。请不要混淆。The requested URL '/1123.jpg' was not found on this server
这种错误,一般是cdn流量用尽导致的,可以升级套餐或转为按量计费。阿里云的云存储有一些限制:
腾讯云没有上述限制。
uniCloud腾讯云版支持云存储的文件权限。当上传的文件不希望被其他人访问时,需配置权限。比如身份证照片。
首先在uniCloud web控制台,腾讯云的服务空间中,可以配置云存储的权限。如果是隐私文件,应该配置为仅管理员可访问。
在云函数中,通过uniCloud.getTempFileURL
(见下),获取该文件的临时URL。然后将临时URL发给客户端,客户端根据临时URL请求云存储的文件。
支付宝小程序云和腾讯云支持以上传时指定的cloudPath作为文件路径进行文件存储。
阿里云在HBuilderX 3.8.5
及之后版本支持以上传时指定的cloudPath作为文件路径进行文件存储,需要在上传时指定参数cloudPathAsRealPath: true
来启用目录支持。为兼容旧版阿里云表现cloudPathAsRealPath
默认为false
。对于客户端和本地云函数此调整在HBuilderX 3.8.5
及之后的版本生效,对于云端云函数此调整自2023年6月17日生效。
阿里云在cloudPathAsRealPath
为false
时传的文件都存储在cloudstorage
目录下,2023年6月17日起访问uniCloud web控制台云存储页面可以看到目录结构。需要注意cloudPathAsRealPath
为true
时,云函数使用同样的cloudPath上传文件会覆盖旧文件,客户端使用同样的cloudPath则会报policy_does_not_allow_file_overwrite
。
阿里云文件列表在控制台支持两种模式:
名称正序排序
。更新时间倒序排序
。开发者可结合两种模式来上传及查看文件。
在uni-app前端进行云存储的操作(不是在云函数里操作),包括在前端上传、删除文件。
腾讯云支持配置云存储权限,需搭配腾讯云自定义登录使用,详情:自定义登录
支付宝小程序云与阿里云不支持控制前端访问云储存的权限
云存储客户端api内部会使用uni.request
、uni.uploadFile
来发送请求,如果有这两个接口写拦截器务必准确区分要拦截的内容
直接上传文件到云存储。
客户端上传文件到云函数、云函数再上传文件到云存储,这样的过程会导致文件流量带宽耗费较大。所以一般上传文件都是客户端直传。
支付宝小程序云、阿里云、腾讯云的单文件大小限制为5GB
支付宝小程序开发工具上传文件到腾讯云时可能会返回失败,请以真机为准
各个小程序平台运行时,网络相关的 API 在使用前需要配置域名白名单。参考
已知问题
Object object
参数名 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
filePath | String | 是 | - | 要上传的文件对象 | - |
cloudPath | String | 是 | - | 使用支付宝小程序云或腾讯云时,表示文件的绝对路径,包含文件名。 使用阿里云时, cloudPath 为云端文件名,传cloudPathAsRealPath: true 可以让cloudPath作为文件存储路径 | - |
cloudPathAsRealPath | Boolean | 否 | false | 是否以cloudPath 作为云端文件绝对路径 | 仅阿里云支持 |
fileType | String | - | - | 文件类型,支付宝小程序、钉钉小程序必填,可选image、video、audio | - |
onUploadProgress | Function | 否 | - | 上传进度回调 | - |
注意
cloudPath
为云端文件名,请勿使用非法字符cloudPath
为文件的绝对路径,包含文件名 foo/bar.jpg、foo/bar/baz.jpg 等,不能包含除[0-9 , a-z , A-Z]、/、!、-、_、.、、*和中文以外的字符,使用 / 字符来实现类似传统文件系统的层级结构。cloudPath
为文件标识,相同的cloudPath
会覆盖,如果没有权限覆盖则会上传失败。阿里云以自动生成的ID为文件标识,不会存在覆盖问题关于腾讯云是否有权限覆盖/删除云端文件
腾讯云使用自定义登录的方式确定用户身份。以下以默认权限”所有用户可读,仅创建者及管理员可写“为例进行讲解
默认情况下用户以匿名身份登录(为了方便暂时称此身份为“匿名用户A”)
匿名用户A身份过期之后再次获取的身份并不是”匿名用户A“(暂记为”匿名用户B“),这时匿名用户B是没有权限覆盖匿名用户A上传的文件的。
如果使用了自定义登录,那么云存储就可以确定用户身份,这时候用户可以覆盖自己上传的文件,删除同理。
字段 | 类型 | 说明 |
---|---|---|
fileID | String | 文件唯一 ID,用来访问文件,建议存储起来 |
requestId | String | 请求序列号,用于错误排查 |
//前端代码
uni.chooseImage({
count: 1,
success(res) {
console.log(res);
if (res.tempFilePaths.length > 0) {
let filePath = res.tempFilePaths[0]
//进行上传操作
// promise方式
const result = await uniCloud.uploadFile({
filePath: filePath,
cloudPath: 'a.jpg',
onUploadProgress: function(progressEvent) {
console.log(progressEvent);
var percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
}
});
// callback方式,与promise方式二选一即可
uniCloud.uploadFile({
filePath: filePath,
cloudPath: 'a.jpg',
onUploadProgress: function(progressEvent) {
console.log(progressEvent);
var percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
},
success() {},
fail() {},
complete() {}
});
}
}
});
Tips
在客户端把文件的fileid转换为临时URL。临时URL有有效期限制,避免其他人获取URL后可以持续访问该文件。
平台兼容性
阿里云 | 腾讯云 | 支付宝小程序云 |
---|---|---|
√ | √ | √ |
支付宝小程序云与腾讯云获取文件临时下载链接。
自HBuilderX 3.1.0起阿里云也支持此接口,但仅为抹平和腾讯云的接口差异。因为阿里云的云存储不支持权限控制。
字段 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
fileList | Array<String> | 是 | - | 要获取下载链接的文件 ID 组成的数组 | - |
请求参数中的fileList
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
fileID | String | 是 | 文件 ID |
字段 | 类型 | 说明 |
---|---|---|
fileList | Array<Object> | 存储下载链接的数组 |
requestId | String | 请求序列号,用于错误排查 |
响应参数中的fileList
字段 | 类型 | 说明 |
---|---|---|
fileID | String | 文件 ID |
tempFileURL | String | 文件访问链接 |
// 客户端获取临时文件示例源码
// promise方式
uniCloud.getTempFileURL({
fileList: ['cloud://test-28farb/a.png']
})
.then(res => {});
// callback方式,与promise方式二选一
uniCloud.getTempFileURL({
fileList: ['cloud://test-28farb/a.png'],
success() {},
fail() {},
complete() {}
});
阿里云迁移服务空间后,旧云存储url需要通过此接口获取新服务空间的cdn链接
平台兼容性
阿里云 | 腾讯云 | 支付宝小程序云 |
---|---|---|
HBuilderX 3.6.10+(Alpha版)、HBuilderX 3.6.5+(正式版) | 不支持 | 不支持 |
字段 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
fileList | Array<String> | 是 | - | 要获取下载链接的文件 ID 组成的数组 | - |
请求参数中的fileList
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
fileID | String | 是 | 旧云存储url |
字段 | 类型 | 说明 |
---|---|---|
fileList | Array<Object> | 存储下载链接的数组 |
响应参数中的fileList
字段 | 类型 | 说明 |
---|---|---|
fileId | string | 文件 ID(从文件url中解析出的id) |
gmtCreate | number | 文件上传时间(精确到秒的时间戳) |
gmtModified | number | 文件更改时间(精确到秒的时间戳) |
name | string | 文件原始名称 |
size | number | 文件大小(Byte) |
type | string | 文件类型 |
url | string | 文件cdn链接 |
HBuilderX 3.1.0起支持
通过ui界面选择文件(图片/视频)并直接上传到云存储。
同时提供了选择回调事件,方便对选择后的图片进行压缩等二次处理,然后再上传。
此接口根据type不同接收兼容性也略有差异
选择图片,type:'image'
App | H5 | 微信小程序 | 支付宝小程序 | 百度小程序 | 抖音小程序、飞书小程序 | QQ小程序 | 快手小程序 | 京东小程序 |
---|---|---|---|---|---|---|---|---|
√ | √ | √ | √ | √ | √ | √ | √ | √ |
选择视频,type:'video'
App | H5 | 微信小程序 | 支付宝小程序 | 百度小程序 | 抖音小程序、飞书小程序 | QQ小程序 | 快手小程序 | 京东小程序 |
---|---|---|---|---|---|---|---|---|
√ | √ | √ | √ | √ | √ | √ | √ | √ |
选择任意文件,type:'all'
App | H5 | 微信小程序 | 支付宝小程序 | 百度小程序 | 抖音小程序、飞书小程序 | QQ小程序 | 快手小程序 | 京东小程序 |
---|---|---|---|---|---|---|---|---|
× | √ | √(仅支持选择聊天文件) | × | × | × | × | × | × |
此接口根据type不同接收不同参数
选择图片,type:'image'
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
type | String | 是 | 文件类型,image(图片)、video(视频)、all(任意文件) |
count | Number | 否 | 文件数量,默认9 |
extension | Array | 否 | 文件后缀 |
sizeType | Array | 否 | original 原图,compressed 压缩图,默认二者都有,type为image时生效 |
sourceType | Array | 否 | album 从相册选图,camera 使用相机,默认二者都有 |
选择视频,type:'video'
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
type | String | 是 | 文件类型,image(图片)、video(视频)、all(任意文件) |
extension | Array | 否 | 文件后缀 |
camera | String | 否 | 摄像切换,front(前置摄像头)、back(后置摄像头) |
compressed | Boolean | 否 | 是否压缩所选的视频源文件,默认值为true,需要压缩,type |
sourceType | Array | 否 | album 从相册选图,camera 使用相机,默认二者都有 |
选择文件,type:all
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
type | String | 是 | 文件类型,image(图片)、video(视频)、all(任意文件) |
count | Number | 否 | 文件数量 |
extension | Array | 否 | 文件后缀 |
说明
onChooseFile(Object OnChooseFileRes)
选择图片的回调事件。方便对选择后的图片进行压缩、裁剪等二次处理,然后再上传。
OnChooseFileRes结构如下
{
errMsg: '',
tempFilePaths: [], // 临时文件路径数组,chooseVideo/chooseImage/chooseFile接口返回的tempFilePath组成的数组
tempFiles: [] // 临时文件组成的数组
}
如果onChooseFile回调有返回值,此返回值会用来替换实际选择的文件,用以上传。可以在此回调内对文件进行额外的处理,通过在onChooseFile内返回一个promise来阻塞上传,在此期间可以对文件进行额外处理。
例:
function cropImg(file) {
return new Promise((resolve, reject) => {
let ext
let filePathProcessed = file.path // 处理结果
// #ifdef H5
ext = file.name.split('.').pop()
resolve({
path: filePathProcessed,
ext,
fileType: file.fileType
})
// #endif
// #ifndef H5
uni.getImageInfo({
src: file.path,
success(info) {
ext = info.type.toLowerCase()
resolve({
path: filePathProcessed,
ext,
fileType: file.fileType
})
},
fail(err) {
reject(new Error(err.errMsg || '未能获取图片类型'))
}
})
// #endif
})
}
uniCloud.chooseAndUploadFile({
type: 'image',
onChooseFile(res) {
const processAll = []
for (let i = 0; i < res.tempFiles.length; i++) {
processAll.push(cropImg(res.tempFiles[i]))
}
return Promise.all(processAll).then((fileList) => {
let result = {
tempFilePaths: []
}
result.tempFiles = fileList.map((fileItem, index) => {
result.tempFilePaths.push(fileItem.path)
return {
path: fileItem.path,
cloudPath: '' + Date.now() + index + '.' + fileItem.ext, // 云端路径,这里随便生成了一个
fileType: fileItem.fileType
}
})
return result
})
}
}).then(res => {
console.log(res)
})
OnUploadProgress(Object OnUploadProgressRes)
上传进度的回调
OnUploadProgressRes结构如下
{
index: 0, // 触发此回调的文件序号
loaded: 256, // 已上传大小
total: 1024, // 总大小
tempFilePath: '', // 本地临时文件路径
tempFile: {} // 本地文件对象
}
成功回调内的响应参数形式如下
{
errMsg: '', // 错误信息
tempFilePaths: [], // 本地临时文件路径组成的数组
tempFiles: [] // 文件对象数组,每项上都被追加了一个url属性,值为文件上传得到的fileID
}
// promise方式
uniCloud.chooseAndUploadFile({
type: 'image'
})
.then(res => {});
// callback方式,与promise方式二选一
uniCloud.chooseAndUploadFile({
type: 'image',
success(res) {},
fail() {},
complete() {}
});
客户端删除云存储文件。
不建议使用此API。删除云存储文件是一个高危操作,应该由云函数进行权限校验后由云函数来删除云存储的文件。
Object object
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
fileList | <Array>.String | 是 | 要删除的文件 ID 组成的数组 |
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
fileList | <Array>.Object | 否 | 删除结果组成的数组 |
requestId | String | 否 | 请求序列号,用于错误排查 |
fileList定义
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
fileID | String | 是 | 文件 ID |
// 客户端删除云文件示例源码
// promise
uniCloud
.deleteFile({
fileList: ['cloud://jimmytest-088bef/1534576354877.jpg']
})
.then(res => {});
// callback
uniCloud.deleteFile(
{
fileList: ['cloud://jimmytest-088bef/1534576354877.jpg'],
success(){},
fail(){},
complete(){}
}
);
某些场景下需要使用客户端未关联的服务空间的云存储,此时可以通过uniCloud.init方法获取对应空间的实例用于上传文件
示例代码
const storageSpace = uniCloud.init({
provider: 'aliyun',
spaceId: 'mp-xxxx',
clientSecret: 'xxxx',
endpoint: 'https://api.next.bspapp.com'
})
const uploadRes = await storageSpace.uploadFile({
filePath: '',
cloudPath: ''
})
在云函数中操作云存储文件(不是在前端),包括在云函数里上传、删除云存储文件。
云函数内上传文件至云存储。
如果是从客户端上传文件,一般不建议先把文件从客户端上传到云函数,再由云函数上传到云存储,而是建议客户端直传云存储。详见:https://uniapp.dcloud.io/uniCloud/storage?id=uploadfile
平台兼容性
阿里云 | 腾讯云 | 支付宝小程序云 |
---|---|---|
√ | √ | √ |
HBuilderX 3.1.0之前版本如使用阿里云,请在客户端通过uniCloud.uploadFile
进行上传
uploadFileOptions参数说明
字段 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
cloudPath | string | 是 | - | 使用腾讯云或支付宝小程序云时,表示文件的绝对路径,包含文件名。 使用阿里云时, cloudPath 为云端文件名,传cloudPathAsRealPath: true 可以让cloudPath作为文件存储路径 | |
fileContent | - | 是 | - | 文件内容,请看下方说明 | |
cloudPathAsRealPath | Boolean | 否 | false | 是否以cloudPath 作为云端文件绝对路径 | 仅阿里云支持 |
说明
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
fileID | fileID | 是 | 文件唯一 ID,用来访问文件,建议存储起来。 |
requestId | string | 否 | 请求序列号,用于错误排查。 |
// 云函数上传文件示例代码
const fs = require("fs");
let result = await uniCloud.uploadFile({
cloudPath: "test-admin.jpeg",
fileContent: fs.createReadStream(`${__dirname}/cos.jpeg`)
});
云函数获取文件下载链接。
平台兼容性
阿里云 | 腾讯云 | 支付宝小程序云 |
---|---|---|
× | √ | √ |
getTempFileURLOptions参数说明
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
fileList | <Array>.string | 是 | 要下载的文件 ID 组成的数组。 |
fileList字段
字段 | 类型 | 必填 | 说明 | ||
---|---|---|---|---|---|
fileID | string | 是 | 文件 ID。 | ||
<!-- | maxAge | Integer | 是 | 文件链接有效期。 | --> |
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
fileList | <Array>.object | 否 | 存储下载链接的数组。 |
requestId | string | 否 | 请求序列号,用于错误排查。 |
fileList字段
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
fileID | string | 是 | 文件 ID。 |
tempFileURL | string | 是 | 文件访问链接。 |
let result = await uniCloud.getTempFileURL({
fileList: ['cloud://test-28farb/a.png']
});
云函数删除云存储文件。
删除云存储文件是高危操作,不建议在客户端操作,而建议在云函数中操作。
deleteFileOptions参数说明
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
fileList | <Array>.string | 是 | 要删除的文件 ID 组成的数组。 |
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
fileList | <Array>.object | 否 | 删除结果组成的数组。 |
requestId | string | 否 | 请求序列号,用于错误排查。 |
fileList字段
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
fileID | string | 是 | 文件 ID。 |
// 云函数删除文件示例代码
let result = await uniCloud.deleteFile({
fileList: [
"cloud://test-28farb/a.png" // 阿里云fileID是url形式,例:https://xxx.com/xxx.png
]
});
云函数下载已上传至云存储的文件到云函数代码空间内。阿里云直接使用http请求url下载即可,无需使用downloadFile接口。
如需下载到客户端请参考:
平台兼容性
阿里云 | 腾讯云 | 支付宝小程序云 |
---|---|---|
× | √ | √ |
downloadFileOptions参数说明
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
fileID | string | 是 | 要下载的文件的 ID。 |
tempFilePath | string | 否 | 下载的文件要存储的位置。 |
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
fileContent | Buffer | 否 | 下载的文件的内容。如果传入 tempFilePath 则不返回该字段。 |
requestId | string | 否 | 请求序列号,用于错误排查。 |
let result = await uniCloud.downloadFile({
fileID: "cloud://aa-99j9f/my-photo.png",
// tempFilePath: '/tmp/test/storage/my-photo.png'
});
阿里云迁移服务空间后,旧云存储url需要通过此接口获取新服务空间的cdn链接
平台兼容性
阿里云 | 腾讯云 | 支付宝小程序云 |
---|---|---|
HBuilderX 3.6.10+(Alpha版)、HBuilderX 3.6.5+(正式版) | 不支持 | 不支持 |
字段 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
fileList | Array<String> | 是 | - | 要获取下载链接的文件 ID 组成的数组 | - |
请求参数中的fileList
字段 | 类型 | 必填 | 说明 |
---|---|---|---|
fileID | String | 是 | 旧云存储url |
字段 | 类型 | 说明 |
---|---|---|
fileList | Array<Object> | 存储下载链接的数组 |
响应参数中的fileList
字段 | 类型 | 说明 |
---|---|---|
fileId | string | 文件 ID(从文件url中解析出的id) |
gmtCreate | number | 文件上传时间(精确到秒的时间戳) |
gmtModified | number | 文件更改时间(精确到秒的时间戳) |
name | string | 文件原始名称 |
size | number | 文件大小(Byte) |
type | string | 文件类型 |
url | string | 文件cdn链接 |
阿里云商用版目前仍可使用此功能,但是未来可能会进行计费
使用阿里云作为服务商时,云存储支持直接使用restful api对资源进行处理,下表列出支持的操作类型。
如果你的数据库及云函数使用腾讯云,也是可以使用阿里云云存储的。详细用法参考:连接多个服务空间
功能 | 操作参数 | 参考文档 |
---|---|---|
图片缩放 | resize | 点击查看 |
图片裁剪 | crop | 点击查看 |
图片旋转 | rotate | 点击查看 |
图片锐化调节 | sharpen | 点击查看 |
图片格式转换 | format | 点击查看 |
图片质量调节 | quality | 点击查看 |
图片水印 | watermark | 点击查看 |
视频截帧 | snapshot | 点击查看 |
Tips
使用腾讯云作为服务商时,云存储通过数据万象
提供图片缩放、图片水印等计算功能。
数据万象
是腾讯云的一个按量计费产品,月初生成上个月的账单,并从账号余额中扣除相关费用。故若在腾讯云中使用图片缩放、图片水印等功能,首先需保证账号余额充足,否则可能会触发账号级停服风险!
说明:数据万象
月初产生的账单,会从uniCloud账号余额中自动扣除,相关费用及单价完全和腾讯云保持一致,具体可参考数据万象 - 计费方式。
腾讯云支持的数据处理功能如下:
功能 | 操作参数 | 参考文档 |
---|---|---|
图片缩放 | thumbnail | 点击查看 |
图片裁剪 | cut,crop,iradius,rradius,scrop | 点击查看 |
图片旋转 | rotate | 点击查看 |
格式转换 | format,cgif,interlace | 点击查看 |
质量变换 | quality,rquality,lquality | 点击查看 |
高斯模糊 | radius,sigma | 点击查看 |
亮度 | bright | 点击查看 |
对比度 | contrast | 点击查看 |
锐化 | sharpen | 点击查看 |
灰度图 | grayscale | 点击查看 |
图片水印 | watermark | 点击查看 |
文字水印 | watermark | 点击查看 |
获取图片基本信息 | imageInfo | 点击查看 |
获取图片 EXIF | exif | 点击查看 |
获取图片主色调 | imageAve | 点击查看 |
去除元信息 | strip | 点击查看 |
快速缩略模板 | w,h,format,q,rq,lq | 点击查看 |
限制图片大小 | size-limit | 点击查看 |
管道操作符 | | | 点击查看 |