使用 FormData 配合 fetch 或 XMLHttpRequest 发送表单是提交混合数据最稳妥方式;自动收集带 name 的字段,额外字段用 append 追加;fetch/XHR 会自动设置 multipart/form-data 及 boundary,切勿手动设 Content-Type;后端需启用 multipart 解析且字段名须严格匹配。

直接用 FormData 配合 fetch 或 XMLHttpRequest 发送表单,是现代前端提交含文件、文本混合数据最稳妥的方式。关键在于不手动序列化数据,让浏览器自动处理边界和编码。
创建 FormData 并自动收集表单字段
只需传入表单 DOM 元素,FormData 会读取所有 name 属性的控件(包括 input[type=file]、textarea、select),无需逐个 append:
const form = document.querySelector('#myForm');
const data = new FormData(form); // 自动包含所有带 name 的字段
如果需要额外字段(如 token、状态标记),再单独追加:
data.append('csrf_token', 'abc123');data.append('submit_type', 'save_draft');
用 fetch 提交(推荐)
fetch 默认识别 FormData,会自动设置正确的 Content-Type(multipart/form-data 及带 boundary),你不用管它:
立即学习“Java免费学习笔记(深入)”;
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
fetch('/api/submit', {
method: 'POST',
body: data // 直接传 FormData 实例
})
.then(res => res.json())
.then(console.log);
注意:不要手动设置 Content-Type,否则浏览器无法生成 boundary,后端收不到文件或字段乱序。
用 XMLHttpRequest 提交(兼容旧环境)
写法稍多一步,但逻辑一致:
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/submit');
xhr.onload = () => console.log(xhr.response);
xhr.send(data); // 同样直接传 FormData
同样禁止设置 Content-Type 请求头 —— xhr 在发送 FormData 时会自动覆盖它。
后端接收注意事项
后端框架(如 Express、Django、Spring)需启用 multipart 解析:
- Express:用
multer中间件 - Django:
request.POST(文本)和request.FILES(文件)自动分离 - PHP:
$_POST和$_FILES原生支持
字段名必须与前端 name 属性完全一致,大小写敏感,空格也不行。

















