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

Edge.js视图引擎条件判断失效问题求助

问题:Edge模板中用户认证导航菜单不切换

我跟着Node.js博客教程开发应用,其他功能正常,但导航栏无法根据用户登录状态切换菜单:

  • 未登录时req.session.userId为undefined,登录后有值
  • 但导航始终显示「Login/Register」,从不显示「Logout」

相关代码片段

index.js 全局变量设置:

app.use('*', (req, res, next) => {
    edge.global('auth', req.session.userId)
    next()
});

app.edge 布局条件渲染:

@if(!auth)
<li class="nav-item">
<a class="nav-link px-lg-3 py-3 py-lg-4" href="/auth/login">Login</a>
</li>
<li class="nav-item">
<a class="nav-link px-lg-3 py-3 py-lg-4" href="/auth/register">Register</a>
</li>
@else
<li class="nav-item">
<a class="nav-link px-lg-3 py-3 py-lg-4" href="/auth/logout">Logout</a>
</li>
@endif

完整index.js代码:

const path = require('path');
const expressEdge = require('express-edge');
const express = require('express');
const { default: edge } = require('edge.js');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cookieParser  = require('cookie-parser'); 
const fileUpload = require('express-fileupload');
const expressSession = require('express-session');
const MongoStore = require('connect-mongo');
const auth = require("./middleware/auth");
const redirectIfAuthenticated = require('./middleware/redirectIfAuthenticated');

const homePageController = require('./controllers/homePage');
const createPostController = require('./controllers/createPost');
const getPostController = require('./controllers/getPost')
const createUserController = require("./controllers/createUser");
const storeUserController = require('./controllers/storeUser');
const loginController = require("./controllers/login");
const loginUserController = require('./controllers/loginUser');
const logoutController = require("./controllers/logout");

const Post = require('./database/models/Post');

const app = new express();

mongoose.connect('MONGOURIhiddenfromyou', { useNewUrlParser: true })
    .then(() => console.log('You are now connected to Mongo!'))
    .catch(err => console.error('Something went wrong', err))

app.use(cookieParser('secret'));

app.use(expressSession({
    secret: 'secret',
    resave: true,
    saveUninitialized: false,
    store: MongoStore.create({
        mongoUrl: 'mongodb://MONGURIhiddenfromyou',
        autoRemove: 'interval',
        autoRemoveInterval: 60 * 24 // In minutes. Default
    })
}));

app.use(fileUpload());
app.use(express.static('public'));
app.use(expressEdge);
app.set('views', __dirname + '/views');
// Only Display Login and Register links to guests
edge.GLOBALS.lol = 'hehe';
app.use('*', (req, res, next) => {
    edge.global('auth', req.session.userId)
    next()
});
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
    extended: true
}));

const storePost = require('./middleware/storePost');
app.use('/posts/store', storePost);
app.get("/", homePageController);
app.get("/post/:id", getPostController);
app.get("/posts/new", auth, createPostController);
app.get('/auth/login', redirectIfAuthenticated, loginController);
app.post('/users/login', redirectIfAuthenticated, loginUserController);
app.get("/auth/register", redirectIfAuthenticated, createUserController);
app.post("/users/register", redirectIfAuthenticated, storeUserController);
app.get("/auth/logout", logoutController);
app.post("/posts/store", auth, async (req, res) => {
    const {
        image
    } = req.files

    await new Promise((resolve, reject) => {
        image.mv(path.resolve(__dirname, 'public/posts', image.name), (error) => {
            if (error) {
                reject(error);
            } else {
                resolve();
            }
        });
    });

    const post = await Post.create({
        ...req.body,
        image: `/posts/${image.name}`
    });

    res.redirect('/');
});
app.get('/about.html', (req, res) => {
    res.sendFile(path.resolve(__dirname, 'pages/about.html'));
});
app.get('/contact.html', (req, res) => {
    res.sendFile(path.resolve(__dirname, 'pages/contact.html'));
});
app.get('/post.html', (req, res) => {
    res.sendFile(path.resolve(__dirname, 'pages/post.html'));
});


app.listen(5000, () => {
    console.log('App listening on port 5000')
});

解决方案

1. 调整中间件执行顺序

全局变量设置中间件必须在expressEdge初始化之前执行,否则模板渲染时auth变量还未被赋值。修改index.js中的顺序:

// 先设置全局auth变量
app.use('*', (req, res, next) => {
    edge.global('auth', req.session.userId)
    next()
});
// 再初始化expressEdge和视图配置
app.use(expressEdge);
app.set('views', __dirname + '/views');

2. 验证Session是否正确赋值

在loginUserController中添加日志,确认登录后req.session.userId是否被正确设置:

console.log('登录后Session userId:', req.session.userId);

如果输出为空,说明登录逻辑未正确写入Session,需要检查登录控制器代码。

3. 模板调试

在app.edge中添加调试输出,确认auth变量值:

<p>调试:当前auth值 = {{ auth }}</p>
@if(!auth)
<!-- 登录/注册菜单 -->
@else
<!-- 登出菜单 -->
@endif

4. 清除浏览器缓存

强制刷新页面(Ctrl+F5)或清除浏览器缓存,避免旧页面缓存导致的显示异常。

5. 检查Session存储配置

确认expressSession的MongoStore连接正常,Session数据能持久化到MongoDB中,避免重启服务后Session丢失。


内容的提问来源于stack exchange,提问作者Olli Köhnke

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:50:18