为何调用已创建的Express路由时出现404 Not Found错误?
注册数据提交至MongoDB时出现404错误的排查与解决
我尝试将注册页面的输入数据通过Express.js路由发送至MongoDB数据库,但尽管已创建对应路由,仍持续收到404: Not Found错误。具体代码如下:
server2.js(服务器搭建、MongoDB连接及Schema创建)
const express = require('express'); const app = express(); const cors = require("cors"); app.use(cors()); require("dotenv").config({path: "./config.env"}); const mongoose = require('mongoose'); //URI key const mongoURI = process.env.ATLAS_URI; console.log(mongoURI); // Connect to the database mongoose.connect(mongoURI, { useNewUrlParser: true, useUnifiedTopology: true, }) .then(console.log("Connected to MongoDb")) .catch(err => console.log(err)); // Define a schema for the data in the "accounts" collection const accountSchema = new mongoose.Schema({ name: { type: String, required: true, unique: true, min: 2, max: 24, }, email: { type: String, required: true, unique: true, max: 200, lowercase: true, }, password: { type: String, required: true, min: 8, max: 30,} }); // Define a model for the "accounts" collection using the schema const Account = mongoose.model('Account', accountSchema); // Start the server const server = app.listen(4000, () => { console.log('Server started on port 4000'); }); server.on("listening", () => { console.log("Server is listening"); }); server.on("error", () => { console.error("Error starting server", error.message); }); module.exports = Account;
records2.js(路由创建)
const express = require("express"); import Account from "../server2"; // recordRoutes is an instance of the express router. // We use it to define our routes. // The router will be added as a middleware and will take control of requests starting with path /record. const accountsRoutes = express.Router(); import Account from "../server2"; import accountModel from "../server2"; // This route adds a new account accountsRoutes.post("http://localhost:4000/accounts/add", async (req, res) => { try { const dePackage = JSON.parse(req); console.log("Route has started"); // Checks if there's an account with the same username or email address const existingAccount = await accountModel.findOne({ $or: [{email:dePackage.email}, {username: dePackage.username}] }); if (existingAccount) { return res.status(400).json({message: "An account with that email/username already exists"}); } const newAccount = new Account({ email: dePackage.email, username: dePackage.username, password: dePackage.password} ); newAccount.save(); //find all users const allUsers = await User.find(); console.log(allUsers); } catch (err) { console.log(err); return res.status(500).json({ message: "Internal server Error"}) } })
registerPage.js(提交时调用路由的前端代码)
import React, {useState} from "react"; function RegisterPage() { // create states to be managed const [email, setEmail] = useState(""); const [userName, setUserName] = useState(""); const [password, setPassword] = useState(""); // create routes to handle changes in form const handleEmail = (event) => { setEmail(event.target.value); } const handleUsername = (event) => { setUserName(event.target.value); } const handlePassword = (event) => { setPassword(event.target.value); } const handleSubmit = async (event) => { event.preventDefault(); const response = await fetch("http://localhost:4000/accounts/add", { method: "POST", headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({email, userName, password}), }); console.log(response.body); const result = await response.json(); console.log(result); } return ( <div> <form onSubmit={handleSubmit}> <label htmlFor="email">email:</label> <input name="email" id="email" type="text" onChange={handleEmail}/> <label htmlFor="username">username: </label> <input name="username" id="password" type="text" onChange={handleUsername} /> <br/> <label htmlFor="password">password: </label> <input name="password" id="password" type="text" onChange={handlePassword}/> <br/> <input type="submit" name="submit" value="register" /> </form> </div> ) } export default RegisterPage;
我已检查服务器是否接收该路由,但显然未生效;也排查过JSON相关问题,似乎并非此原因。我是后端新手,恳请各位提供帮助。
问题排查与修复步骤
1. 路由未挂载到Express应用
server2.js中未将accountsRoutes挂载到应用,导致路由未被注册。在server2.js的mongoose连接之后、启动服务器之前添加:
const accountsRoutes = require('./records2'); // 根据实际文件路径调整 app.use('/accounts', accountsRoutes);
2. 路由路径错误
records2.js中定义POST路由时使用了完整URL,路由应使用相对路径:
// 错误写法 accountsRoutes.post("http://localhost:4000/accounts/add", ...) // 正确写法(已挂载到/accounts路径下,只需写/add) accountsRoutes.post("/add", ...)
3. 缺少JSON解析中间件
Express默认不解析JSON请求体,在server2.js的app.use(cors())之后添加:
app.use(express.json());
4. 混用CommonJS与ES模块
records2.js同时使用require和import,统一改用CommonJS:
const Account = require("../server2"); const accountModel = require("../server2");
5. Schema字段与提交数据不匹配
Schema定义的是name字段,前端提交的是userName,后端创建账户用的是username,三者不统一。可修改Schema:
const accountSchema = new mongoose.Schema({ username: { type: String, required: true, unique: true, min: 2, max: 24, }, // 其他字段不变 });
6. 异步操作与请求体处理错误
newAccount.save()需加await确保数据保存完成User.find()中的User未定义,改用Account.find()JSON.parse(req)错误,直接使用req.body(已被express.json()解析)
修改后的路由逻辑:
accountsRoutes.post("/add", async (req, res) => { try { const { email, userName, password } = req.body; console.log("Route has started"); const existingAccount = await accountModel.findOne({ $or: [{email}, {username: userName}] }); if (existingAccount) { return res.status(400).json({message: "An account with that email/username already exists"}); } const newAccount = new Account({ email, username: userName, password }); await newAccount.save(); const allUsers = await Account.find(); console.log(allUsers); res.status(201).json({message: "Account created successfully", user: newAccount}); } catch (err) { console.log(err); return res.status(500).json({ message: "Internal server Error"}) } })
7. 前端输入ID错误
前端用户名输入框id写错,修改为:
<input name="username" id="username" type="text" onChange={handleUsername} />
内容的提问来源于stack exchange,提问作者Toshhken
相关产品推荐
相关产品推荐

