最标准可靠的方式是使用 FormData 对象:它自动处理 multipart/form-data 的 boundary 和编码,支持用 append() 混合添加文本字段与文件,fetch 或 XHR 直接传入 body 即可,无需手动设 Content-Type。

在文件上传请求中同时携带普通文本字段,最标准、最可靠的方式是使用 FormData 对象 —— 它天然支持混合添加文件(File 或 Blob)和普通键值对(如用户名、ID、描述等),且能被 fetch 或 XMLHttpRequest 正确识别为 multipart/form-data 格式。
用 FormData 构建混合数据
FormData 会自动处理边界(boundary)和编码,无需手动拼接字符串或设置 Content-Type 头(浏览器会自动设为带正确 boundary 的 multipart/form-data):
- 创建空的
FormData实例 - 用
.append(key, value)添加文本字段(value是字符串) - 同样用
.append(key, file)添加文件(file来自<input type="file">的files[0]) - 直接传给
fetch()的body选项
示例:
const formData = new FormData();
formData.append('username', 'alice');
formData.append('category', 'report');
formData.append('description', 'Q3 sales summary');
const fileInput = document.querySelector('#file');
if (fileInput.files.length > 0) {
formData.append('upload', fileInput.files[0]); // 字段名 'upload' 需与后端约定
}
fetch('/api/upload', {
method: 'POST',
body: formData // ✅ 不要设置 headers 中的 Content-Type!浏览器会自动处理
})
.then(res => res.json())
.then(data => console.log(data));
后端接收注意事项
服务端需按 multipart/form-data 解析请求体,不能当作 JSON 处理:
立即学习“Java免费学习笔记(深入)”;
- Node.js(Express):需配合
multer、busboy或内置req.files(v4.19+ 实验性) - Python(Flask):用
request.form取文本字段,request.files取文件 - PHP:文本字段在
$_POST,文件在$_FILES - Java(Spring):用
@RequestParam接收文本,@RequestPart或MultipartFile接收文件
避免常见错误
- ❌ 不要手动设置
headers: { 'Content-Type': 'multipart/form-data' }—— 这会覆盖浏览器自动生成的带 boundary 的正确头,导致后端无法解析 - ❌ 不要用
JSON.stringify()包裹 FormData —— FormData 不是普通对象,不能序列化为 JSON - ❌ 不要试图把文件转成 base64 后和文本一起塞进 JSON —— 浪费内存、增大体积、失去流式上传优势,且需后端额外解码
- ✅ 若需额外认证头(如
Authorization),可安全添加在headers中,不影响 FormData 自动设置的 content-type
补充:用 XMLHttpRequest 也一样简单
如果必须兼容老环境,XMLHttpRequest 同样支持 FormData:
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/upload');
xhr.onload = () => console.log(xhr.response);
xhr.send(formData); // 直接 send,不用设 header


















