Next.js 13中表单无法通过Prisma ORM向数据库提交数据
Next.js 13 表单提交数据无法存入Postgres数据库的问题排查与修复
核心问题分析与修复步骤
1. API路由请求体获取方式错误
Next.js 13 App Router的POST函数中,不能直接通过req.body读取请求数据,必须调用await req.json()解析JSON格式的请求体。
修改后的route.js:
import { NextResponse } from 'next/server'; import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient(); export async function POST(req) { // 解析请求体(关键修复) const body = await req.json(); // 修正字段名不匹配问题:前端传的是mail,后端需要email const { name, password, mail: email } = body; try { const user = await prisma.user.create({ data: { name, email, password }, }); // 返回创建成功的用户信息,便于前端确认 return NextResponse.json({ message: '用户创建成功', user }, { status: 201 }) } catch (error) { // 打印具体错误到控制台,返回详细错误信息 console.error('创建用户失败:', error); return NextResponse.json({ message: '创建用户失败', error: error.message }, { status: 500 }) } }
2. 表单字段名不匹配
前端表单中邮箱字段注册的是mail,但API路由里尝试获取的是email,导致邮箱数据无法正确传入数据库。你可以二选一修改:
- 要么在API路由中通过解构重命名(如上代码)
- 要么修改前端表单的注册字段为
email:
<input {...register("email", { required: true, pattern: /^\S+@\S+$/i })} type="email" id="email" placeholder="Email Address" aria-invalid={errors.email ? "true" : "false"} /> {errors.email?.type === 'required' && <p className="errorMessage" role="alert">邮箱地址不能为空</p>} {errors.email?.type === 'pattern' && <p className="errorMessage" role="alert">请输入有效的邮箱地址</p>}
3. 前端请求未处理响应与错误
当前fetch请求没有检查响应状态,也没有捕获网络错误,无法判断请求是否成功。修改page.js中的onSubmit函数:
const onSubmit = async data => { console.log(data); try { const response = await fetch("/api/createuser", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.message || '请求失败'); } const result = await response.json(); console.log('用户创建成功:', result); router.push("/login"); reset(); } catch (error) { console.error('提交失败:', error); // 这里可以添加前端错误提示,比如弹窗/toast } }
4. 密码验证规则与提示不一致
输入框提示密码最少8位,但验证规则是minLength:4,建议统一规则:
<input {...register("password", { required: true, minLength: 8 })} id="password" placeholder="Password must contain a minimum of 8 characters" aria-invalid={errors.password ? "true" : "false"} /> {errors.password?.type === 'required' && <p className="errorMessage" role="alert">密码不能为空</p>} {errors.password?.type === 'minLength' && <p className="errorMessage" role="alert">密码长度不能少于8位</p>}
内容的提问来源于stack exchange,提问作者user19102549
相关产品推荐
相关产品推荐

