浏览器原生不支持文件夹上传的进度与重试,需自行管理状态;webkitRelativePath 非真实路径,须前端清洗、后端白名单校验以防越权;Firefox 中不可靠,应降级为文件名拼接;多文件上传时每个 XMLHttpRequest 需独立闭包绑定进度。

浏览器原生不提供文件夹上传的「进度状态」或「失败重试」能力,webkitdirectory 只负责把文件列表交给你,后续所有状态管理(已选、上传中、成功、失败、取消)都得自己实现。
为什么 webkitRelativePath 不能直接当上传路径用
它只是浏览器生成的字符串,比如 product-A/drawings/plate.dwg,但不代表服务器上已有 /product-A/drawings/ 这个目录。后端收到这个路径后,若不做路径校验和安全过滤,可能被构造为 ../../etc/passwd 导致越权写入。
- 必须在前端剥离上级路径:用
path.split('/').filter(p => p && !p.startsWith('..'))清洗 - 后端需白名单校验路径前缀,例如只允许以
uploads/开头 -
webkitRelativePath在 Firefox 中不可靠(部分版本返回空),建议 fallback 到文件名拼接逻辑
XMLHttpRequest 上传多个文件时如何绑定单个进度
每个 XMLHttpRequest 实例只能监听自己的 upload.onprogress,不能共享。如果你用循环发请求,又没给每个请求配独立的闭包变量,最后所有进度都会显示成最后一个文件的值。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 用
for (let i = 0; i 而不是 <code>for (var i = 0; ...),避免作用域污染 - 上传前为每个文件生成唯一 ID(如
Math.random().toString(36).substr(2, 9)),并存到 Map 中用于更新 DOM - 不要复用同一个
FormData实例:每次新建,否则文件内容会叠加
上传中断后怎么恢复状态而不是重传全部
浏览器关闭、网络闪断、用户手动取消后,XMLHttpRequest 不会自动保存已上传字节。要支持断点续传,必须引入分片机制 —— 把大文件切块,每块单独上传并记录 offset。
立即学习“前端免费学习笔记(深入)”;
- 小项目可跳过:对单个
- 分片需前后端协同:前端计算
file.slice(start, end),后端按chunk_index和total_chunks合并 - 关键细节:上传前先发 HEAD 请求查服务端是否已有该文件的完整哈希,有则跳过整个文件(适合 CAD 图纸这类不变资产)
最常被忽略的是错误归因:上传失败时,xhr.status === 0 多半是跨域或 CORS 配置问题,不是后端挂了;而 413 Request Entity Too Large 是 Nginx/Apache 默认限制了单次请求体大小,跟前端 JS 写法无关。


















