jQuery ajax发送POST请求时服务端req.body打印为空大括号如何解决
问题原因和修复方案
核心问题
- 服务端Express未配置请求体解析中间件:原生Express不会自动解析POST请求的请求体,未配置对应中间件时
req.body默认是空对象 - 客户端请求格式和预期解析规则不匹配:jQuery.ajax发送非键值对的纯字符串时,默认
Content-Type为application/x-www-form-urlencoded,服务端按表单格式解析无法匹配到内容,自然返回空
修复方案
方案1:发送JSON格式数据(最常用)
客户端修改
$.ajax({ data: JSON.stringify({content: 'hello'}), // 序列化为JSON字符串 method: 'POST', url: 'http://localhost:8000/api', crossDomain: true, contentType: 'application/json', // 明确指定请求格式为JSON success: function (data) { console.log(JSON.stringify(data)); }, error: function (xhr, status, err) { console.log(err) } });
服务端修改
// 增加JSON解析中间件,要放在路由定义之前 app.use(express.json()); app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); app.post('/api', function (req, res) { console.log(req.body) // 此时会输出 { content: 'hello' } res.json({status: 'ok'}) // 必须返回响应,否则前端会超时 }); app.listen(8000, () => { console.log(`server is running on port 8000`); });
方案2:发送纯文本格式数据
客户端修改
$.ajax({ data: 'hello', method: 'POST', url: 'http://localhost:8000/api', crossDomain: true, contentType: 'text/plain', // 明确指定请求格式为纯文本 success: function (data) { console.log(JSON.stringify(data)); }, error: function (xhr, status, err) { console.log(err) } });
服务端修改
// 增加纯文本解析中间件,要放在路由定义之前 app.use(express.text()); app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); app.post('/api', function (req, res) { console.log(req.body) // 此时会输出字符串 'hello' res.json({status: 'ok'}) // 必须返回响应,否则前端会超时 }); app.listen(8000, () => { console.log(`server is running on port 8000`); });
额外注意事项
- 所有解析中间件必须放在路由定义之前,否则不会生效
- POST请求处理完成后必须给前端返回响应,否则前端会进入超时错误逻辑
- 如果是4.x以下的旧版本Express,需要单独安装
body-parser包,引入后使用bodyParser.json()、bodyParser.text()替代内置的对应方法
内容的提问来源于stack exchange,提问作者seriously
相关产品推荐
相关产品推荐

