当前位置: 首页 > news >正文

UniApp文件上传大小限制问题解决方案

问题背景

最近在开发一个基于UniApp的wgt项目(小程序)时,遇到了一个让人头疼的文件上传问题。本项目是嵌入在安卓应用中的小程序,需要实现视频文件上传功能。由于是wgt项目,所以是在安卓应用内部运行的小程序,对兼容性和稳定性要求较高。

第一版方案:uni.chooseVideo插件

最初我使用了UniApp官方的 uni.chooseVideo 插件来实现视频选择功能。看起来很简单,但很快就遇到了兼容性问题:

兼容性问题

  • 低版本安卓:基本可以正常使用
  • 高版本安卓:打开相册时出现乱码,用户体验极差

这个问题让我意识到,官方插件在不同安卓版本上的兼容性并不稳定,特别是在wgt项目中,兼容性问题更加突出。

第二版方案:原生插件

为了解决兼容性问题,我们的团队想出了一个合理保守的方案:让安卓同事开发一个原生插件,通过 sendNativeEvent 来调用。

技术实现

// 使用sendNativeEvent调用原生插件
uni.sendNativeEvent('插件名称xxx', {title: "",multiple: false,filetypes: "video/mp4"
}, (ret) => {// 处理返回结果
});

优势

  • 完全控制文件选择逻辑
  • 解决了安卓版本兼容性问题
  • 用户体验更加稳定
  • 使用自己开发的插件后,确实解决了眼下的兼容性问题

新的挑战:文件大小限制

解决了兼容性问题后,我遇到了更大的挑战——文件上传大小限制

问题现象

当文件超过20MB时,UniApp默认的nginx服务器直接返回错误:

<html>
<head><title>413 Request Entity Too Large</title>
</head>
<body>
<center><h1>413 Request Entity Too Large</h1>
</center>
<hr><center>nginx</center>
</body>
</html>

问题分析

通过多次验证,我发现:

  • 20MB以下:可以正常"通过"
  • 20MB以上:UniApp默认的nginx直接断开连接,请求无法发送出去

这里的"通过"很重要,说明20MB是一个关键的分界线。

深入调查:uni.chooseVideo的秘密

于是我好奇,为什么会出现这样的情况呢?然后我用 uni.chooseVideo 插件来试一下,发现了一个有趣的现象:

观察到的现象

  1. 选择视频后会显示长时间的loading,等待时间很长,至少30秒
  2. 最终上传的文件大小比原文件小很多
  3. 本地40MB的视频被压缩到14MB

关键发现

原来 uni.chooseVideo 插件默认会自动压缩视频!这就是为什么它能够处理大文件的原因。

uni.chooseVideo 有个属性叫 compressed,你需要把它关掉,不然它就默认给你压缩了。但是问题来了,即使把 compressed 关掉也没用,如果文件超过20MB的话,还是会被断掉。

解决方案:手动视频压缩

那只能选择压缩视频的方法了。所以我使用 sendNativeEvent 选择完毕视频后,也给视频进行压缩。UniApp官网也提供了免费的压缩插件,我就直接使用了它,压缩效果还不错,但有一点慢。使用的是 uni.compressVideo

技术实现

