uniapp 分片上传最佳实践

更新时间: 2026/07/21 16:51:11

自 V10.10.10 版本起,NIM SDK uniapp 支持通过分片上传方式上传超过 100 MB 的大文件。本文详细介绍如何启用 uniapp 分片上传,以及不同 uniapp 运行时的推荐配置与行为差异。

功能概述

NIM SDK 的 uniapp 分片上传功能通过 cloudStorageConfig.enableUniappChunkUpload 配置控制,如需启用,请在初始化时将该项设置为 true。

  • true:优先走 uniapp 分片上传。若当前宿主不具备分片能力,SDK 自动回退到表单上传。
  • false 或不传:关闭 uniapp 分片上传,统一走表单上传路径。

各 uniapp 运行时的行为表现如下:

运行时 enableUniappChunkUpload=false/不传 enableUniappChunkUpload=true
uniapp App(Android/iOS) 表单上传 优先分片上传,能力不足时回退表单上传
uniapp 微信小程序 表单上传 优先分片上传,能力不足时回退表单上传
uniapp H5 表单上传 复用浏览器分片上传语义
其他非目标 uniapp 宿主 表单上传 可能回退表单上传

启用分片上传后,将影响以下上传场景:

  • nim.cloudStorage.uploadFile(...)
  • 发送图片、语音、视频、文件消息时触发的底层文件上传
  • V2NIMStorageService.uploadFile(...)
  • V2NIMStorageService.uploadFileWithMetaInfo(...)

初始化示例如下:

tsimport NIM from 'nim-web-sdk-ng/dist/v2/NIM_UNIAPP_SDK'

const nim = NIM.getInstance(
  {
    appkey: 'your-appkey',
    apiVersion: 'v2'
  },
  {
    cloudStorageConfig: {
      enableUniappChunkUpload: true
    }
  }
)

注意事项

  • 请按现有业务形态接入,请勿为了统一代码路径强行混用 filefilePath
  • 仅在有明确的大文件上传、断点续传或弱网恢复需求时,再开启 enableUniappChunkUpload
  • 对于 H5、App、小程序混合项目,建议按运行时做分支处理,分别传入最符合宿主语义的上传源。

推荐入参

不同 uniapp 运行时的推荐上传源如下:

运行时 推荐入参 说明
uniapp App/uniapp 小程序 filePath 传入宿主选择器返回的临时文件路径
uniapp H5,未开启分片 filePath 建议与其他 uniapp 宿主保持一致的入参模型
uniapp H5,已开启分片 filefileInput 传入浏览器 File 对象或 <input type="file"> 元素
  • 若业务同时覆盖 H5 和 App/小程序,建议按运行时分支组装上传参数。
  • 请勿假设同一套入参能无差别适配所有 uniapp 宿主。

接入示例

uniapp App/微信小程序

建议传入 filePath

tsconst result = await nim.cloudStorage.uploadFile({
  type: 'image',
  filePath: tempFilePath,
  onUploadProgress(progress) {
    console.log(progress.percentageText)
  }
})

console.log(result.url)

发送消息示例:

tsconst message = nim.V2NIMMessageCreator.createImageMessage(tempFilePath)
await nim.V2NIMMessageService.sendMessage(message, conversationId)

uniapp H5(未开启分片)

enableUniappChunkUpload=false 或未配置时,建议优先传入 filePath,与 uniapp App/小程序侧的入参模型保持一致。

tsconst result = await nim.cloudStorage.uploadFile({
  type: 'file',
  filePath: tempFilePath,
  onUploadProgress(progress) {
    console.log(progress.percentageText)
  }
})

发送消息示例:

tsconst message = nim.V2NIMMessageCreator.createFileMessage(tempFilePath, 'example.pdf')
await nim.V2NIMMessageService.sendMessage(message, conversationId)
  • 此处的 filePath 指业务层最终传给 SDK 的字符串路径。
  • 若 H5 页面原始拿到的是浏览器 File 对象,可由业务层先转换为统一的 filePath 形态后再传入。

uniapp H5(已开启分片)

enableUniappChunkUpload=true 时,H5 复用浏览器分片上传语义,建议直接传入 filefileInput

tsconst file = input.files[0]

const result = await nim.cloudStorage.uploadFile({
  type: 'file',
  file,
  onUploadProgress(progress) {
    console.log(progress.percentageText)
  }
})

发送消息示例:

tsconst file = input.files[0]
const message = nim.V2NIMMessageCreator.createFileMessage(file, file.name)
await nim.V2NIMMessageService.sendMessage(message, conversationId)

续传与缓存行为

启用 uniapp 分片上传后:

  • uniapp App/小程序:在当前运行期内维护续传上下文。上传取消后,SDK 会尽量保留未完成的上下文,供后续继续上传。
  • 已完成上传的文件:可能直接复用完成态缓存,避免重复上传。

未启用分片上传时:

  • 不进入 uniapp 分片状态机。
  • getFileUploadInformation() 视为无 uniapp 分片续传上下文。
  • IM NOS LBS 上传能力按表单上传语义上报。

H5 注意说明

uniapp H5 与 App/小程序的上传模型存在本质差异:

  • H5 分片上传本质上复用浏览器 File 上传语义。
  • H5 仅在显式开启 enableUniappChunkUpload 时,才会走浏览器分片上传链路。
  • H5 未开启分片时,SDK 走表单上传路径。

因此建议:

场景 建议
未开启分片 传入 filePath,与其他 uniapp 宿主保持一致。
已开启分片 直接传入浏览器 File 对象。
同时兼容 H5 和非 H5 在选择文件后按运行时分支组织参数。

文件大小校验

maxSize 可用于限制上传文件大小:

tsawait nim.cloudStorage.uploadFile({
  type: 'video',
  filePath: tempFilePath,
  maxSize: 20 * 1024 * 1024
})
  • 浏览器 file 上传场景可直接校验。
  • filePath 上传场景下,若宿主能探查到本地文件大小,SDK 也会执行校验。
  • 如果宿主本身无法稳定提供文件大小,建议业务侧在调用上传前自行判断。

常见问题

为什么开启 uniapp 分片上传后实际仍然走表单上传?

可能原因:

  • 当前运行时不是目标分片宿主。
  • 当前宿主缺少可用的分片读取能力。
  • 本地文件大小无法探查。
  • H5 传入的不是可用的浏览器 File

SDK 在这些情况下会优先保证上传成功,自动回退到表单上传。

为什么 H5 和 App/小程序的接入代码不完全一样?

因为底层文件对象模型不同:

  • H5 侧通常拿到 File
  • App/小程序侧通常拿到 filePath

这属于运行时差异,不建议强行统一成单一入参模型。

是否必须开启分片上传?

不是。

若您的文件普遍较小,或当前业务更关注稳定性与兼容性,可以沿用表单上传,无需开启分片上传。

此文档是否对你有帮助?
有帮助
去反馈
  • 功能概述
  • 注意事项
  • 推荐入参
  • 接入示例
  • uniapp App/微信小程序
  • uniapp H5(未开启分片)
  • uniapp H5(已开启分片)
  • 续传与缓存行为
  • H5 注意说明
  • 文件大小校验
  • 常见问题
  • 为什么开启 uniapp 分片上传后实际仍然走表单上传?
  • 为什么 H5 和 App/小程序的接入代码不完全一样?
  • 是否必须开启分片上传?