
使用 axios 发送 formdata 时,若未正确设置请求头,express 默认无法解析 multipart/form-data 请求,导致 req.body 为空;根本原因在于客户端未告知服务器数据格式,且服务端缺少 multer 等表单解析中间件。
使用 axios 发送 formdata 时,若未正确设置请求头,express 默认无法解析 multipart/form-data 请求,导致 req.body 为空;根本原因在于客户端未告知服务器数据格式,且服务端缺少 multer 等表单解析中间件。
在前端使用 FormData 构造请求体时,浏览器会自动将 Content-Type 设置为 multipart/form-data 并附带随机 boundary(如 boundary=----WebKitFormBoundary...)。但 Axios 默认会覆盖这一行为:当传入 FormData 实例却未显式配置 headers 时,Axios 会错误地设置 Content-Type: application/json(或直接不设),从而破坏浏览器原生的 multipart 编码机制,导致后端无法识别和解析。
因此,切勿手动设置 Content-Type: application/json —— 这是典型误区。正确做法是:完全省略 Content-Type 头,让浏览器自动设置:
const url = `${location.origin}/agregar/`;
const formdata = new FormData();
formdata.append("urlProyect", btneliminar.dataset.proyectoUrl);
formdata.append("tarea", nuevaTarea.value);
// ✅ 正确:不设置 headers,让浏览器自动设置 multipart/form-data
axios.post(url, formdata);
// ❌ 错误:强制设置为 application/json,破坏 FormData 编码
// axios.post(url, formdata, {
// headers: { 'Content-Type': 'application/json' }
// });
与此同时,服务端也需匹配处理逻辑:body-parser 仅支持 urlencoded 和 json 格式,不支持 multipart/form-data。你当前的 app.use(bodyParser.urlencoded({ extended: true })) 对 FormData 请求完全无效,因此 req.body 始终为空。
✅ 正确解决方案是引入专用于文件/表单上传的中间件——multer:
npm install multer
然后更新服务端配置:
const express = require('express');
const multer = require('multer');
const app = express();
// 配置 multer(无文件上传时可使用内存存储)
const upload = multer(); // 默认使用内存存储,适合纯字段提交
// ⚠️ 移除 body-parser 对 multipart 的无效尝试
// app.use(bodyParser.urlencoded({ extended: true })); // 保留仅用于普通表单(非 FormData 场景)
// app.use(bodyParser.json()); // 如需 JSON 接口可保留
// ✅ 使用 multer 解析 multipart/form-data
app.use(upload.none()); // 仅处理文本字段(无文件),等价于解析 FormData 中的字符串字段
// 路由与静态资源等保持不变
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;
// 后续业务逻辑...
};
? 注意事项:
- 若后续需上传文件,将
upload.none()替换为upload.single('fieldName')或upload.fields([...]); -
multer会将文本字段放入req.body,文件字段放入req.file/req.files; - 不要混用
body-parser和multer处理同一类请求,避免冲突; - 开发时可通过浏览器 Network 面板检查请求的
Content-Type是否为multipart/form-data; boundary=...,并确认 Payload 中字段是否可见。
总结:FormData + Axios 的核心原则是「客户端交由浏览器自动编码,服务端用 multer 主动解析」——二者缺一不可。











