设置required:true时API调用失败,MongoDB用户模型字段丢失问题
注册API字段验证失败与数据库无数据问题排查
问题现象
向localhost:5002/api/auth/register发送POST请求(请求体包含username、email、password)时,收到ValidationError提示Path 'username' is required;移除Schema中username的required:true配置后,API调用成功,但MongoDB集合中无username、email、password字段。
相关代码
MongoDB User Schema
const mongoose = require("mongoose"); const UserSchema = new mongoose.Schema( { username: { type: String, required: true, unique: true, }, email: { type: String, }, password: { type: String, }, profilePic: { type: String, default: "", }, }, { timestamps: true } ); module.exports = mongoose.model("User", UserSchema);
注册API路由
const router = require("express").Router(); const User = require("../models/User"); //REGISTER router.post("/register", async (req, res) => { try { const newUser = new User({ username: req.body.username, email: req.body.email, password: req.body.password, }); const user = await newUser.save(); res.status(200).json(user); } catch (err) { res.status(500).json(err); } }); module.exports = router;
项目入口index.js
const express = require("express"); const app = express(); const dotenv = require("dotenv"); const mongoose = require("mongoose"); const authRoute = require("./routes/auth"); const cors = require("cors"); const bodyParser = require("body-parser"); app.use( bodyParser.urlencoded({ extended: false, }) ); app.use(bodyParser.json()); app.use(express.urlencoded({ extended: true })); app.use(cors()); app.use(express.json()); dotenv.config(); mongoose .connect(process.env.MONGO_URL, { useUnifiedTopology: true, useNewUrlParser: true, }) .then(() => console.log("DB Connected!!!")) .catch((err) => { console.log("did not work", err); }); app.use("/api/auth", authRoute); app.use("/", (req, res) => { console.log("main url"); }); app.listen("5002", () => { console.log("server running"); });
问题根源
- 请求体解析冲突:index.js中同时使用了第三方
body-parser和Express内置的解析中间件,重复解析导致请求体无法被正确读取,req.body为空对象。此时创建User实例时,username、email、password均为undefined,触发mongoose的必填字段验证报错;移除required:true后,mongoose会忽略undefined字段,因此数据库中无对应数据。 - 请求头缺失:若POST请求未设置
Content-Type: application/json,Express的express.json()中间件无法解析JSON格式的请求体,同样会导致req.body为空。
解决方案
1. 清理冗余解析中间件
Express从v4.16.0开始内置了body-parser的功能,无需单独引入body-parser包,直接使用Express内置中间件即可,避免重复解析冲突。修改index.js的中间件部分:
const express = require("express"); const app = express(); const dotenv = require("dotenv"); const mongoose = require("mongoose"); const authRoute = require("./routes/auth"); const cors = require("cors"); // 调整中间件顺序:先处理CORS,再解析请求体 app.use(cors()); app.use(express.json()); // 解析JSON格式请求体 app.use(express.urlencoded({ extended: true })); // 解析URL编码格式请求体 dotenv.config(); // 数据库连接及路由挂载逻辑保持不变...
2. 确保请求头正确设置
发送POST请求时,必须设置请求头Content-Type: application/json,否则Express无法正确解析JSON请求体。例如在Postman中,选择Body为raw -> JSON格式,工具会自动添加该请求头。
3. 验证请求体是否被正确读取
在注册路由中添加日志,确认req.body是否获取到数据:
router.post("/register", async (req, res) => { console.log("请求体内容:", req.body); // 打印请求体,排查是否为空 try { const newUser = new User({ username: req.body.username, email: req.body.email, password: req.body.password, }); const user = await newUser.save(); res.status(200).json(user); } catch (err) { res.status(500).json(err); } });
验证修复效果
重新启动服务后,发送带正确请求头的POST请求,此时req.body应能正确获取到字段值,mongoose验证通过后,数据会正常存入MongoDB集合。
内容的提问来源于stack exchange,提问作者alex deralu
相关产品推荐
相关产品推荐

