为什么我在尝试与数据库通信时会在生产中收到 504 服务器错误

问题描述 投票:0回答:1

我快失去理智了。我已经多次这样做了。我目前正在使用我在 youtube 上找到的一些家伙项目。基本上尝试设置身份验证流程。我正在使用 nextjs 和 mongoose 来创建它。我认为使用 React 服务器操作是一个问题,所以我使用 api 调用,但可能也不是问题。

这是基本注册表。

"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);
        
    }


}

我已经为数据库设置了环境变量,但是nextjs,我有一个 AUTH_SECRET="" NEXTAUTH_URL=""

不知道这个名字是否重要,但似乎如果我将其上传到 vercel,它就不起作用。如果我将其上传到heruoku,它就不起作用。仅当我设置本地主机环境时。生产不起作用,为什么。

这是错误信息

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

说实话,我不指望你能弄清楚,如果我什至都无法弄清楚,我认为你也不会,但祝你好运。

我尝试使用最新版本从头开始基本的 nextjs 项目。创建了一个基本的注册表单、一个基本的服务器操作和 API 路由来测试这两种情况。开发工作,在huroko 和vercel 上尝试生产。使用猫鼬。不断收到 504 或 503 错误。我讨厌我的生活

typescript mongoose next.js vercel
1个回答
0
投票

我想到了两种情况:

  • 确保您的云提供商(Vercel、Heroku 或其他)拥有所有环境变量。特别是 MONGO_URI。仅仅因为您在本地拥有它们并不意味着它们在生产环境中。

  • 如果没问题,并且您正在使用 MongoDB Atlas,请检查您是否启用了访问白名单,并且它不包括您的生产 IP。

希望对你有帮助,祝你好运!

© www.soinside.com 2019 - 2024. All rights reserved.