MERN基础应用前端无法向后端传递数据问题求助
MERN应用表单数据无法传递到后端,ValidationError问题解决
问题描述
开发基础MERN应用时,前端提交表单后,后端返回ValidationError,提示所有字段均为必填项,但前端已正常填写数据。
前端代码
import { useState } from 'react'; const SurveyForm = () => { const [name, setName] = useState(''); const [gender, setGender] = useState('male'); const [nationality, setNationality] = useState(''); const [email, setEmail] = useState(''); const [phoneNumber, setPhoneNumber] = useState(''); const [address, setAddress] = useState(''); const [message, setMessage] = useState(''); const [hiddenText, setHiddenText] = useState(''); const handleSubmit = async(e) => { e.preventDefault(); if (hiddenText !== '') { alert('表单提交疑似垃圾信息。'); return; } const newSurvey = { name, gender, nationality, email, phoneNumber, address, message }; console.log(newSurvey) const response = await fetch(`http://localhost:5000/survey/add-survey`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name, gender, nationality, email, phoneNumber, address, message }) }); const jsona = await response.json(); console.log(jsona); setName(''); setGender(''); setNationality(''); setEmail(''); setPhoneNumber(''); setAddress(''); setMessage(''); alert('表单提交成功!'); } return ( <div className="min-h-screen bg-gray-100 py-6 flex flex-col justify-center sm:py-12"> <div className="relative py-3 "> <div className="relative bg-white shadow-lg sm:rounded-3xl sm:p-20"> <h1 className="text-2xl font-bold mb-8 text-center">Survey Form</h1> <form onSubmit={handleSubmit} className="space-y-6"> <div> <label htmlFor="name" className="block text-sm font-medium text-gray-700">Name:</label> <input id="name" name="name" type="text" autoComplete="name" required className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" value={name} onChange={(e) => setName(e.target.value)} /> </div> <div> <label htmlFor="gender" className="block text-sm font-medium text-gray-700">Gender:</label> <select id="gender" name="gender" required className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" value={gender} onChange={(e) => setGender(e.target.value)}> <option value="male">Male</option> <option value="female">Female</option> <option value="other">Other</option> </select> </div> <div> <label htmlFor="nationality" className="block text-sm font-medium text-gray-700">Nationality:</label> <input id="nationality" name="nationality" type="text" required className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" value={nationality} onChange={(e) => setNationality(e.target.value)} /> </div> <div> <label htmlFor="email" className="block text-sm font-medium text-gray-700">Email:</label> <input id="email" name="email" type="email" autoComplete="email" required className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" value={email} onChange={(e) => setEmail(e.target.value)} /> </div> <div> <label htmlFor="phoneNumber" className="block text-sm font-medium text-gray-700">Phone Number:</label> <input id="phoneNumber" name="phoneNumber" type="tel" required className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" value={phoneNumber} onChange={(e) => setPhoneNumber(e.target.value)} /> </div> <div> <label htmlFor="address" className="block text-sm font-medium text-gray-700">Address:</label> <textarea id="address" name="address" required className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" value={address} onChange={(e) => setAddress(e.target.value)}></textarea> </div> <div> <label htmlFor="message" className="block text-sm font-medium text-gray-700">Message:</label> <textarea id="message" name="message" required className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" value={message} onChange={(e) => setMessage(e.target.value)}></textarea> </div> <input type="text" value={hiddenText} onChange={(e) => setHiddenText(e.target.value)} style={{display: 'none'}} /> <button type="submit" className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Submit</button> </form> </div> </div> </div> ); }; export default SurveyForm;
后端代码
const express = require('express'); const router = express.Router(); const Survey = require('../models/Survey'); router.get('/get-surveys', (req, res) => { Survey.find({}, (err, surveys) => { if (err) { res.status(500).send('获取调查数据出错'); } else { res.status(200).json(surveys); } }); }); router.post('/add-survey', async (req, res) => { const surveyData = req.body; console.log(surveyData) const newSurvey = await Survey.create(surveyData); newSurvey.save() .then(() => { res.status(200).json({ message: '调查保存成功' }) }) .catch((err) => { console.log(err) res.status(500).json({ message: '保存调查出错' }); }); }); module.exports = router;
报错信息
ValidationError: 调查验证失败:message: 路径
message是必填项。, address: 路径address是必填项。, phoneNumber: 路径phoneNumber是必填项。, email: 路径nationality是必填项。, gender: 路径gender是必填项。, name: 路径name是必填项。
解决方案
1. 配置JSON解析中间件
后端未解析JSON请求体,导致req.body为空对象,Mongoose因此触发必填字段验证错误。在后端主文件(如app.js或server.js)中添加以下代码:
const express = require('express'); const app = express(); // 解析JSON格式的请求体 app.use(express.json()); // 挂载调查路由 const surveyRouter = require('./routes/survey'); app.use('/survey', surveyRouter);
2. 修复后端路由代码
避免async/await和.then()混用,且Survey.create()方法已自动保存文档,无需额外调用.save():
router.post('/add-survey', async (req, res) => { try { const newSurvey = await Survey.create(req.body); res.status(200).json({ message: '调查保存成功' }); } catch (err) { console.log(err); res.status(500).json({ message: '保存调查出错' }); } });
3. 处理跨域问题(若存在)
如果前端和后端端口不同,需配置CORS:
- 安装cors包:
npm install cors
- 在后端主文件添加:
const cors = require('cors'); app.use(cors());
内容的提问来源于stack exchange,提问作者Ashgreninja55
相关产品推荐
相关产品推荐