// 判断文件类型
const isVideo = this.isVideoFile(file);if (isVideo) {// 视频文件进行压缩const compressedFile = await compressVideoWithUni(file);await this.handleFileUpload(compressedFile);
} else {// 非视频文件直接上传await this.handleFileUpload(file);
}// 使用UniApp官方压缩插件
export const compressVideoWithUni = async (file) => {return new Promise((resolve, reject) => {uni.compressVideo({src: file.path,quality: 'low', // 使用最低质量,最大压缩success: (res) => {const compressedFile = {...file,path: res.tempFilePath,size: res.size};resolve(compressedFile);},fail: (error) => {reject(new Error(error.errMsg || '压缩失败'));}});});
};

文件类型判断

isVideoFile(file) {if (!file || !file.path) return false;const extension = file.path.split('.').pop()?.toLowerCase();const videoExtensions = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'webm', 'm4v', '3gp'];return videoExtensions.includes(extension);
}

最终效果

解决的问题

  1. ✅ 安卓版本兼容性问题
  2. ✅ 文件大小限制问题
  3. ✅ 用户体验优化

技术特点

  • 智能处理:只有视频文件才进行压缩
  • 容错机制:压缩失败时自动降级到原文件
  • 用户友好:显示压缩进度和状态
  • 性能优化:避免不必要的压缩操作

经验总结

技术要点

  1. UniApp的局限性:官方插件在某些场景下存在兼容性问题
  2. 文件大小限制:20MB是uni.uploadFile默认nginx的限制
  3. 视频压缩的重要性:大文件必须压缩才能正常上传

开发建议

  1. 测试覆盖:在不同安卓版本上充分测试
  2. 用户体验:提供清晰的状态反馈
  3. 错误处理:实现完善的容错机制
  4. 性能考虑:避免不必要的文件处理

技术选型

  • 原生插件 > 官方插件(在兼容性要求高的场景)
  • 手动压缩 > 依赖默认行为(在需要精确控制的场景)

UniApp官方文档不够完善

在解决这个问题的过程中,我发现了一个让人无语的问题:UniApp官方文档的严重不足

文档缺失问题

  1. uni.uploadFile 文档:完全没有提到20MB的文件大小限制
  2. uni.chooseVideo 文档:虽然有 compressed 属性说明,但没有明确说明压缩的具体行为和时间
  3. 错误处理:413错误在官方文档中没有任何说明

开发者体验问题

  • 需要自己摸索和踩坑才能发现问题
  • 官方文档过于简单,缺乏实际使用场景的说明
  • 错误信息不够友好,调试困难

建议改进

  1. 完善文档:明确标注各种限制和约束
  2. 错误说明:提供常见错误的解决方案
  3. 最佳实践:增加实际项目中的使用建议

结语

这个问题的解决过程让我深刻体会到,在移动端开发中,兼容性和性能优化永远是绕不开的话题。通过这次经历,我不仅解决了当前的问题,还为自己积累了宝贵的经验。

同时,我也深刻认识到官方文档的局限性,作为开发者,我们不能完全依赖官方文档,需要在实际项目中不断探索和总结。

记住:有时候官方插件并不是最佳选择,根据具体需求选择合适的技术方案才是王道!


本文记录了UniApp文件上传大小限制问题的完整解决过程,希望能为遇到类似问题的开发者提供参考。

http://www.xdnf.cn/news/1365445.html

相关文章:

  • kafka 副本集设置和理解
  • kafka常用命令
  • 宋红康 JVM 笔记 Day07|本地方法接口、本地方法栈
  • Linux(四):进程状态
  • python项目中pyproject.toml是做什么用的
  • SDC命令详解:使用set_timing_derate命令进行约束
  • K8s高可用:Master与候选节点核心解析
  • 基于MalConv的恶意软件检测系统设计与实现
  • 力扣(用队列实现栈)
  • SSH 反向隧道:快速解决服务器网络限制
  • 蜗牛播放器 Android TV:解决大屏观影痛点的利器
  • 【科研绘图系列】R语言绘制代谢物与临床表型相关性的森林图
  • 从0死磕全栈第1天:从写一个React的hello world开始
  • leetcode 238 除自身以外数组的乘积
  • PHP学习笔记1
  • 基于MATLAB实现支持向量机(SVM)进行预测备
  • 数据结构青铜到王者第三话---ArrayList与顺序表(1)
  • 【数学·三角函数】两角和差公式 二倍角公式
  • idea官网选择具体版本的下载步骤
  • easy-dataset的安装
  • 【STM32】G030单片机的独立看门狗
  • 不止效率工具:AI 在文化创作中如何重构 “灵感逻辑”?
  • 《拉康精神分析学中的欲望辩证法:能指的拓扑学与主体的解构性重构》
  • 【科研绘图系列】R语言浮游植物生态数据的统计与可视化
  • [系统架构设计师]专业英语(二十二)
  • 系统架构设计师-计算机系统存储管理-页式、段氏、段页式模拟题
  • 探索量子计算的新前沿
  • 【Linux】timerfd和POSIX定时器(timer_create)
  • ASW3642 pin√pin替代TS3DV642方案,可使用原小板只需简单调整外围|ASW3642 HDMI二切一双向切换器方案
  • prepare_model_for_kbit_training()函数解析(56)