提交数据至MongoDB时遭遇500错误及空值问题求助
问题排查与解决:表单提交数据为null且返回500错误
问题根源分析
1. 用户输入数据未存入数据库
API代码中硬编码了固定测试值(gebruikersNaam: "Jack"、risicoScore: 4),完全未使用前端提交的请求体数据,导致数据库始终存入预设值,而非用户输入内容。
2. 500服务器错误
- App Router路由类型误用:API文件位于
app/api/risk(Next.js 13+ App Router),但使用了Pages Router专属的NextApiRequest/NextApiResponse类型,导致请求体无法被正确解析,引发后续错误。 - 类型不匹配:前端
rangeValue存在字符串/数字混合的情况(初始值为"50",仅值为"0"时转为数字),而MongoDB接口Riskscore要求risicoScore为number类型,类型不一致会触发数据库插入时的隐性报错。
修复代码
1. 前端Form.tsx修正(统一rangeValue为数字类型)
'use client' import React, { FormEvent, useState } from "react"; import axios from 'axios'; const Form: React.FC = () => { // 统一rangeValue为number类型,避免类型混合 const [rangeValue, setRangeValue] = useState<number>(50); const [name, setName] = useState(''); const giveRangeValue = (event: React.ChangeEvent<HTMLInputElement>) => { // 直接将滑块输入转为数字 setRangeValue(Number(event.target.value)); } const handleSubmit = async (e: FormEvent<HTMLFormElement>) => { e.preventDefault() console.log("Name:", name); console.log("Range Value:", rangeValue); const postData = { gebruikersNaam: name, risicoScore: rangeValue, }; try { const response = await axios.post('/api/risk', postData); console.log(response.data); } catch (error) { console.error("提交失败:", error); } } return ( <main className={"flex flex-row"}> <form onSubmit={handleSubmit}> <div className={"form-div space-y-4"}> <div className={"alert flex flex-col items-start"}> <label>Naam</label> <input className={'input'} id="email" value={name} type="text" name="gebruikersNaam" onChange={(e) => setName(e.target.value)} /> </div> <div className={"alert flex flex-row"}> <input id="range" type={"range"} min={0} max={100} value={rangeValue} onChange={giveRangeValue} /> <span className={"value"}>{rangeValue}</span> </div> <div className={"form-btns"}> <button className={"btn mr-5"} type={"submit"}>Maak melding</button> <button className={"btn btn-form ml-10"} type={"button"}><a href={"../"}>Terug</a></button> </div> </div> </form> </main> ) } export default Form
2. 后端API路由修正(app/api/risk/route.ts)
注意:App Router下的API文件必须命名为route.ts,并使用Web标准的Request/Response对象:
import { getCollection } from "@util/mongodb"; import { Riskscore } from "@/types/db/Riskscore"; export async function POST(req: Request) { try { // App Router下需手动解析请求体 const { gebruikersNaam, risicoScore } = await req.json(); // 验证必填字段与类型 if (!gebruikersNaam || typeof risicoScore !== 'number') { return new Response(JSON.stringify({ error: '无效的输入数据' }), { status: 400 }); } const collection = await getCollection<Riskscore>('netherlands', 'risicoscores'); // 使用前端提交的真实数据插入数据库 const result = await collection.insertOne({ overlast: "E38", gebruikersNaam, risicoScore, }); if (result.insertedId) { return new Response(JSON.stringify({ message: '数据成功存入MongoDB' }), { status: 200 }); } else { return new Response(JSON.stringify({ error: '插入数据失败' }), { status: 500 }); } } catch (error) { console.error('服务器错误:', error); return new Response(JSON.stringify({ error: '服务器内部错误' }), { status: 500 }); } }
3. Riskscore.d.ts(无需修改)
import { Document } from "mongodb"; export interface Riskscore extends Document { overlast: string gebruikersNaam: string risicoScore: number }
验证修复效果
- 前端输入用户名、调整滑块后,控制台会打印正确的用户输入值。
- 提交后,MongoDB将存入用户输入的真实数据。
- 服务器返回200状态码,不再出现500错误。
内容的提问来源于stack exchange,提问作者B.Simsek
相关产品推荐
相关产品推荐

