拖拽上传需在dragover和drop中均调用preventDefault(),分片上传以5MB为片、用Math.ceil计算片数并精确slice,断点续传靠localStorage存已传索引(带文件指纹),合并由服务端自动触发。

dragover 和 drop 事件必须 preventDefault()
浏览器对拖入文件的默认行为是打开或下载,不阻止就会跳转或报错 Failed to execute 'readAsDataURL' on 'FileReader': The requested file could not be read。只监听 drop 不够,dragover 也得调 preventDefault(),否则根本进不了 drop 回调。
常见错误是只在 drop 里阻止,结果拖进去没反应;或者加了 preventDefault() 却漏了 stopPropagation(),导致父容器也响应拖拽逻辑,样式错乱或事件冲突。
- 务必给
dragover和drop都加e.preventDefault() - 建议统一用
e.stopPropagation()避免事件冒泡干扰 - 视觉反馈(如加
highlightclass)只应在dragenter/dragleave中控制,别混进drop
大文件不能直接传,得用 Blob.slice() 分片
File 是 Blob 的子类,所以能直接调 slice()。关键不是“能不能切”,而是“怎么切才不崩内存”。5MB/片是较稳妥的起点,20GB 文件切出来约 4000 片,前端不会卡死,服务端也容易做幂等校验。
别用 file.size / 1024 / 1024 算 MB 数再比较——浮点误差可能导致最后一片为空;应该用 Math.ceil(file.size / chunkSize) 算总片数,再用 file.slice(start, end) 精确截取。
-
start = i * chunkSize,end = Math.min((i + 1) * chunkSize, file.size) - 每片上传前建议生成唯一
chunkId(如${fileId}-${i}),服务端靠它去重和排序 - 避免把整个
File对象塞进FormData——直接传Blob片,减少引用和 GC 压力
断点续传靠 localStorage 记录已传分片索引
用户刷新页面、网络中断后能接着传,核心就一句话:上传成功后立刻存当前分片序号到 localStorage,下次初始化时读出来过滤掉已传的片。不要等全部传完再存,否则崩溃就前功尽弃。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
注意 localStorage 是字符串存储,得用 JSON.parse() 和 JSON.stringify() 处理数组;key 要带文件指纹(比如 file.name + file.lastModified 拼接的 hash),否则同名文件覆盖会出错。
- 初始化时:用
localStorage.getItem(key)读已传索引数组 - 上传循环中:
if (uploadedChunks.includes(i)) continue - 单片成功后:
uploadedChunks.push(i); localStorage.setItem(key, JSON.stringify(uploadedChunks)) - 上传完成立即清空对应 key,避免残留干扰下一次上传
合并请求不能由前端发,必须服务端触发
前端调个 fetch('/merge', { method: 'POST', body: JSON.stringify({ fileId }) }) 看似简单,但极不可靠:用户关页、网络闪断、重复点击都会导致合并失败或多次触发。正确做法是——所有分片上传成功后,服务端检查该 fileId 下是否已收齐全部分片,自动执行合并,并返回最终文件 URL。
前端只需轮询或监听 WebSocket 通知,而不是主动发起合并。否则你得处理“合并中”“合并失败”“合并超时”三种状态,还可能因并发上传导致服务端写冲突。
- 服务端收到分片时,记录
fileId+chunkIndex+etag到数据库或 Redis - 每次上传成功后,查该
fileId的已收片数是否等于totalChunks - 相等则异步触发合并逻辑,完成后更新文件状态为
ready - 前端轮询
/status?fileId=xxx,直到返回{ status: 'ready', url: '...' }
真正难的不是切片或拖拽,是让每一片上传都可验证、可回溯、可中断恢复。fileId 设计、分片幂等性、服务端合并时机,这三个点漏掉任何一个,断点续传就形同虚设。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










