# 开发指南 ## 启用uni-cloud-ext-storage扩展库@use-in-function 扩展存储是单独的扩展库,开发者需手动将uni-cloud-ext-storage扩展库添加到云函数或云对象的依赖中。 操作步骤: 1. 右键需要添加的云函数或云对象 2. 点击-管理公共模块或扩展库依赖 3. 勾选uni-cloud-ext-storage扩展库 ![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/3707/ext-storage/445.png) ## API ### 获取扩展存储管理对象@getExtStorageManager 云端在操作扩展存储前,需要先获取 extStorageManager 对象实例,然后再通过 extStorageManager.xxx 调用对应的API **云端代码** ```js const extStorageManager = uniCloud.getExtStorageManager({ provider: "qiniu", // 扩展存储供应商 domain: "example.com", // 域名地址 }); ``` #### 请求参数 |参数名 |类型 |必填 |默认值 |说明 | |:-: |:-: |:-: |:-: |:-: | |provider |String |是 |- |扩展存储供应商,可选
qiniu: 七牛云| |domain |String |是 |- |扩展储存域名(域名地址)如:example.com | ### 获取前端上传参数@getUploadFileOptions 接口名:getUploadFileOptions 调用此接口可在云端获取前端上传所需参数,将上传参数返回给前端,前端使用 uni.uploadFile 即可上传文件 你可以在调用 extStorageManager.getUploadFileOptions 前执行一些自己的业务逻辑,判断用户是否有上传权限。 **云端代码** ```js module.exports = { getUploadFileOptions(data = {}) { let { cloudPath, // 前端传过来的文件路径 } = data; // 可以在此先判断下此路径是否允许上传等逻辑 // ... // 然后获取 extStorageManager 对象实例 const extStorageManager = uniCloud.getExtStorageManager({ provider: "qiniu", domain: "example.com", // 域名地址 }); // 最后调用 extStorageManager.getUploadFileOptions let uploadFileOptionsRes = extStorageManager.getUploadFileOptions({ cloudPath: cloudPath, allowUpdate: false, // 是否允许覆盖更新,如果返回前端,建议设置false,代表仅新增,不可覆盖 }); return uploadFileOptionsRes; } } ``` #### 请求参数 |参数名 |类型 |必填 |默认值 |说明 | |:-: |:-: |:-: |:-: |:-: | |cloudPath |String |否 |- |云端文件路径(不填会自动生成) | |allowUpdate |Boolean |否 | false |是否允许覆盖更新 true:可覆盖 false:仅新增,不可覆盖 | #### 响应参数 |字段 |类型 |说明 | |:-: |:-: |:-: | |uploadFileOptions|Object |uni.uploadFile所需的参数 | |cloudPath |String |文件云端路径 | |fileID |String |文件ID | |fileURL |String |文件URL(如果是私有权限的文件,则此URL是无法直接访问的) | 响应参数 uploadFileOptions 详情 ```json { "expTime": 1704459639, // 过期时间,已秒为单位的时间戳 "cloudPath": "public/test/1704456039122.jpg", // 文件云端路径 "fileID": "qiniu://public/test/1704456039122.jpg", // 文件ID "fileURL": "https://cdn.example.com/public/test/1704456039122.jpg", // 文件URL(如果是私有权限的文件,则此URL是无法直接访问的) "uploadFileOptions": { "url": "https://upload.qiniup.com", // 上传网关地址,对应uni.uploadFile的url参数 "name": "file", // 文件对应的 key,对应uni.uploadFile的name参数 // HTTP 请求中其他额外的 form data,对应uni.uploadFile的formData参数 "formData": { "token": "xxxxxxxx", "key": "public/test/1704456039122.jpg", } } } ``` **前端上传代码** ```js uni.chooseImage({ count: 1, success: async (res) => { const filePath = res.tempFilePaths[0]; uni.showLoading({ title: "上传中...", mask: true }); // ext-storage-co 是你自己写的云对象(参考上面的云端代码) const uniCloudStorageExtCo = uniCloud.importObject("ext-storage-co"); const uploadFileOptionsRes = await uniCloudStorageExtCo.getUploadFileOptions({ cloudPath: `test/${Date.now()}.jpg`, // 支持自定义目录 }); const uploadTask = uni.uploadFile({ ...uploadFileOptionsRes.uploadFileOptions, // 上传文件所需参数 filePath: filePath, // 本地文件路径 success: () => { const res = { cloudPath: uploadFileOptionsRes.cloudPath, // 文件云端路径 fileID: uploadFileOptionsRes.fileID, // 文件ID fileURL: uploadFileOptionsRes.fileURL, // 文件URL(如果是私有权限,则此URL是无法直接访问的) }; // 数据库里可直接保存 fileURL 或 fileID console.log("上传成功", res); }, fail: (err) => { console.log("上传失败", err); } }); // 监听上传进度 uploadTask.onProgressUpdate((res) => { console.log("监听上传进度", res); }); uni.hideLoading(); } }); ``` ### 云端上传文件@uploadFile 接口名:uploadFile 调用此接口可在云端上传文件到云存储 **云端代码** ```js const extStorageManager = uniCloud.getExtStorageManager({ provider: "qiniu", domain: "example.com", // 域名地址 }); // 文件的base64值 let base64 = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAAAXNSR0IArs4c6QAAAX1JREFUeF7tnLFxwkAQRf86dEwHDqEATAeO3YNdgmugBFGDiemAoQBSd+DUhD6Pxk6Y4XTB13o08AiFDt09vf3cCGZDkhbd6qHoey3Fk6T7/tgNv05S2YXu3o6v+4/4haODVGY3DOXC0uMzpGXMu+W7FM/AuUSgbGPePX5RVlU9Tj2ggj11AgBq2AEgAHkBgkEYhEEeAQzy+JFBGIRBHgEM8viRQRg0AYOOL/vqLBablTfDxujsa49SYtmTHGKUfW0A/UcGZd9FDDJSKvvmUGKUmKGnJAzCIAxK3aRSYpQYJUaJsZM2qoCdNI87DH0kYRAGYZBHAIM8fmQQBmGQRwCDPH5kEAZhkEcAgzx+ZBAGYZBH4NoNSqXT+PAx/puU/rMPgBpP9QAEoLYDQ3uR9ui8M8ggQtqzazIGecuY9uhRvuanvURvdgBq8AMQgCgxjwAGefzIIAzCII8ABnn8aLA0zK9vsESLrjqjsqXJW5XOX5O3/n3aBJ5ROmsT+AM4B3/QCW75sQAAAABJRU5ErkJggg==`; let base64Str = "base64,"; let base64Index = base64.indexOf(base64Str); if (base64Index > -1) base64 = base64.substring(base64Index + base64Str.length); let fileContent = new Buffer(base64, 'base64'); let res = await extStorageManager.uploadFile({ cloudPath: `${Date.now()}.png`, // 云端文件名,不填则自动生成 fileContent, // 要上传的文件内容 allowUpdate: false, // 是否允许覆盖 }); console.log('uploadFile: ', res); ``` #### 请求参数 |参数名 |类型 |必填 |默认值 |说明 | |:-: |:-: |:-: |:-: |:-: | |fileContent|Buffer |是 |- |文件内容 | |cloudPath |String |否 |- |云端文件路径(不填会自动生成) | |allowUpdate |Boolean|否 | false |是否允许覆盖更新 true:可覆盖 false:仅新增,不可覆盖| #### 响应参数 |字段 |类型 |说明 | |:-: |:-: |:-: | |cloudPath |String |文件云端路径 | |fileID |String |文件ID | |fileURL |String |文件URL(如果是私有权限的文件,则此URL是无法直接访问的) | ### 获取临时下载链接@getTempFileURL 接口名:getTempFileURL 调用此接口可批量获取私有文件的临时下载链接 你可以在调用 extStorageManager.getTempFileURL 前执行一些自己的业务逻辑,判断用户是否有获取临时下载链接权限。 **云端代码** ```js const extStorageManager = uniCloud.getExtStorageManager({ provider: "qiniu", domain: "example.com", // 域名地址 }); let res = extStorageManager.getTempFileURL({ fileList: ["qiniu://test.jpg"], // 文件地址列表 }); console.log('getTempFileURL: ', res); return res; ``` #### 请求参数 |参数名 |类型 |必填 |默认值 |说明 | |:-: |:-: |:-: |:-: |:-: | |fileList |Array |是 |- |文件地址列表,数组内元素值类型支持(fileID、cloudPath、fileURL)
如:"qiniu://test.jpg" "test.jpg" "https://example.com/test.jpg" 均表示同一个文件 | #### 响应参数 |字段 |类型 |说明 | |:-: |:-: |:-: | |fileList |Array |存储下载链接的数组 | 响应参数中的fileList |字段 |类型 |说明 | |:-: |:-: |:-: | |tempFileURL|String |临时文件URL地址| |fileID |String |文件ID | |cloudPath |String |文件云端路径 | ### 下载文件@downloadFile 接口名:downloadFile 调用此接口获得文件Buffer 你可以在调用 extStorageManager.downloadFile 前执行一些自己的业务逻辑,判断用户是否有下载该文件权限 **云端代码** ```js const extStorageManager = uniCloud.getExtStorageManager({ provider: "qiniu", domain: "example.com", // 域名地址 }); let res = extStorageManager.downloadFile({ fileID: "qiniu://test.jpg", // 待下载的文件 }); console.log('getTempFileURL: ', res); return res; ``` #### 请求参数 |参数名 |类型 |必填 |默认值 |说明 | |:-: |:-: |:-: |:-: |:-: | |fileID |String |是 |- |待下载的文件,该字段支持的值类型:fileID、cloudPath、fileURL
如:"qiniu://test.jpg" "test.jpg" "https://example.com/test.jpg" 均表示同一个文件 | #### 响应参数 |字段 |类型 |说明 | |:-: |:-: |:-: | |fileContent |Buffer |下载的文件的内容 | ### 删除文件@deleteFile 接口名:deleteFile 调用此接口可批量删除云端文件 **云端代码** ```js const extStorageManager = uniCloud.getExtStorageManager({ provider: "qiniu", domain: "example.com", // 域名地址 }); let res = await extStorageManager.deleteFile({ fileList: ["qiniu://test.jpg"], // 待删除的文件地址列表 }); console.log('deleteFile: ', res); return res; ``` #### 请求参数 |参数名 |类型 |必填 |默认值 |说明 | |:-: |:-: |:-: |:-: |:-: | |fileList |Array |是 |- |文件地址列表,数组内元素值类型支持(fileID、cloudPath、fileURL)
如:"qiniu://test.jpg" "test.jpg" "https://example.com/test.jpg" 均表示同一个文件 | #### 响应参数 |字段 |类型 |说明 | |:-: |:-: |:-: | |fileList |Array|删除结果组成的数组。 | ### 修改文件状态@updateFileStatus 接口名:updateFileStatus 可以将指定文件设置为私有权限或公共权限 默认上传的文件都是公共权限,如果需要将文件设置为私有权限,则可调用此接口 **云端代码** ```js const extStorageManager = uniCloud.getExtStorageManager({ provider: "qiniu", domain: "example.com", // 域名地址 }); let res = await extStorageManager.updateFileStatus({ fileID: "qiniu://test.jpg", // 待修改的文件 isPrivate: true, // true 私有 false 公共 }); console.log('updateFileStatus: ', res); return res; ``` #### 请求参数 |参数名 |类型 |必填 |默认值 |说明 | |:-: |:-: |:-: |:-: |:-: | |fileID |String |是 |- |待修改的文件,该字段支持的值类型:fileID、cloudPath、fileURL
如:"qiniu://test.jpg" "test.jpg" "https://example.com/test.jpg" 均表示同一个文件 | |isPrivate|Boolean|是 |- |true 设为私有权限 false 设为公共读权限 | #### 响应参数 |字段 |类型 |说明 | |:-: |:-: |:-: | |errCode |Number |0 成功 其他均为失败| |errMsg |String |失败描述| ## 小程序域名白名单 小程序需要添加域名白名单,否则无法正常使用 ### 上传域名 将下方域名添加到小程序的uploadFile合法域名列表中 ``` https://upload.qiniup.com ``` ### 下载域名 下载域名就是你开通扩展存储时绑定的自定义域名,将你的自定义域名添加到download合法域名列表中 ## 常见问题@question ### 运行报错,当前空间不支持provider:"qiniu" 通常是因为空间没有开通扩展存储导致的,[前往开通教程](./service.md),如果确定已经开通,则可尝试重启项目并重新上传相关云函数。 ### 运行报错,uniCloud.getExtStorageManager is not a function 出现这个错误时,请依次执行以下操作 1. 检查HBuilderX的版本是否 >= 3.99 2. 右键云函数或云对象,管理公共模块或扩展库依赖,勾选uni-cloud-ext-storage扩展库 3. 重新上传这个云函数或云对象 ## 外部系统如何上传文件到扩展存储 可以通过云函数或云对象开启URL化的方式来获取前端上传参数,拿到上传参数后即可通过uni.uploadFile(或其他三方请求库)上传文件 相关文档: [获取前端上传参数](https://doc.dcloud.net.cn/uniCloud/ext-storage/dev.html#getuploadfileoptions) [云函数URL化](https://doc.dcloud.net.cn/uniCloud/http.html)