必须在dragover和drop事件中调用e.preventDefault()才能获取e.dataTransfer.files,否则files为空;遍历FileList取file.size(字节数),需过滤size=68的伪文件,并在drop回调中立即校验大小,移动端不支持故无需校验。

拖拽时怎么拿到每个文件的 size 属性
直接从 e.dataTransfer.files 里取,但必须先在 dragover 和 drop 事件中调用 e.preventDefault(),否则 files 是空的。拿到后遍历 FileList,每个 file.size 就是字节数,它天然只读、稳定、无需额外解析。
常见错误现象:
-
e.dataTransfer.files.length === 0—— 多半是漏了preventDefault()或监听了错的事件(比如只监听change) - Chrome/Safari 拖入文件夹时
file.size === 68—— 这是伪文件,必须过滤掉,不能当作真实文件上传
为什么不能只靠 files.length > 0 做有效性判断
因为 files.length > 0 只说明有“看起来像文件”的条目,不代表能用。Safari 拖文件夹、某些 Android WebView 返回空 files 却有 "Files" 类型、甚至用户拖了个网页链接进来——这些都会让 files 非空但实际无效。
真正安全的检测逻辑是:
立即学习“前端免费学习笔记(深入)”;
- 逐个检查
file.size > 0 - 检查
file.name是否含扩展名(file.size === 68时通常没有) - 可选:用
file.type做 MIME 粗筛,但别全信(浏览器可伪造)
大文件或批量拖拽时 size 校验要放在哪一步
必须在真正触发上传或读取前完成校验,而不是等 FileReader 开始读了才发现超限。否则用户已等待数秒,才提示“文件太大”,体验极差。
实操建议:
- 在
drop回调里立刻遍历e.dataTransfer.files,用Array.from(e.dataTransfer.files)转成数组再filter - 对单个文件,直接比对
file.size > 100 * 1024 * 1024(例如限制 100MB) - 对多个文件,累加总 size 做全局限制,避免用户拖 20 个 50MB 文件绕过单文件限制
- 校验失败时,同步给出明确提示(如“第 3 个文件:xxx.pdf(128MB),超出 100MB 限制”)
移动端要不要做 size 检测
不用。iOS 和 Android 主流 WebView 基本不支持 dragover/drop,e.dataTransfer.files 在这些环境里始终为空。你写的 size 检测逻辑根本不会执行。真要做移动端上传,得 fallback 到 <input type="file" multiple>,那里的 files 对象才可靠。
容易被忽略的一点:即使你在桌面端写了完整校验,也得确认后端同样做了 size 与类型验证——前端检测只是用户体验层,不是安全边界。



















