生产环境NextJS+Mongoose连接数据库时出现504/500错误求助
NextJS + Mongoose 生产环境注册接口500/504错误排查
问题描述
跟着YouTube上的项目搭建了NextJS+Mongoose的认证流程,试过React Server Actions和API调用两种实现方式,本地环境运行完全正常,但部署到Vercel、Heroku生产环境后,注册接口调用时持续出现504或500错误。已配置数据库环境变量,但生产环境始终无法正常运行,求排查原因。
相关代码
注册页面组件
"use client"; import Link from "next/link"; import React, { useEffect } from "react"; import {useRouter} from "next/navigation"; import axios from "axios"; import { toast } from "react-hot-toast"; export default function SignupPage() { const router = useRouter(); const [user, setUser] = React.useState({ email: "", password: "", username: "", }) const [buttonDisabled, setButtonDisabled] = 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 success", response.data); router.push("/login"); } catch (error:any) { console.log("Signup failed", error.message); toast.error(error.message); }finally { setLoading(false); } } useEffect(() => { if(user.email.length > 0 && user.password.length > 0 && user.username.length > 0) { setButtonDisabled(false); } else { setButtonDisabled(true); } }, [user]); return ( <div className="flex flex-col items-center justify-center min-h-screen py-2"> <h1>{loading ? "Processing" : "Signup"}</h1> <hr /> <label htmlFor="username">username</label> <input className="p-2 border border-gray-300 rounded-lg mb-4 focus:outline-none focus:border-gray-600 text-black" id="username" type="text" value={user.username} onChange={(e) => setUser({...user, username: e.target.value})} placeholder="username" /> <label htmlFor="email">email</label> <input className="p-2 border border-gray-300 rounded-lg mb-4 focus:outline-none focus:border-gray-600 text-black" id="email" type="text" value={user.email} onChange={(e) => setUser({...user, email: e.target.value})} placeholder="email" /> <label htmlFor="password">password</label> <input className="p-2 border border-gray-300 rounded-lg mb-4 focus:outline-none focus:border-gray-600 text-black" id="password" type="password" value={user.password} onChange={(e) => setUser({...user, password: e.target.value})} placeholder="password" /> <button onClick={onSignup} className="p-2 border border-gray-300 rounded-lg mb-4 focus:outline-none focus:border-gray-600">{buttonDisabled ? "No signup" : "Signup"}</button> <Link href="/login">Visit login page</Link> </div> ) }
API路由代码
import {connect} from "@/dbConfig/dbConfig"; import User from "@/models/userModel"; 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 if user already exists const user = await User.findOne({email}) if(user){ return NextResponse.json({error: "User already exists"}, {status: 400}) } //hash password const salt = await bcryptjs.genSalt(10) const hashedPassword = await bcryptjs.hash(password, salt) const newUser = new User({ username, email, password: hashedPassword }) const savedUser = await newUser.save() console.log(savedUser); //send verification email return NextResponse.json({message: "success"}, {status: 200}) } catch (error: any) { return NextResponse.json({error: error.message}, {status: 500}) } }
数据库连接代码
import mongoose from 'mongoose'; export async function connect() { try { mongoose.connect(process.env.MONGO_URI!); const connection = mongoose.connection; connection.on('connected', () => { console.log('MongoDB connected successfully'); }) connection.on('error', (err) => { console.log('MongoDB connection error. Please make sure MongoDB is running. ' + err); process.exit(); }) } catch (error) { console.log('Something goes wrong!'); console.log(error); } }
错误日志
frame_ant.js:1 POST https://hate-my-life-2263e32f7a48.herokuapp.com/api/users/signup 500 (Internal Server Error) t.send @ frame_ant.js:1 (anonymous) @ 124-4ee39ffa73575f2e.js:14 xhr @ 124-4ee39ffa73575f2e.js:14 ex @ 124-4ee39ffa73575f2e.js:14 request @ 124-4ee39ffa73575f2e.js:14 (anonymous) @ 124-4ee39ffa73575f2e.js:14 (anonymous) @ 124-4ee39ffa73575f2e.js:14 m @ page-e1564dbf3d774990.js:1 ae @ bce60fc1-ece4c58e84f01921.js:9 ao @ bce60fc1-ece4c58e84f01921.js:9 (anonymous) @ bce60fc1-ece4c58e84f01921.js:9 u8 @ bce60fc1-ece4c58e84f01921.js:9 u6 @ bce60fc1-ece4c58e84f01921.js:9 (anonymous) @ bce60fc1-ece4c58e84f01921.js:9 oC @ bce60fc1-ece4c58e84f01921.js:9 io @ bce60fc1-ece4c58e84f01921.js:9 sn @ bce60fc1-ece4c58e84f01921.js:9 i9 @ bce60fc1-ece4c58e84f01921.js:9 i5 @ bce60fc1-ece4c58e84f01921.js:9 page-e1564dbf3d774990.js:1 Signup failed Request failed with status code 500
排查关键点
数据库连接问题
- 检查MongoDB Atlas的IP白名单设置,确认是否允许Vercel/Heroku的服务器IP访问,可临时开放
0.0.0.0/0测试(测试后需及时改回) - 验证生产环境的
MONGO_URI是否正确,避免复制时遗漏后缀、密码错误等问题,可在API路由中添加console.log(process.env.MONGO_URI)打印验证 - 修改数据库连接代码,添加
await等待连接完成:
同时API路由中需等待连接函数执行:// 原代码 mongoose.connect(process.env.MONGO_URI!); // 修改后 await mongoose.connect(process.env.MONGO_URI!);// 原代码 connect() // 修改后 await connect()
API路由异步处理问题
- 确保bcryptjs依赖已正确安装到生产环境,检查
package.json中是否包含该依赖,避免生产构建时遗漏 - 可适当降低bcryptjs的salt值(比如从10改为8),减少密码哈希的计算时间,避免触发平台超时限制
超时与平台限制
- Heroku免费版有30秒请求超时限制,若数据库操作+哈希计算耗时过长会触发504错误,需优化操作速度
- 选择MongoDB Atlas的就近节点,降低网络延迟
日志排查
- 查看Vercel/Heroku的服务器日志,确认API路由中的
console.log(reqBody)、console.log(savedUser)是否输出,定位请求是否到达服务器、在哪一步出错 - 完善catch块的错误日志,打印详细错误信息:
catch (error: any) { console.error("Signup API Error:", error); return NextResponse.json({error: error.message}, {status: 500}) }
内容的提问来源于stack exchange,提问作者lyub12
相关产品推荐
相关产品推荐

