不能直接用 e.target.files.length 判断文件夹总大小,因为该属性仅表示选中文件个数,与体积无关;需转为数组后过滤 size=68 和 size=0 的伪文件/空文件,再累加 file.size。

为什么不能直接用 e.target.files.length 判断文件夹总大小
因为 e.target.files 是一个 FileList,它只包含用户选中的**所有文件**(不含子目录本身),但不反映目录结构层级或嵌套关系。它的长度只是文件个数,和体积完全无关。更关键的是:即使用户选中空文件夹,files.length 也可能大于 0(比如 Safari 拖入文件夹时会塞进 size=68 的伪条目)。真正要算“总大小”,必须逐个读 file.size 并累加。
webkitRelativePath 能帮你识别是否来自同一文件夹,但不影响 size 计算
这个属性返回类似 "project/src/index.js" 的路径字符串,可用于分组、去重或还原目录结构,但它和 file.size 无任何计算关联。你仍需遍历每个 file 实例取 size——哪怕两个文件 webkitRelativePath 不同,只要都在同一个被选中的根文件夹下,它们就该计入总大小。
- 必须先调用
Array.from(e.target.files)转成数组,才能用reduce()累加 - 过滤掉
file.size === 68的条目(Safari 文件夹伪文件) - 跳过
file.size === 0的条目(空文件或损坏文件,不应参与上传)
拖拽 vs 的 size 获取方式一致
两者最终都通过 e.dataTransfer.files(拖拽)或 e.target.files(input)拿到 FileList,后续遍历逻辑完全一样。区别只在事件监听位置:
拖拽需确保 dragover 和 drop 中都调用了 e.preventDefault(),否则 files 为空;而 input 只需监听 change 即可。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 拖拽场景下,若
e.dataTransfer.files.length === 0,八成是漏了e.preventDefault() - 移动端不支持
webkitdirectory和拖拽文件夹,files始终为空,这段 size 计算逻辑根本不会执行 - 批量拖入多个文件夹时,
files会混在一起,无法区分归属,只能统一按总大小限制
总大小校验必须在上传前同步完成,不能依赖后端
前端计算总 size 是为了即时反馈,避免用户等几十秒后才被告知“超出 2GB 限制”。但要注意:这个值只是客户端估算,file.size 是浏览器提供的元数据,不是实际读取后计算的哈希或 CRC,所以它快但不可篡改性为零。真正可靠的边界控制必须由后端二次校验。
- 示例:限制总大小 ≤ 2GB →
const total = Array.from(files).filter(f => f.size > 68 && f.size > 0).reduce((a, f) => a + f.size, 0); if (total > 2 * 1024 * 1024 * 1024) { /* 提示 */ } - 不要在
FileReader或分片上传启动后再校验,那时已产生 I/O 开销 - 如果用户拖入 5000 个文件,遍历本身几乎无性能压力,但生成预览缩略图或计算 MD5 才会卡住主线程
实际落地时,最易被忽略的是:伪文件(size=68)和空文件(size=0)必须在累加前剔除,且这个过滤动作不能省略——哪怕你只打算支持 Chrome,Safari 用户一旦拖入文件夹就会触发这个 case,导致总大小虚高。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










