移动端h5相册多图上传需兼顾平台兼容、exif校正、内存安全与网络自适应:针对ios/安卓/qq浏览器差异降级处理;canvas双步合一校正方向并压缩;promise队列控并发、toblob避base64;依network type和screen width动态调优quality与尺寸,超10mb自动分批。

移动端H5中实现相册多图上传的响应式预处理,核心不是“适配屏幕尺寸”,而是让图片在不同设备性能、网络条件和系统限制下稳定完成选择→校正→压缩→上传全流程。重点在于规避常见断点:iOS多选失效、安卓EXIF方向错乱、大图内存溢出、微信/QQ浏览器兼容异常。
相册多图选择与平台降级处理
原生 <input type="file" accept="image/*" multiple> 在 iOS Safari 和微信中实际支持多选(iOS 13.4+),但 QQ 浏览器默认禁用多选,仅开放相册入口。不能依赖 multiple 属性直接生效。
- 先检测浏览器环境:
const isQQ = /QQ\//i.test(navigator.userAgent),若命中则移除multiple并改用单次循环触发多次选择 - 对 iOS 设备,不设
capture可同时唤起相册+相机选项;Android Chrome 下设capture="environment"更倾向调用后置摄像头 - 监听 change 后立即重置 input.value = "",避免重复选同一张图不触发事件
EXIF方向校正 + Canvas 压缩双步合一
用户从相册选图,尤其竖屏拍摄,常因 EXIF Orientation 元数据未被 canvas 自动识别,导致预览/上传后图片逆时针旋转90°或镜像。单纯用 CSS transform 仅改变显示,不影响实际上传内容。
- 使用
exif-js或轻量替代方案(如piexifjs)读取 orientation 值(重点关注 3/6/8) - 在 Canvas 绘制前动态调整 canvas.width/height 和 ctx.translate/rotate,确保绘制结果方向正确
- 压缩逻辑绑定在方向校正之后:目标宽度建议设为 800~1200px(兼顾清晰度与体积),quality 控制在 0.6~0.75 区间,实测可将 4MB 原图压至 300KB 内
内存安全的批量压缩策略
一次选 10 张 5MB 图片,直接并发转 base64 极易触发 Android 低端机内存崩溃。需控制并发数 + 按需释放引用。
- 用 Promise 队列控制并发,例如最多同时处理 3 张,其余 await 排队
- 每张图压缩完成后,立刻调用
URL.revokeObjectURL()清理预览 URL,避免 Blob 内存驻留 - 不全量转 base64:压缩后用
canvas.toBlob(callback, 'image/jpeg', quality)直接产出 Blob,再塞入 FormData,跳过 base64 中间态节省内存
响应式上传行为判断
“响应式”在此场景体现为根据当前网络与设备动态调整上传策略,而非仅 CSS 媒体查询:
- 通过
navigator.connection?.effectiveType判断是 4G/3G/WiFi,WiFi 下可放宽压缩比(quality=0.8),弱网下强制降至 0.5 并启用分块上传 - 对
screen.width 的小屏设备(如旧款 iPhone SE),额外限制最大输出宽为 640px - 上传前检查总文件体积:
Array.from(files).reduce((sum, f) => sum + f.size, 0),超 10MB 则提示“建议分批上传”并自动拆分为两组请求











