你是不是也经历过这样的崩溃时刻?
在开发上传头像功能时,明明文件选好了,服务器却返回“400 Bad Request”;或者在用JSON提交表单数据时,file字段突然消失得无影无踪……
别慌!这不是你的错,而是你一直混淆了FormData和JSON这两个“表兄弟”。今天,我用血泪经验+实战代码,彻底拆解它们的本质差异——看完这篇,你再也不用在表单提交上“掉坑”了!
一、FormData:文件上传的“终极搬运工”
定义:浏览器内置API,专为多部分表单数据(multipart/form-data)设计,能轻松处理文件、文本、二进制数据。
核心特点:
- 用
append(key, value)添加数据(value可以是File对象) - 自动设置
Content-Type: multipart/form-data
经典用例:
// 上传图片文件
const formData = new FormData();
formData.append('avatar', document.getElementById('fileInput').files[0]);
fetch('/upload', {
method: 'POST',
body: formData
});
✅ 优势:文件不会被转码,服务器直接接收原始文件。
❌ 陷阱:不能直接用 JSON 格式传输文件!如果强行用JSON.stringify(formData),文件会变成[object FormData],服务器直接报错。
二、JSON:数据交换的“通用语言”
定义:轻量级数据格式(application/json),用于序列化 JavaScript 对象,适合纯文本数据交换。
核心特点:
- 用
JSON.stringify(obj)转为字符串,JSON.parse(str)反解析 - 不支持文件!所有数据必须是字符串/数字/数组等基础类型
经典用例:
// 提交用户信息(无文件)
const userData = { name: '张三', age: 25 };
fetch('/api/user', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData)
});
✅ 优势:服务器解析简单,兼容所有 RESTful API。
❌ 陷阱:文件字段会丢失!若userData包含file: File,JSON.stringify会忽略它(因为File无法序列化)。
三、灵魂对比:为什么99%的人搞混?
| 维度 | FormData | JSON |
|---|---|---|
| 数据类型 | 支持 File、Blob、字符串 | 仅支持基础类型(字符串/数字等) |
| Content-Type | multipart/form-data | application/json |
| 文件处理 | ✅ 原始传输,服务器直接存文件 | ❌ 文件会丢失/报错 |
| 服务器解析 | 需特殊处理(如 Node.js 的 multer) | 直接 req.body 解析 |
| 适用场景 | 文件上传、表单提交(含文件) | API 数据交互(纯文本) |
关键真相:
FormData ≠ JSON!
用FormData时,服务器收到的是“多部分数据”;用JSON时,服务器收到的是“字符串化对象”。
混用 = 400错误 + 三天调试!
四、避坑指南:场景化使用策略
✅ 场景1:上传头像/文件
必须用 FormData!
// 错误示范(用JSON传文件)→ 服务器收不到文件
fetch('/upload', {
body: JSON.stringify({ file: fileInput.files[0] }) // 会变成 [object File]
});
// 正确示范(用FormData)
const formData = new FormData();
formData.append('file', fileInput.files[0]);
fetch('/upload', { body: formData }); // 服务器完美接收
✅ 场景2:提交注册表单(无文件)
用 JSON 更高效!
// 用FormData反而麻烦
const formData = new FormData();
formData.append('name', '张三');
formData.append('email', 'zhangsan@example.com');
fetch('/register', { body: formData }); // 服务器需手动解析
// 用JSON更简洁
fetch('/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: '张三', email: 'zhangsan@example.com' })
});
⚠️ 终极陷阱:混合数据怎么办?
需求:提交表单(含文件+文本)。
错误做法:
// 混用导致文件丢失!
const data = { name: '张三', file: fileInput.files[0] };
fetch('/submit', { body: JSON.stringify(data) }); // file 会消失
正确做法:
const formData = new FormData();
formData.append('name', '张三');
formData.append('file', fileInput.files[0]); // 文件单独处理
fetch('/submit', { body: formData });
五、进阶思考:为什么这个坑这么深?
- 历史原因:早期浏览器对文件上传支持弱,FormData 诞生就是为了填补这个空白。
- 开发者误区:以为“所有数据都能转 JSON”,忽略了文件的特殊性。
- 未来趋势:随着 Web API 发展(如
fetch),FormData 已成文件上传的唯一标准,JSON 则是 API 交互的事实标准。
结语:一句话记住精髓
“文件走 FormData,数据走 JSON;混用 = 400错误 + 项目经理暴怒!”
下次写表单时,先问自己:“这个字段需要上传文件吗?” 如果答案是“是”,立刻用 FormData;否则,用 JSON.stringify。
755

被折叠的 条评论
为什么被折叠?



