You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用EJS表单提交数据时所有值返回undefined问题求助

问题诊断与修复方案

核心问题:Express实例混用导致解析中间件未生效

你的代码中存在Express实例不一致的关键问题:在Server类构造函数里创建了类专属的this.app = express()实例,但在setRendering、configRoutes等方法中,却直接使用了全局的app变量(开头定义的const app = express();)。这导致你配置的表单解析中间件仅挂载到了全局app上,而实际运行的服务器是类内部的this.app实例,表单提交的x-www-form-urlencoded格式数据完全没被解析,最终req.body全为undefined。

具体修复步骤

1. 统一使用类内的Express实例

修改app.js,删除全局app变量,所有方法内均使用this.app替代原有的app:

// app.js 修改后
const express = require('express');
const mongoose = require('mongoose');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser')
const loginRoutes = require('./routes/loginRoutes');
const signupRoutes = require('./routes/signupRoutes');
const logoutRoutes = require('./routes/logoutRoutes');
// 移除全局app定义:const app = express();
const path = require('path');


class Server {
    constructor() {
        this.app = express();
        this.port = process.env.PORT || 3000;
        this.app.use(express.json());
        this.path = path;

        this.setRendering();
        this.configRoutes();
        this.connectDB();
        this.serverSetup();
    }

    setRendering() {
        // 替换所有app为this.app
        this.app.use(bodyParser.urlencoded({ extended: true }));
        this.app.set('views', this.path.join(__dirname, './frontend/views'))
        this.app.set('view engine', 'ejs');
        this.app.use(express.static(this.path.join(__dirname, './frontend/static')));
        this.app.use(express.json())

    }

    configRoutes() {
        this.app.get('/', (req, res) => {
            res.render('./index')
        });

        this.app.use('/auth', loginRoutes, signupRoutes, logoutRoutes)
        this.app.get('*', (req, res) => {
            res.send('Page Not Found, check your spelling or routes');
        })
    }

    connectDB() {
        const URL = 'mongodb://localhost:27017/collection';
        require('dotenv').config();
        mongoose.connect(URL, {
            useNewUrlParser: true,
            useUnifiedTopology: true,
        })
        .then(() => {
            console.log(`Connected to MongoDB at the following URL: ${URL}`)
        })
        .catch((err) => {
            console.error('Error connecting to MongoDB:', err);
        });

        mongoose.connection.on('error', (err) => {
            console.error('MongoDB Connection Error:', err);
        });
        mongoose.connection.once('open', () => {
            console.log('Connection established');
        });
        mongoose.connection.on('disconnected', () => {
            console.log('Successfully Disconnected from MongoDB');
        });

        process.on('SIGINT', () => {
            mongoose.connection.close(() => {
                console.log('Mongoose Connection automatically Disconnected due to process termination.');
                process.exit(0);
            });
        });
    }

    serverSetup() {
        this.app.listen(this.port, () => {
            console.log(`server running at http://localhost:${this.port}/`)
        })
    }

}

new Server();

2. 可选:简化中间件配置(使用Express内置解析器)

从Express 4.16.0开始,express.urlencoded已内置body-parser.urlencoded的功能,你可以替换掉bodyParser依赖,直接使用内置解析器,减少依赖包:

setRendering() {
    // 替换bodyParser为Express内置解析器
    this.app.use(express.urlencoded({ extended: true }));
    this.app.set('views', this.path.join(__dirname, './frontend/views'))
    this.app.set('view engine', 'ejs');
    this.app.use(express.static(this.path.join(__dirname, './frontend/static')));
    this.app.use(express.json())
}

3. 验证修复效果

重启服务器后提交注册表单,此时req.body将正确获取到表单中的email、password等字段值,后续逻辑可正常执行。

额外确认项

  • 表单name属性与后端解构字段名完全匹配(你的代码已符合要求)
  • 表单method为POST、action路径与路由配置一致(你的代码已符合要求)

内容的提问来源于stack exchange,提问作者user30069178

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 15:43:14