
使用 axios 发送 formdata 时服务端接收不到数据,根本原因在于未正确设置请求头,导致 express 无法识别 multipart/form-data 格式,需禁用自动设置 content-type 并配合 multer 解析。
使用 axios 发送 formdata 时服务端接收不到数据,根本原因在于未正确设置请求头,导致 express 无法识别 multipart/form-data 格式,需禁用自动设置 content-type 并配合 multer 解析。
当使用 FormData 对象通过 Axios 发起 POST 请求时,浏览器会自动以 multipart/form-data 格式编码请求体,并生成符合规范的边界(boundary)。但 Axios 默认会在请求头中自动设置 Content-Type: application/json(或其它非 multipart 类型),这会覆盖浏览器自动生成的、带 boundary 的正确类型,导致服务端无法解析表单字段——req.body 为空对象 {}。
✅ 正确做法:禁用 Axios 自动设置 Content-Type
客户端代码需显式将 Content-Type 设为 undefined,让浏览器自行设置:
const url = `${location.origin}/agregar/`;
const formdata = new FormData();
formdata.append("urlProyect", btneliminar.dataset.proyectoUrl);
formdata.append("tarea", nuevaTarea.value);
// 关键:不设置 Content-Type,或设为 undefined
axios.post(url, formdata, {
headers: {
'Content-Type': undefined // ← 告诉 Axios 交由浏览器自动设置 multipart/form-data
}
});⚠️ 注意:绝不能设置
'Content-Type': 'application/json'或'application/x-www-form-urlencoded'—— 这会强制覆盖 multipart 头,使 FormData 失效。
? 服务端:替换 body-parser,改用 multer
body-parser 完全不支持 multipart/form-data(即文件上传或原生 FormData)。它仅处理 urlencoded 和 json 类型。因此,即使前端正确发送,服务端仍无法解析。
✅ 正确方案:引入 multer,专用于解析 multipart 请求:
npm install multer
更新服务端配置:
const express = require('express');
const multer = require('multer');
const routes = require('./routes');
const path = require('path');
const db = require('./config/db');
// 配置 multer(无文件上传时可使用内存存储)
const upload = multer(); // 默认使用内存存储,适合纯表单字段
db.sync()
.then(() => console.log('Database synced'))
.catch(err => console.error('DB sync error:', err));
const app = express();
// ✅ 移除 body-parser.urlencoded —— 它对 FormData 无效
// app.use(bodyParser.urlencoded({ extended: true }));
// ✅ 使用 multer 解析 multipart/form-data
app.use(upload.none()); // ← 仅处理文本字段(无文件上传时使用)
app.set('view engine', 'pug');
app.set('views', path.join(__dirname, './views'));
app.use(express.static('public'));
app.use('/', routes());
app.listen(3000, () => console.log('Server running on http://localhost:3000'));控制器中即可正常访问字段:
exports.agregarTarea = async (req, res) => {
console.log(req.body); // ✅ 此时输出 { urlProyect: '...', tarea: '...' }
const { urlProyect, tarea } = req.body;
// 后续业务逻辑...
};? 补充验证技巧
- 浏览器开发者工具 → Network → 查看该请求的 Headers 标签页,确认
Content-Type是否为类似multipart/form-data; boundary=----WebKitFormBoundary...; - 检查请求的 Payload(而非 Preview 或 Response)是否包含实际字段内容;
- 若后续需支持文件上传,将
upload.none()改为upload.single('fieldName')或upload.fields([...])。
✅ 总结
| 环节 | 错误做法 | 正确做法 |
|---|---|---|
| 客户端 | 手动设置 Content-Type: application/json
|
设置 headers: { 'Content-Type': undefined }
|
| 服务端 | 依赖 body-parser 解析 FormData |
使用 multer + upload.none() 解析纯表单字段 |
| 字段名 | 前后端不一致 | 确保 formdata.append('key', value) 与 req.body.key 严格匹配 |
遵循以上配置,req.body 将完整接收 FormData 提交的字段,彻底解决“空请求体”问题。


















