使用Axios发送FormData POST请求,服务器为何接收空请求体?
Axios + FormData 传输数据时服务器接收空请求体问题
在使用Axios与FormData实现客户端向服务器传输数据时,服务器端已配置body-parser中间件解析表单数据,但接收的请求体为空(req.body返回空对象)。已确认字段名称匹配,且body-parser配置无误,相关代码如下:
客户端代码
const url = `${location.origin}/agregar/`; var formdata = new FormData(); formdata.append("urlProyect", btneliminar.dataset.proyectoUrl); formdata.append("tarea", nuevaTarea.value); axios.post(url, formdata);
服务器代码
const express = require('express'); const routes = require('./routes'); const path = require('path'); const bodyParser = require('body-parser'); const db = require('./config/db'); require('./models/Proyectos'); require('./models/Tareas'); db.sync() .then(()=>{console.log('its ok')}) .catch((error => {console.log('oh no!')})) const app = express(); app.use(bodyParser.urlencoded({ extended: true })); app.set('view engine', 'pug'); app.set('views', path.join(__dirname, './views')); app.use(express.static('public')); app.use('/', routes()); app.listen(3000);
控制器代码
exports.agregarTarea = async (req, res) => { console.log(req.body) // 返回 {} }
问题原因及解决方法
原因
body-parser.urlencoded() 仅能解析 application/x-www-form-urlencoded 类型的请求体,而FormData默认发送的请求头是 multipart/form-data,这种类型body-parser无法解析,导致req.body为空。
解决方法
方法1:不使用FormData,直接发送urlencoded格式数据(无文件上传场景)
如果不需要上传文件,无需用FormData,直接传普通对象并指定请求头即可:
const url = `${location.origin}/agregar/`; axios.post(url, new URLSearchParams({ urlProyect: btneliminar.dataset.proyectoUrl, tarea: nuevaTarea.value }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } });
或者让Axios发送JSON格式数据,服务器端新增express.json()解析:
服务器代码中添加:
app.use(express.json());
客户端代码改为:
axios.post(url, { urlProyect: btneliminar.dataset.proyectoUrl, tarea: nuevaTarea.value });
方法2:使用multer解析multipart/form-data(需上传文件场景)
如果必须用FormData(比如要上传文件),需要用multer中间件替代body-parser处理该类型请求:
- 安装multer:
npm install multer
- 修改服务器代码:
const express = require('express'); const routes = require('./routes'); const path = require('path'); const multer = require('multer'); const db = require('./config/db'); require('./models/Proyectos'); require('./models/Tareas'); db.sync() .then(()=>{console.log('its ok')}) .catch((error => {console.log('oh no!')})) const app = express(); // 配置multer,仅解析文本字段(无需存储文件) const upload = multer({ storage: multer.memoryStorage() }); // 在路由前使用upload.none()解析所有文本字段 app.use('/', upload.none(), routes()); app.set('view engine', 'pug'); app.set('views', path.join(__dirname, './views')); app.use(express.static('public')); app.listen(3000);
修改后,控制器中的req.body就能正常获取FormData里的字段值。
内容的提问来源于stack exchange,提问作者Fabian Barua
相关产品推荐
相关产品推荐

