javascript如何实现拖放功能与文件上传【教程】
发布时间 - 2026-02-01 00:00:00 点击率:次拖放上传需同时处理dragover和drop事件并阻止默认行为,正确读取DataTransfer中的文件,区分items与files,用FileReader配合分片处理大文件,通过FormData安全上传,并注意移动端降级及边界情况处理。
JavaScript 实现拖放上传,核心不是“加个 dragover 就能用”,而是得拦住浏览器默认行为、正确读取 DataTransfer、区分文件与非文件项,并处理好大文件分片或取消的边界情况。
为什么 drop 事件拿不到文件?
常见错误是只监听 drop,却没阻止 dragover 的默认行为——浏览器会直接打开文件或跳转,根本不会触发 drop。
必须同时处理两个事件:
-
dragover中调用e.preventDefault()(仅此一项就足够让drop触发) -
drop中再次e.preventDefault(),再从
e.dataTransfer.files取文件
注意:e.dataTransfer.items 和 .files 行为不同:.items 可包含目录(需递归读取),.files 是扁平的 FileList,多数场景用后者更稳。
FileReader 读取失败的三个典型原因
不是所有文件都能直接 readAsDataURL,尤其大文件或受限环境:
- 内存溢出:读取几百 MB 文件时,
readAsDataURL会生成超长 base64 字符串,可能卡死页面;改用readAsArrayBuffer+ 分片上传 - 跨域限制:如果页面是
file://协议,部分浏览器禁止FileReader(Safari 尤其严格) - 读取中断:用户在读取中刷新页面,
onloadend不一定触发,应监听onerror和onabort
示例判断:
const reader = new FileReader();
reader.onload = () => console.log(reader.result.slice(0, 50));
reader.onerror = () => console.error('读取失败:', reader.error?.name);
reader.readAsArrayBuffer(file); // 比 readAsDataURL 更可控
如何安全地把文件传给后端?
别直接把 File 对象塞进 fetch body——它支持,但容易忽略关键细节:
- 用
FormData包裹,字段名必须和后端约定一致,例如formData.append('upload', file) - 避免手动设置
Content-Type:FormData会自动生成带 boundary 的 multipart,设错反而导致 400 - 大文件建议加进度监听:
upload.onprogress(XMLHttpRequest)或用ReadableStream+fetch流式上传(较新 API) - 后端接收时注意:Node.js 的
express默认不解析 multipart,需multer;Python Flask 要检查request.files是否为空
拖放区域被遮挡或失效怎么办?
视觉上看着是拖放区,实际没响应,往往因为:
- CSS 设置了
pointer-events: none(比如为了透出背景图) - 父容器有
overflow: hidden且拖拽起点在区域外,某些浏览器会截断事件流 - 区域高度为 0:空
div没内容也没高度,dragover压根不会进入——加min-height: 100px或padding - 移动端不支持原生
drag/drop(iOS Safari 全面禁用),必须降级为点击选择
检测是否支持的最小验证:
if ('draggable' in document.createElement('span')) {
// 可以用原生 drag/drop
} else {
// 强制显示 file input
}
真正难的不是写通拖放,而是当用户拖入 2GB 视频、中途关掉标签页、网络突然中断时,你的代码还知道该停在哪一步、报什么错、要不要重试——这些逻辑不在教程里,但在生产环境里天天发生。
# css
# javascript
# python
# java
# js
# node.js
# node
# go
# 浏览器
# app
# safari
# flask
# express
# 字符串
# 递归
# pointer
# append
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?
网站建设保证美观性,需要考虑的几点问题!
Laravel怎么判断请求类型_Laravel Request isMethod用法
JS碰撞运动实现方法详解
Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)
Laravel如何发送系统通知?(Notification渠道示例)
矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?
Laravel怎么在Controller之外的地方验证数据
如何在阿里云完成域名注册与建站?
如何快速登录WAP自助建站平台?
如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程
Laravel如何从数据库删除数据_Laravel destroy和delete方法区别
微信小程序 wx.uploadFile无法上传解决办法
详解Android——蓝牙技术 带你实现终端间数据传输
百度输入法ai组件怎么删除 百度输入法ai组件移除工具
如何用西部建站助手快速创建专业网站?
香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南
Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践
进行网站优化必须要坚持的四大原则
教你用AI将一段旋律扩展成一首完整的曲子
使用PHP下载CSS文件中的所有图片【几行代码即可实现】
长沙做网站要多少钱,长沙国安网络怎么样?
弹幕视频网站制作教程下载,弹幕视频网站是什么意思?
消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工
Laravel怎么实现观察者模式Observer_Laravel模型事件监听与解耦开发【指南】
如何用美橙互联一键搭建多站合一网站?
如何在建站之星网店版论坛获取技术支持?
再谈Python中的字符串与字符编码(推荐)
网站建设整体流程解析,建站其实很容易!
edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】
Java解压缩zip - 解压缩多个文件或文件夹实例
Laravel如何配置Horizon来管理队列?(安装和使用)
公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?
Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能
如何快速查询网站的真实建站时间?
利用python获取某年中每个月的第一天和最后一天
Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】
网站图片在线制作软件,怎么在图片上做链接?
ai格式如何转html_将AI设计稿转换为HTML页面流程【页面】
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
Laravel怎么调用外部API_Laravel Http Client客户端使用
什么是JavaScript解构赋值_解构赋值有哪些实用技巧
如何在宝塔面板中修改默认建站目录?
如何在香港服务器上快速搭建免备案网站?
Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】
如何在IIS中配置站点IP、端口及主机头?
,南京靠谱的征婚网站?
Windows11怎样设置电源计划_Windows11电源计划调整攻略【指南】
Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】
如何快速搭建高效可靠的建站解决方案?


