Next.js注册页面触发500错误,终端报Cannot read properties of undefined (reading 'headers')
注册接口500错误及TypeError排查
错误现象
- 前端控制台提示:
signup failed Request failed with status code 500 - 终端抛出:
TypeError: Cannot read properties of undefined (reading 'headers'),错误栈指向Next.js路由模块
注册页面(page.tsx)代码
"use client" import React, { useEffect} from "react"; import Link from "next/link"; import axios from "axios" import { useRouter } from "next/navigation"; const SignUpPage = () => { const router= useRouter(); const [user, setUser]=React.useState({ username:"", email:"", password:"", }) const [buttonDisabaled, setButtonDisabaled]=React.useState(false) const [loading, setLoading]= React.useState(false) const onSignUp= async()=>{ try { setLoading(true); const response= await axios.post("/api/users/signup", user); console.log("signup Successfully", response.data); router.push("/login"); } catch (error:any) { console.log("signup failed", error.message) }finally{ setLoading(false) } } useEffect(()=>{ if(user.username.length > 0 && user.email.length > 0 && user.password.length > 0 ){ setButtonDisabaled(false) }else{ setButtonDisabaled(true) } },[user]) return ( <div> <section className="gradient-form h-full bg-neutral-200 dark:bg-neutral-700"> <div className="container h-full p-10"> <div className="g-7 flex h-full flex-wrap items-center justify-center text-neutral-800 dark:text-neutral-200"> <div className="w-full"> <div className="block rounded-lg bg-white shadow-lg dark:bg-neutral-800"> <div className="g-0 lg:flex lg:flex-wrap"> {/* Left column container*/} <div className="px-4 md:px-0 lg:w-6/12"> <div className="md:mx-6 md:p-12"> {/*Logo*/} <div className="text-center"> <img className="mx-auto w-48" src="https://tecdn.b-cdn.net/img/Photos/new-templates/bootstrap-login-form/lotus.webp" alt="logo" /> <h4 className="mb-12 mt-1 pb-1 text-xl font-semibold"> we are developers Team </h4> </div> <p className="mb-4">Sign Up</p> {/*Username input*/} <div className="relative mb-4" data-te-input-wrapper-init> <h4 className="mb-12 mt-1 pb-1 text-xl font-semibold"> {loading?"processing" :""} </h4> <label htmlFor="usermane"> Username</label> <input id="username" type="text" className="peer block min-h-[auto] w-full rounded border-0 bg-white px-3 py-[0.32rem] leading-[1.6] outline-none transition-all duration-200 ease-linear focus:placeholder:opacity-100 data-[te-input-state-active]:placeholder:opacity-100 motion-reduce:transition-none text-black [&:not([data-te-input-placeholder-active])]:placeholder:opacity-0" placeholder="Username" value={user.username} onChange={(e)=>setUser({...user, username:e.target.value})} /> </div> {/*email input*/} <div className="relative mb-4" data-te-input-wrapper-init> <label htmlFor="email">Email</label> <input id="email" type="email" className="peer block min-h-[auto] w-full rounded border-0 bg-white px-3 py-[0.32rem] leading-[1.6] outline-none transition-all duration-200 ease-linear focus:placeholder:opacity-100 data-[te-input-state-active]:placeholder:opacity-100 motion-reduce:transition-none text-black [&:not([data-te-input-placeholder-active])]:placeholder:opacity-0" placeholder="email" value={user.email} onChange={(e)=>setUser({...user, email:e.target.value})} /> </div> {/*password input */} <div className="relative mb-4" data-te-input-wrapper-init> <label htmlFor="email">Email</label> <input id="password" type="password" className="peer block min-h-[auto] w-full rounded border-0 bg-white px-3 py-[0.32rem] leading-[1.6] outline-none transition-all duration-200 ease-linear focus:placeholder:opacity-100 data-[te-input-state-active]:placeholder:opacity-100 motion-reduce:transition-none text-black [&:not([data-te-input-placeholder-active])]:placeholder:opacity-0" placeholder="Password" value={user.password} onChange={(e)=>setUser({...user, password:e.target.value})} /> </div> {/*Submit button*/} <div className="mb-12 pb-1 pt-1 text-center"> <button onClick={onSignUp} className="mb-3 inline-block w-full rounded px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white shadow-[0_4px_9px_-4px_rgba(0,0,0,0.2)] transition duration-150 ease-in-out hover:shadow-[0_8px_9px_-4px_rgba(0,0,0,0.1),0_4px_18px_0_rgba(0,0,0,0.2)] focus:shadow-[0_8px_9px_-4px_rgba(0,0,0,0.1),0_4px_18px_0_rgba(0,0,0,0.2)] focus:outline-none focus:ring-0 active:shadow-[0_8px_9px_-4px_rgba(0,0,0,0.1),0_4px_18px_0_rgba(0,0,0,0.2)]" data-te-ripple-init data-te-ripple-color="light" style={{ background: "linear-gradient(to right, #ee7724, #d8363a, #dd3675, #b44593)", }} > {buttonDisabaled ?"No SignUp" :"Sign Up"} </button> <Link href="/login"> <span className="mb-3 inline-block w-full rounded px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white shadow-[0_4px_9px_-4px_rgba(0,0,0,0.2)] transition duration-150 ease-in-out hover:shadow-[0_8px_9px_-4px_rgba(0,0,0,0.1),0_4px_18px_0_rgba(0,0,0,0.2)] focus:shadow-[0_8px_9px_-4px_rgba(0,0,0,0.1),0_4px_18px_0_rgba(0,0,0,0.2)] focus:outline-none focus:ring-0 active:shadow-[0_8px_9px_-4px_rgba(0,0,0,0.1),0_4px_18px_0_rgba(0,0,0,0.2)]" data-te-ripple-init data-te-ripple-color="light" style={{ background: "linear-gradient(to right, #ee7724, #d8363a, #dd3675, #b44593)", }} > Visit to Login </span> </Link> </div> </div> </div> </div> </div> </div> </div> </div> </section> </div> ); }; export default SignUpPage;
注册接口(route.ts)代码
import { connect } from "@/dbConfig/dbConfig" import User from "@/models/userModels" import { NextRequest, NextResponse } from "next/server" import bcryptjs from "bcryptjs" connect() export async function POST(request:NextRequest){ try { const reqBody= await request.json(); const {username, email, password}=reqBody; console.log(reqBody); //check is user Already exist or not const user = await User.findOne({email}); if(user){ return NextResponse.json({error:"user Already Exists"}) } //hashed password const saltRounds= 10; const salt=await bcryptjs.genSalt(saltRounds); const hashedPassword= await bcryptjs.hash(password,salt); const newUser= new User({ username, email, password:hashedPassword }); const savedUser= await newUser.save(); console.log(savedUser) } catch (error:any) { console.error("Error during signup:", error); return NextResponse.json({ error: error.message }, { status: 500 }); } }
问题原因及修复方案
核心问题
路由处理函数POST在用户注册成功的分支中没有返回任何响应对象,Next.js会尝试读取一个undefined值的headers属性,从而抛出TypeError: Cannot read properties of undefined (reading 'headers'),最终导致前端收到500状态码。
修复步骤
修改route.ts,在用户保存成功后添加返回成功响应:
export async function POST(request:NextRequest){ try { const reqBody= await request.json(); const {username, email, password}=reqBody; console.log(reqBody); //check is user Already exist or not const user = await User.findOne({email}); if(user){ return NextResponse.json({error:"用户已存在"}, {status: 400}) } //hashed password const saltRounds= 10; const salt=await bcryptjs.genSalt(saltRounds); const hashedPassword= await bcryptjs.hash(password,salt); const newUser= new User({ username, email, password:hashedPassword }); const savedUser= await newUser.save(); console.log(savedUser) // 新增:返回成功响应 return NextResponse.json({ message: "用户注册成功", user: { username: savedUser.username, email: savedUser.email } }, { status: 201 }) } catch (error:any) { console.error("注册过程出错:", error); return NextResponse.json({ error: error.message }, { status: 500 }); } }
额外优化点
前端密码输入框的label错误地写为Email,改为Password即可:
{/*password input */} <div className="relative mb-4" data-te-input-wrapper-init> <label htmlFor="password">Password</label> {/* 修正label的for和文本 */} <input id="password" type="password" className="peer block min-h-[auto] w-full rounded border-0 bg-white px-3 py-[0.32rem] leading-[1.6] outline-none transition-all duration-200 ease-linear focus:placeholder:opacity-100 data-[te-input-state-active]:placeholder:opacity-100 motion-reduce:transition-none text-black [&:not([data-te-input-placeholder-active])]:placeholder:opacity-0" placeholder="Password" value={user.password} onChange={(e)=>setUser({...user, password:e.target.value})} /> </div>
内容的提问来源于stack exchange,提问作者Krish Chhabra
相关产品推荐
相关产品推荐

