cURL/Postman发送JSON格式POST请求体失败 Express接口异常排查
问题描述
基于Node.js与Express搭建后端接口服务时,出现两类异常:
- Postman向接口发送POST请求,服务返回HTTP 200状态码,但响应内容仅包含自增id字段,未返回提交的JSON对象内容
- CMD命令行窗口中使用cURL发送同类型POST请求时直接触发报错
核心实现代码如下:
const express = require('express'); const Joi = require('joi'); const app = express(); app.use(express.json({extended: false})); // POST接口 app.post('/api/courses', (req, res) => { const {error} = validateCourse(req.body); if(error){ return res.status(400).send(error.details[0].message); } const course = { id: (courses.length + 1), name: req.params.name }; courses.push(course); res.send(course); }); // 参数校验方法 function validateCourse(course){ const schema = { name: Joi.string().min(3).required() }; return Joi.validate(course, schema); }
调试参考素材包含Postman请求配置界面、POST请求头配置界面、多次发起POST请求后的应用返回效果截图。
故障根因
代码存在3处明确错误:
- 取值逻辑错误:POST请求提交的JSON载荷经
express.json()中间件解析后,会挂载到req.body对象。代码中使用的req.params.name用于匹配URL路径中的动态参数,当前接口路径/api/courses未定义:name路径占位符,该值始终为undefined,因此响应体仅返回自增id,缺失提交的name字段 - 中间件配置错误:
extended是express.urlencoded()中间件的专属配置项,express.json()不支持该参数,错误传参会导致部分场景下JSON解析失败,是cURL请求直接报错的核心诱因 - 变量缺失定义:代码中未初始化
courses数组,首次接收请求时会直接抛出引用错误。
修复方案
按以下步骤调整代码即可:
- 修正JSON中间件配置,移除不支持的
extended参数 - 补全
courses数组的初始定义 - 修正name字段的取值来源,从
req.body中获取提交的参数 - 补充服务监听逻辑(用于本地启动测试)
修复后的完整核心代码:
const express = require('express'); const Joi = require('joi'); const app = express(); // 修正json中间件配置 app.use(express.json()); // 补全缺失的courses初始数组 const courses = []; // POST接口 app.post('/api/courses', (req, res) => { const {error} = validateCourse(req.body); if(error){ return res.status(400).send(error.details[0].message); } const course = { id: (courses.length + 1), // 修正取值来源,从请求体中获取name name: req.body.name }; courses.push(course); res.send(course); }); // 参数校验方法 function validateCourse(course){ const schema = { name: Joi.string().min(3).required() }; return Joi.validate(course, schema); } // 服务启动监听 const port = process.env.PORT || 3000; app.listen(port, () => console.log(`服务已启动,监听端口:${port}`));
验证方法
- Postman验证:向
http://localhost:3000/api/courses发送POST请求,请求体选择raw-JSON格式,传入{"name":"测试课程"},即可正常返回包含id和name的完整响应 - cURL验证:在CMD中执行以下命令,可正常得到返回结果:
curl -H "Content-Type: application/json" -X POST -d "{\"name\":\"curl测试课程\"}" http://localhost:3000/api/courses
补充说明:若使用Joi v14及以上版本,
Joi.validate()的旧调用方式已被废弃,建议调整为schema.validate(course)的新写法,避免控制台抛出废弃警告。
内容的提问来源于stack exchange,提问作者Gnome-Improvement713
相关产品推荐
相关产品推荐

