FormData 是二进制数据的「搬运工」
-
核心价值:让前端开发者无需关心二进制数据的底层处理(如编码转换、协议拼接),专注于业务逻辑。
-
适用场景:任何涉及文件上传、混合数据(文本 + 二进制)的场景,如用户头像上传、简历附件提交、富文本图片插入等。
-
对比传统方案:
- 更简单:无需
FileReader、Base64 转换等繁琐步骤。 - 更高效:直接传输原始二进制数据,减少内存占用和转换耗时。
- 更通用:服务端原生支持
multipart/form-data解析,兼容性强。
- 更简单:无需
用代码对比两种方案
方案 1:传统 Base64 编码(需手动转换)
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
// 1. 使用 FileReader 将文件转为 Base64 字符串
const reader = new FileReader();
reader.onload = function() {
const base64Data = reader.result; // 得到类似 "data:image/png;base64,..." 的字符串
// 2. 通过 JSON 发送 Base64 字符串
fetch('/upload', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
filename: file.name,
content: base64Data // 文本形式的 Base64 数据
})
});
};
reader.readAsDataURL(file); // 读取文件内容并将其转换为 Base64 编码字符串 的方法
方案 2:FormData 方案(直接发送二进制)
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
// 1. 创建 FormData,直接添加文件对象
const formData = new FormData();
formData.append('file', file); // 无需转换,直接添加二进制数据
// 2. 发送请求(浏览器自动处理为 multipart/form-data)
fetch('/upload', {
method: 'POST',
body: formData // 直接发送二进制数据
});
文件上传方案对比表
| 维度 | 传统方案(Base64) | FormData 方案 |
|---|---|---|
| 核心实现 | 将文件转为 Base64 字符串,通过 JSON 发送 | 直接发送二进制数据,使用 multipart/form-data 协议 |
| 代码复杂度 | 高 需手动处理: 1. FileReader 读取文件 2. 转为 Base64 编码 3. 拼接 JSON 请求体 | 低 仅需: 1. 创建 FormData 对象 2. append() 添加文件 3. 直接发送 |
| 数据体积 | 增加约 33% Base64 编码会膨胀数据大小 | 无额外开销 直接传输原始二进制数据 |
| 性能表现 | 低 1. 编码 / 解码耗时 2. 大文件内存占用高 | 高 1. 无需编码转换 2. 流式处理大文件 |
| 服务端处理 | 复杂 1. 接收 JSON 数据 2. 手动解码 Base64 3. 转换为文件 | 简单 主流框架(如 Express、Django)可直接解析文件字段 |
| 典型场景 | 1. 必须使用 JSON 格式传输时 2. 兼容老旧服务端 | 1. 现代 Web 应用文件上传 2. 表单数据与文件混合提交 |
| 兼容性 | 良好(IE10+) | 良好(IE10+,需注意 FormData 支持) |
| 示例代码片段 | const reader = new FileReader();<br>reader.onload = function() {<br> const base64Data = reader.result;<br> fetch('/upload', {<br> body: JSON.stringify({ data: base64Data })<br> });<br>};<br>reader.readAsDataURL(file);<br> | const formData = new FormData();<br>formData.append('file', file);<br>fetch('/upload', {<br> body: formData<br>});<br> |
关键结论
- 优先使用 FormData:在支持现代浏览器的场景下,FormData 方案更高效、更简洁。
- Base64 的适用场景:仅在必须使用 JSON 格式传输或服务端不支持
multipart/form-data时考虑。 - 性能差异:对于大文件(如视频、高清图片),FormData 方案的优势尤为明显,可节省大量带宽和处理时间。