拖文件上传需在dragover事件中立即调用event.preventDefault(),否则drop不触发;取文件用dataTransfer.files,上传用FormData;移动端须降级为file input。

能直接拖文件进网页上传,不需要插件,但必须手动阻止浏览器默认行为,否则会打开图片或跳转到文件地址。
dragover 里不写 preventDefault 就根本触发不了 drop
这是最常踩的坑:很多开发者只在 drop 事件里调用 event.preventDefault(),结果拖进去没反应。其实 dragover 是关键闸门——浏览器默认会拒绝接收拖入内容,必须显式拦截才能让 drop 有机会执行。
-
dragover事件中必须立刻执行event.preventDefault(),不能延迟、不能加条件判断 - 可以顺便设置
event.dataTransfer.dropEffect = 'copy',让光标显示为“复制”样式,用户更清楚能放 - 别在
dragover里做耗时操作(比如读文件),它会高频触发,卡顿明显
drop 里取文件要用 dataTransfer.files,不是 items
日常上传场景(单文件/多图片)直接用 event.dataTransfer.files 最稳妥。它是标准 FileList,支持遍历、类型检查、大小读取;而 items 主要用于处理文件夹(需调用 webkitGetAsEntry),反而增加兼容性负担。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 检查是否有文件:
if (e.dataTransfer.files.length === 0) return - 过滤图片:
Array.from(e.dataTransfer.files).filter(f => f.type.startsWith('image/')) - 注意:
files是只读类数组,不能用forEach直接调用,得先转成数组
上传必须用 FormData,不能直接 fetch(file)
fetch 的 body 不接受原始 File 对象,必须包装进 FormData。否则会报错 TypeError: Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body 或静默失败。
立即学习“前端免费学习笔记(深入)”;
- 正确写法:
const formData = new FormData(); formData.append('file', file); fetch('/upload', { method: 'POST', body: formData }) - 服务端接收字段名(这里是
'file')要和后端约定一致,PHP 用$_FILES['file'],Node.js Koa 需配@koa/multer等中间件 - 如果传多个文件,
append('files', file)多次即可,后端收到的是同名数组
移动端没有 drag 事件,input 降级不是可选项
iOS 和 Android 浏览器完全不触发 dragstart/drop,所以纯拖拽逻辑在手机上必然失效。必须保留 <input type="file"> 并视觉隐藏,用 label 激活,再通过 JS 同步处理逻辑。
- 不要用
display: none隐藏 input,iOS Safari 会禁用它;改用position: absolute; left: -9999px - 拖拽成功后,记得清空
dataTransfer.clearData(),避免重复提交同一组文件 - 文件校验(类型、大小)必须前后端都做,前端只是体验优化,不能替代后端安全检查


















