HTML5移动端文件上传需满足accept明确、用户手势触发、合理设置capture三条件才能稳定唤起选择器;iOS/Android对accept值解析不同,需按平台细化声明并真机测试。
HTML5 在移动端原生支持文件上传,不需要额外插件,但直接照搬 PC 端写法大概率会失败——比如 点击无反应、只弹相机不弹文件选择器、iOS 无法多选、安卓部分 WebView 拒绝触发等。
在移动端经常不工作根本原因不是 HTML5 不支持,而是浏览器对 input[type="file"] 的行为做了差异化限制:
accept 明确声明的文件类型(例如漏写 accept="image/*",连相册都不弹)click() 调用静默忽略(比如用 setTimeout 延迟调用或 JS 主动触发)capture 属性,或强制跳转拍照而非文件选择multiple 在 iOS 12–14 上仅对图片有效,iOS 15+ 才支持文档类多选单靠 不够,要同时满足三个条件才大概率触发原生选择器:
accept,且值要具体(accept="image/*" 可,accept="*" 不可)label 间接触发后 JS 调用 click())capture(仅当需要调用摄像头/相册时),否则留空accept 不只是过滤类型,它直接决定系统弹什么界面:
accept="image/*" → 弹「照片」App;accept=".pdf,.docx" → 弹「文件」App(需 i
accept="image/*" → 通常弹图库;但若设备没图库 App,可能 fallback 到文件管理器accept="video/*" 在 iOS 会强制打开录像,不是相册;要相册视频得用 accept="image/*,video/*"
accept=".pdf,.xlsx"),不能只写 application/pdf
移动端上传后常需预览,但 URL.createObjectURL() 在 iOS Safari 14.5+ 有内存泄漏风险,且旧版安卓 WebView 不支持 FileReader 的 readAsDataURL:
预览图片,避免 base64(iOS 有时渲染空白)file.size 并提示用户,iOS Safari 会静默截断超限文件input[type="file"] 的 capture,需降级为纯文件选择,并提示“请从手机相册中选取”change 事件的 e.target.files.length 判断是否选中——iOS 有时返回空数组但实际已选,应监听 input 事件并立即读取真正难的不是“能不能传”,而是“什么时候该弹相册、什么时候该弹文件管理器、用户点了取消怎么识别、WebView 怎么降级”。这些边界情况没有通用解法,得按目标平台逐个测真机。