webkitdirectory 仅 Chromium 和 Safari 16.4+ 支持,Firefox 已移除;必须同时使用 webkitdirectory 和 multiple,通过 webkitRelativePath 还原目录结构,但 Firefox 中该字段为空,导致兼容性硬伤。

不能直接用 webkitdirectory 做跨浏览器文件夹上传,它只在 Chromium(Chrome/Edge)和 Safari 16.4+ 中有效,Firefox 已彻底移除支持,且行为不一致——这是首先要确认的底线。
必须同时写 webkitdirectory 和 multiple
缺一不可。只写 webkitdirectory 会导致 Chrome/Safari 弹出对话框后返回一个空 FileList 或仅根目录名字符串(不是 File 对象);只写 multiple 则退化为普通多文件选择。
-
<input type="file" webkitdirectory multiple>是最小可用组合 -
directory属性是历史残留(旧版 Firefox 曾支持),现在无效但加上无害,可保留作兼容性占位 - 不要加
accept:对文件夹选择无过滤作用,反而可能干扰弹窗触发 - 不要设
value或用 JS 赋值:input.value是只读的,强行写入无效
webkitRelativePath 是唯一能还原目录结构的字段
用户选中文件夹后,event.target.files 返回的是扁平化的 FileList,所有子文件都“摊平”在一层里。每个 File 对象的 webkitRelativePath 字段(如 "src/main.js" 或 "docs/README.md")才是你重建路径的唯一依据。
-
file.name永远只是纯文件名(如"main.js"),不含任何路径信息 -
file.path在现代 Chromium 中已被移除,读取会返回undefined,别试 - Firefox 中
webkitRelativePath恒为空字符串,无法还原结构——这就是它不支持的根本原因
JS 触发点击会被静默拒绝,必须用户主动点击
input.click() 在绝大多数浏览器中会被安全策略拦截,表现为无反应或控制台报错 Failed to execute 'click' on 'HTMLElement': The element is not interactable。
立即学习“前端免费学习笔记(深入)”;
- 隐藏原生
input可用opacity: 0; position: absolute覆盖,但绝不能用display: none或visibility: hidden,否则事件完全失效 - 不要尝试用
label绑定后 JS 模拟点击,一样被拦 - 拖拽上传(
dragover/drop)可绕过此限制,但需手动处理DataTransfer.items,且webkitRelativePath同样只在 Chromium/Safari 中可用
真正麻烦的地方不在怎么写 HTML,而在于:一旦你依赖 webkitRelativePath 构建路径并上传,后端就必须按这个相对路径存文件——而这个字段在 Firefox 里根本不存在,你得要么降级为单文件上传,要么引入额外的客户端压缩打包逻辑。没人能跳过这个兼容性硬伤。



















