You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB验证报错:messages.0.name字段必填,寻求解决方案

解决Mongoose验证错误:messages.0.name: Path name is required

我遇到了这个错误:Error: userdata validation failed: messages.0.name: Path 'name' is required,已经卡了24小时,以下是我的代码详情,请帮忙解决。


客户端代码

const submitContact = async(e)=>{
  e.preventDefault();
  const {name,email,message} = contact;
  const response = await fetch('http://localhost:4000/sent',{
    method:'POST',
    credentials: 'include',
    headers:{
      "Accept":"application/json",
      "ContentType":"application/json"
    },
    body:JSON.stringify({name,email,message})
  })
//const data = await res.json();
  if(response.status===201){
    window.alert('sent!')
    console.log('Message not sent!!')
  }else{
    window.alert('Server errro..')
    //setContact({...contact,message:""})
  }
  console.log(contact);
}

MongoDB Schema代码

const mongooseSchema = new mongoose.Schema({
  name:{
    type:String,
    required:true
  },
  email:{
    type:String,
    required:true
  },
  password:{
    type:String,
    required:true
  },
  confirmpassword:{
    type:String,
    required:true
  },

  messages:[
    {
      name:{
        type:String,
        required:true
      },
      email:{
        type:String,
        required:true
      },
      message:{
        type:String,
        required:true
      } 
    }
  ],
  tokens:[
    {
        token:{
            type:String,
            required:true
        }
    }
  ]
},{timestamps:true})
mongooseSchema.methods.addMessage = async function(name,email,message){
  try{
    this.messages= this.messages.concat({name,email,message})
    await this.save();
    return this.messages;
  }catch(e){
    console.log(e);
  }
}
const usermodel = new mongoose.model('userdata',mongooseSchema)
module.exports = usermodel;

路由代码

app.post('/sent',auth,async(req,res)=>{
           try{
            const {name,email,message} = req.body;
            // if(!name || !email ||!message){
            //     console.log(`${req.body} is blank.`);
            //     return res.status(401).json({error:"error"})
            // }
            const userif = await usermodel.findOne({_id:req.userid});
            if(userif){
                const umessage = await userif.addMessage(name,email,message)
                await userif.save();
                console.log(userif);
                res.status(201).json({message:"added.."})
            }else{
                console.log("error")
            }
            }catch(e){
            console.log(e);
           }
        })

Express配置代码

const express = require('express')
require('dotenv').config();
const dotenv = require('dotenv');
dotenv.config({path: './.env'})
const multer = require('multer');
const mongooseModel = require('./database')
const jwt = require('jsonwebtoken');
const bycrpt = require('bcryptjs')
const cors = require('cors')
const cookieParser = require("cookie-parser")
const bodyParser = require('body-parser');
const path = require('path')
const app = express();
const auth = require('./middle/auth')
const usermodel = require('../server/database2');
const corsOptions = {
origin:true,
credentials:true
};
app.use(cors(corsOptions));
app.use(cookieParser());
app.use(bodyParser.json());
app.use('/pictures',express.static(path.join(__dirname,'pictures')));

问题原因及解决方案

1. 核心问题:请求头拼写错误

客户端请求头里的ContentType拼写错误,正确的应该是Content-Type。这个错误会导致服务器无法正确解析JSON格式的请求体,最终req.body里的name、email、message都是undefined,传入addMessage方法后,Mongoose因为验证规则(name为必填项)抛出错误。

2. 其他辅助问题

  • 路由里重复调用了await userif.save(),addMessage方法内部已经执行过save,重复调用没必要。
  • 客户端成功判断逻辑写反:状态码201是成功,却打印了"Message not sent!!"。

修改后的代码

客户端代码修正
const submitContact = async(e)=>{
  e.preventDefault();
  const {name,email,message} = contact;
  // 先打印确认参数是否正确获取
  console.log('要发送的参数:', {name,email,message});
  const response = await fetch('http://localhost:4000/sent',{
    method:'POST',
    credentials: 'include',
    headers:{
      "Accept":"application/json",
      "Content-Type":"application/json" // 修正拼写错误
    },
    body:JSON.stringify({name,email,message})
  })
  const data = await response.json(); // 取消注释,方便查看返回信息
  if(response.status===201){
    window.alert('发送成功!')
    console.log('消息发送成功!!') // 修正逻辑
  }else{
    window.alert('服务器错误..')
    console.error('服务器返回错误:', data) // 打印错误信息便于排查
  }
  console.log(contact);
}
路由代码修正
app.post('/sent',auth,async(req,res)=>{
  try{
    const {name,email,message} = req.body;
    // 取消注释这段,提前拦截空值请求
    if(!name || !email || !message){
      console.log('请求体存在空值:', req.body);
      return res.status(400).json({error:"姓名、邮箱、消息都不能为空"})
    }
    const userif = await usermodel.findOne({_id:req.userid});
    if(userif){
      const umessage = await userif.addMessage(name,email,message)
      // 移除重复的save调用
      console.log(userif);
      res.status(201).json({message:"消息添加成功.."})
    }else{
      console.log("未找到目标用户")
      res.status(404).json({error:"未找到目标用户"})
    }
  }catch(e){
    console.log(e);
    res.status(500).json({error: e.message}) // 返回错误信息给客户端,便于排查
  }
})

额外建议

  • 可以把Express里的app.use(bodyParser.json())替换为app.use(express.json()),因为Express 4.16版本之后已经内置了bodyParser的json解析功能,避免版本兼容问题。
  • 客户端发送请求前,先打印{name,email,message}确认这些值是否正确从contact对象中获取到,排除前端数据绑定的问题。

内容的提问来源于stack exchange,提问作者Vivek Bhardwaj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 15:30:58