拖拽上传需精确控制浏览器捕获拖拽事件、解析文件、读取内容并发送至服务器;通过监听dragover/drop事件、阻止默认行为、获取File对象、前端校验类型与大小来实现。

拖拽上传不是把文件扔进网页就完事,关键在浏览器如何捕获拖拽事件、解析文件、读取内容并发送到服务器——整套流程需要精确控制每个环节。
监听拖拽区域,阻止默认行为
用户把文件拖进页面时,浏览器默认会尝试打开或跳转,必须先阻止这个行为,才能让自定义逻辑生效。
- 给目标容器(比如一个
div)绑定dragover和drop事件 -
dragover中调用event.preventDefault(),否则无法触发drop -
drop事件里通过event.dataTransfer.files获取 File 对象列表
验证文件类型与大小,提升体验
不能等文件传到后端才告诉用户“不支持这种格式”,前端拦截能减少无效请求和等待感。
- 遍历
files列表,检查file.type(如"image/png")或用file.name.split('.').pop().toLowerCase()获取扩展名 - 对比预设白名单(如
['jpg', 'jpeg', 'png', 'pdf']) - 用
file.size判断是否超限,例如限制单个文件 ≤ 5MB:file.size
读取文件内容,适配不同用途
上传前是否需要预览?是否要校验哈希?是否需转 Base64?这些都依赖 FileReader 的异步读取能力。
- 创建
new FileReader()实例,监听load事件获取结果 - 用
readAsDataURL(file)获取 base64 字符串(适合图片预览) - 用
readAsArrayBuffer(file)获取二进制数据(适合计算 SHA-256 或分片上传) - 注意:FileReader 是一次性读取,不可复用;多个文件需为每个创建独立实例
构造请求,发送到服务端
读取完成后,根据后端接口要求选择传输方式——FormData 更通用,ArrayBuffer 更灵活。
- 普通上传:新建
FormData,append('file', file),再用fetch提交 - 带元数据:可额外
append('name', file.name)、append('size', file.size) - 大文件或需断点续传:用
ArrayBuffer分片,配合Uint8Array截取片段,手动构造请求体 - 记得设置
Content-Type为multipart/form-data(FormData会自动处理)
整个过程看似线性,实际要处理异常:文件为空、读取失败、网络中断、后端报错——加个简单的 loading 状态和错误提示,体验就稳多了。

















