浏览器按rfc 7578用随机boundary分隔各字段,每个part含content-disposition头和原始二进制数据,整请求一次性发送,不支持暂停续传;分片上传须弃用form表单,改用fetch手动分片上传。

form enctype="multipart/form-data" 是怎么构造请求体的
浏览器不是把文件二进制“直接塞进”HTTP body,而是按 RFC 7578 构造一个带 boundary 的多段结构。每个 input 字段(包括文本和文件)变成一个独立 part,用随机生成的 boundary 分隔,每个 part 头部必须含 Content-Disposition,例如:
Content-Disposition: form-data; name="avatar"; filename="photo.jpg" Content-Type: image/jpeg <binary data here></binary>
这个结构天然不支持暂停、续传或校验——整条请求是一次性发完的。所以你看到上传中途刷新就归零,服务端也收不到“已传 60%”这种状态。
常见错误现象:
- 后端
$_FILES或MultipartFile为空 → 漏写enctype="multipart/form-data"或 method 不是 POST - 收到的文件名是
blob或乱码 → 前端用了application/json或application/x-www-form-urlencoded提交 - 大文件直接失败 → Nginx 报
413 Request Entity Too Large,或 PHP 返回UPLOAD_ERR_INI_SIZE(对应upload_max_filesize超限)
为什么不能靠表单提交做分片上传
分片上传和 form enctype="multipart/form-data" 在协议层互斥:前者是多次独立 HTTP 请求,每次只传一段字节范围 + 元数据;后者是单次原子请求,无偏移、无会话上下文。
一旦决定分片,就必须放弃 <form></form> 提交机制,改用 fetch 或 XMLHttpRequest 手动构造请求:
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
- 用
File.prototype.slice()截取分片,如file.slice(0, 5 * 1024 * 1024) - 每个请求用
FormData封装,但 key 名要带唯一标识,比如chunk_data、file_id、chunk_index - 不要手动设置
Content-Type头 —— 浏览器调用fetch(formData)时会自动注入boundary;手设反而导致解析失败 - 服务端不能再依赖
$_FILES自动提取,得从php://input或$_POST读元数据,再拼接分片
Node.js 中 multiparty 的流式解析怎么绕过内存瓶颈
multiparty 的核心不是“等整个请求收完再解析”,而是实现 Writable 流接口,在 _write 方法里边收边拆。它拿到 chunk 后立刻识别 boundary,切出 part,触发 part 或 file 事件,文件数据可直接 pipe 到磁盘,不进内存。
这意味着:
- 上传 2GB 文件,进程 RSS 内存可能只涨几 MB
- 服务端能实时监听
part事件,拿到字段名、文件名、Content-Type等头部信息,早于完整接收 - 如果没显式调用
form.parse(req),或没监听file事件,文件内容会被丢弃 —— 它不会像multer那样默认保存到临时目录 - 错误处理必须在
req.on('error')和form.on('error')两个地方都设,否则流中断可能静默失败
边界字符串(boundary)为什么不能手动干预
boundary 是浏览器根据当前会话动态生成的随机字符串,比如 ----WebKitFormBoundary7MA4YWxkTrZu0gW,它出现在 Content-Type 头里,也作为请求体的分隔符。你不能在 JS 里硬编码、覆盖或复用旧值。
原因很实际:
- curl 测试时必须用
-F "file=@test.jpg",它会自动生成合法 boundary;用-d手动拼几乎必然失败 - fetch 发送
FormData时若手动设headers['Content-Type'],浏览器会禁用自动 boundary 插入,后端收不到标准 multipart 结构 - 多个文件同名字段(如
<input name="files" multiple>)依赖 boundary 区分各 part,手动干预会导致解析错位
真正容易被忽略的是:boundary 不只是个分隔符,它是整个 multipart 解析的锚点。服务端解析器(PHP 的 ext/standard/multipart.c、Java 的 commons-fileupload、Node 的 multiparty)全靠它定位每个 part 的起始和结束 —— 错一位,后面全乱。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










