NextJS注册页面提交报错:Mongoose必填字段验证失败
注册页面提交触发Mongoose必填字段验证失败问题解决
问题描述
我是一名中级JavaScript开发者,这是我的第二个NextJS项目。当前注册页面存在以下问题:
- 使用ThunderClient发送POST请求时无任何错误,数据能正常存入MongoDB
- 通过注册页面提交表单时触发MongooseValidatorError,提示:
用户验证失败:password:路径password为必填项,email:路径email为必填项,name:路径name为必填项 - 日志显示字段值均为
undefined,移除Mongoose模型中必填限制后,会向MongoDB插入空数据
相关代码
注册页面组件代码
import React from "react"; import { useState } from "react"; import Link from "next/link"; const Signup = () => { const [name, setName] = useState() const [email, setEmail] = useState() const [password, setPassword] = useState() const handleChange = (e) => { if(e.target.name == 'name'){ setName(e.target.value); } else if(e.target.name == 'email'){ setEmail(e.target.value); } else if(e.target.name == 'password'){ setPassword(e.target.value); } }; const handleSubmit = async (e) => { e.preventDefault() const data = { name, email, password } let res = await fetch('http://localhost:3000/api/signup', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); let response = await res.json(); console.log(response); setName('') setEmail('') setPassword('') }; return ( <div className="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4 flex flex-col"> <form onSubmit={handleSubmit} className='mt-8 space-y-10' method="POST"> <div className="mb-4"> <label className="block text-grey-darker text-sm font-bold mb-2" htmlFor="name" > Name </label> <input value={name} onChange={handleChange} required className="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker" id="name" type="text" placeholder="name" /> </div> <div className="mb-4"> <label className="block text-grey-darker text-sm font-bold mb-2" htmlFor="email" > Email </label> <input value={email} onChange={handleChange} required className="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker" id="email" type="email" placeholder="email" /> </div> <div className="mb-6"> <label className="block text-grey-darker text-sm font-bold mb-2" htmlFor="password" > Password </label> <input value={password} onChange={handleChange} required className="shadow appearance-none border border-red rounded w-full py-2 px-3 text-grey-darker mb-3" id="password" type="password" placeholder="Password" /> <p className="text-red text-xs italic">Please choose a password.</p> </div> <div className="flex items-center justify-between"> <button className="bg-blue hover:bg-blue-dark text-black font-bold py-2 px-4 rounded" type="submit" > Sign In </button> <a className="inline-block align-baseline font-bold text-sm text-blue hover:text-blue-darker" href="/forgot" > Forgot Password? </a> </div> </form> </div> ); }; export default Signup;
Mongoose模型文件
const mongoose = require('mongoose'); const UserSchema = new mongoose.Schema( { name: {type: String, required: true}, email: {type: String, required: true, unique: true}, password: {type: String, required: true}, }, {timestamps: true} ); mongoose.models = {} export default mongoose.model("User", UserSchema);
API代码
import connectDb from "../../middleware/mongoose" import User from "../../models/User" const handler = async (req, res)=> { if(req.method == 'POST'){ let u = new User(req.body) await u.save() res.status(200).json({success: "success"}) } else{ res.status(400).json({error: "this method is not allowed"}) } } export default connectDb(handler);
日志错误信息
{ properties: [Object], kind: 'required', path: 'email', value: undefined, reason: undefined, [Symbol(mongoose:validatorError)]: true }
问题根源
注册组件中的所有<input>标签都缺少name属性,而handleChange函数是通过判断e.target.name来更新对应state的。因为没有name属性,e.target.name为空字符串,导致state从未被正确更新,最终提交给后端的data对象中name、email、password均为undefined,触发Mongoose的必填字段验证错误。
ThunderClient请求正常是因为手动构造了包含正确字段的JSON数据,不受前端表单的name属性影响。
解决方案
给每个<input>标签添加对应的name属性,确保与handleChange中的判断值一致:
修改后的注册组件关键部分
// Name输入框 <input value={name} onChange={handleChange} required className="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker" id="name" name="name" // 新增name属性 type="text" placeholder="name" /> // Email输入框 <input value={email} onChange={handleChange} required className="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker" id="email" name="email" // 新增name属性 type="email" placeholder="email" /> // Password输入框 <input value={password} onChange={handleChange} required className="shadow appearance-none border border-red rounded w-full py-2 px-3 text-grey-darker mb-3" id="password" name="password" // 新增name属性 type="password" placeholder="Password" />
同时建议给useState初始化空字符串,避免初始值为undefined:
const [name, setName] = useState('') const [email, setEmail] = useState('') const [password, setPassword] = useState('')
修改后,表单输入会正确更新state,提交时后端能接收到完整的字段值,Mongoose验证通过后即可正常存入数据。
内容的提问来源于stack exchange,提问作者kanwar 31k
相关产品推荐
相关产品推荐

