首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用express-flash或connect-flash会导致消息对象为空

使用express-flash或connect-flash会导致消息对象为空
EN

Stack Overflow用户
提问于 2021-03-26 07:51:42
回答 1查看 436关注 0票数 0

我试着用express做一个NodeJS网络服务器,结果遇到了一个奇怪的bug,我搞不懂。

我非常熟悉Express & EJS,这次我想使用connect-flash (或express- flash )来显示flash消息。我读了一些关于这两个的内容,看了一些教程,但我不明白为什么它不能工作。connect-flash和express-flash的结果基本相同,如下所示:

我导入express,session,然后flash,启动视图引擎,session,然后flash:

代码语言:javascript
复制
const express        = require("express");

const session        = require("express-session");
const flash          = require("express-flash");

app.set("view engine", "ejs");

app.use(session({
    secret: process.env.SESSION_SECRET,
    resave: true,
    saveUninitialized: true,
    cookie: { secure: true }
}));

app.use(flash());

然后我做一些身份验证的事情。例如,当用户注册时,我使用passport进行身份验证:

代码语言:javascript
复制
router.post("/register", (req, res) => {
    const { name, email, password, confirmpassword } = req.body;
    let errors = [];

    if(!name || !email || !password || !confirmpassword)
        errors.push({ message: "Please fill in all fields!" });
    
    if(password !== confirmpassword) 
        errors.push({ message: "Passwords do not match!" });

    if(password.length < 6)
        errors.push({ message: "Password should be at least 6 characters long!" });

    if(errors.length > 0) {
        res.render("register", { errors, name, email });
    } else {
        User.findOne({ email: email })
        .then(user => {
            if(user) {
                errors.push({ message: "A user with this email address already exists!" });
                res.render("register", { errors, name, email });
            } else {
                const newUser = new User({
                    name,
                    email,
                    password
                });

                bcrypt.genSalt(10, (error, salt) => {
                    if(error)
                        throw error;
                    
                    bcrypt.hash(newUser.password, salt, (error, hash) => {
                        if(error)
                            throw error;
                        
                        newUser.password = hash;
                        newUser.save()
                            .then(user => {
                                req.flash("success_message", "You have successfully registered!");
                                res.redirect("/login");
                            })
                            .catch(error => console.log(error));
                    })
                })
            }
        });
    }
});

这就是我不能理解的部分。正如您所看到的,在创建新用户时,我会传递一条闪光消息(success_message)。重定向工作得很好,总的来说,整个服务器都工作得很好,但是闪光消息是空白的。在其他情况下也会发生这种情况,例如注销时:

代码语言:javascript
复制
router.get("/logout", (req, res) => {
    req.logout();
    req.flash("success_message", "You logged out successfully!");
    res.redirect("/login");
});

或者在登录前加载页面时:

代码语言:javascript
复制
    ensureAuthenticated: (req, res, next) => {
        if(req.isAuthenticated())
            return next();

        req.flash("error_message", "Please log in to view that resource");
        res.redirect("/login");
    },

甚至在passport策略本身:

代码语言:javascript
复制
new localStrategy({ usernameField: 'email', passReqToCallback: true }, (req, email, password, done) => {
            User.findOne({ email: email })
                .then(user => {
                    if(!user)
                        return done(null, false, req.flash("error_message", "The email and password you entered did not match any of our records. Please double-check and try again."));

                    bcrypt.compare(password, user.password, (error, match) => {
                        if(error)
                            throw(error);

                        if(match)
                            return done(null, user);

                        return done(null, false, req.flash("error_message", "The email and password you entered did not match any of our records. Please double-check and try again."));
                    });
                })
                .catch(error => console.log(error));
        })
    );

我尝试通过名为messages.ejs的部分页面加载flash消息:

代码语言:javascript
复制
<% console.log(locals) %>
<% console.log(messages) %>

<% if(messages.success_message) { %>
    <div class="alert alert-success alert-dismissible fade show" role="alert">
        <%= messages.success_message %>
        <button type="button" class="close" data-dismiss="alert" aira-label="Close">
            <span aria-hidden="true">&times;</span>
        </button>
    </div>
<% } %>


<% if(messages.error_message) { %>
    <div class="alert alert-danger alert-dismissible fade show" role="alert">
        <%= messages.error_message %>
        <button type="button" class="close" data-dismiss="alert" aira-label="Close">
            <span aria-hidden="true">&times;</span>
        </button>
    </div>
<% } %>

但前两个console.log只是返回本地变量对象,在其中您可以清楚地看到消息是空的。

代码语言:javascript
复制
{
  settings: {
    'x-powered-by': true,
    etag: 'weak',
    'etag fn': [Function: generateETag],
    env: 'development',
    'query parser': 'extended',
    'query parser fn': [Function: parseExtendedQueryString],
    'subdomain offset': 2,
    'trust proxy': false,
    'trust proxy fn': [Function: trustNone],
    view: [Function: View],
    views: 'D:\\Workspace JavaScript\\Passager\\views',
    'jsonp callback name': 'callback',
    'view engine': 'ejs'
  },
  messages: {},
  contentFor: [Function: contentFor],
  _locals: [Object: null prototype] { messages: {} },
  cache: false
}

我不会在任何地方记录闪光消息,也不会做任何事情来“删除”它们。我甚至尝试过手动抛出router.get请求:

代码语言:javascript
复制
router.get("/login", forwardAuthenticated, (req, res) => res.render("login", {message: req.flash('success_message')}));
router.get("/register", forwardAuthenticated, (req, res) => res.render("register", {message: req.flash('success_message')}));

但是,我似乎不明白为什么他们没有展示。

谁有什么想法?:)

EN

回答 1

Stack Overflow用户

发布于 2021-03-26 08:07:56

对于将来遇到此主题的任何人:

我尝试了几乎所有的方法,并意识到如果发生此问题,您需要检查一些关键因素:

  1. 确保导入express,然后导入express-session,最后导入express-flash。使用它们也是如此。首先为会话调用app.use,然后为闪存调用。

  1. 如果使用passport,请确保在localStrategy parameters

中将‘passport’设置为true

代码语言:javascript
复制
new localStrategy({ usernameField: 'email', passReqToCallback: true }, (req, email, password, done) => {

这样你就可以设置闪光信息

  1. 确保您不调用req.flash("key");,因为它也会删除您的值。一旦被调用,存储的值就会被删除。

  1. 最后的答案,这就是发生在我身上的事情。我在本地环境中对其进行了测试,并使用

设置了会话

代码语言:javascript
复制
cookie: { secure: true }

这会导致cookie无法保存,从而导致flash消息无法保存。

希望它是有用的:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66809137

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档