【问题标题】:Node/Express flash message via res.locals on Heroku通过 Heroku 上的 res.locals 的 Node/Express 闪存消息
【发布时间】:2017-02-09 22:30:30
【问题描述】:

我正在使用在 res.locals 上提供错误消息,并根据需要通过重定向显示它们。我不完全确定这是如何工作的,但确实如此。至少当我在本地运行服务器时。

另一方面,部署到 Heroku,它没有。什么也没有。我在页面上犯了错误,而我的性感快讯在他们的缺席中闪闪发光。

我在本地使用 sqlite3 并使用connect-session-sequelize 存储会话。

我在 Heroku 上使用 postgres。

server.js

/* jshint node: true */
'use strict';

var express = require('express');
var session = require('express-session');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var _ = require('underscore');
var db = require('./db.js');
var SequelizeStore = require('connect-session-sequelize')(session.Store);
var flash = require('express-flash');
var app = express();
var PORT = process.env.PORT || 3000;

app.use(cookieParser());

// Track logins with express session
app.use(session({
    secret: 'Magic mike',
    resave: true,
    saveUninitialized: false,
    store: new SequelizeStore({
        db: db.sequelize
    })
}));

app.use(flash());

// Make userId available in templates
app.use(function(req, res, next){
    res.locals.currentUser = req.session.userId;
    res.locals.sessionFlash = req.session.sessionFlash;
    delete req.session.sessionFlash;
    next();
});

// To parse incoming req
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: false
}));


// Serve static files
app.use(express.static(__dirname + '/public'));

// View engine setup
app.set('view_engine', 'pug');
app.set('views', __dirname + '/views');


var routes = require('./routes/index.js');
app.use('/', routes);
....

db.js

var Sequelize = require('sequelize');
var env = process.env.NODE_ENV || 'development';
var sequelize;

if (env === 'production') {
    sequelize = new Sequelize(process.env.DATABASE_URL, {
        dialect: 'postgres'
    });
} else {
sequelize = new Sequelize(undefined, undefined, undefined, {
    'dialect': 'sqlite',
    'storage': __dirname + '/data/shoplist.sqlite'
});

}

var db = {};

db.item = sequelize.import(__dirname + '/models/item.js');
db.user = sequelize.import(__dirname + '/models/user.js');
// db.shoplist = sequelize.import(__dirname + '/models/shoplist.js');
db.sequelize = sequelize;
db.Sequelize = Sequelize;

// db.item.belongsTo(db.shoplist);
// db.shoplist.hasMany(db.item);
db.item.belongsTo(db.user);
db.user.hasMany(db.item);
// db.user.belongsTo(db.shoplist);
// db.shoplist.hasMany(db.user);


module.exports = db;
....

routes/index.js

var express = require('express');
var router = express.Router();
var _ = require('underscore');
var mid = require('../middleware/');
var db = require('../db.js');
var flash = require('express-flash');

router.all('/login-error', function(req, res) {
    res.redirect(301, '/login');
});

router.all('/register-error', function(req, res) {
    res.redirect(301, '/register');
});

// GET /homepage
router.get('/', function(req, res, next) {
    req.flash('info', 'Velkommen!');
    return res.render('index.pug', {
        title: 'Welcome!',
        url: req.originalUrl
    });
});
....
// POST /login
router.post('/login', function(req, res, next) {
    var body = _.pick(req.body, 'name', 'password');

    if (req.body.name && req.body.password) {
        db.user.authenticate(body).then(function(user) {
            req.session.userId = user.id;
            // To make sure the session is stored in db befor redirect
            req.session.save(function() {
                return res.redirect('makeitem');
            });
        }).catch(function(e) {
            var err = new Error("Wrong username or password.");
            err.status = 400;
            err.message = "Wrong username or password.";
            req.session.sessionFlash = {
                type: 'error',
                message: err.message
            };
            res.redirect('/login-error');

        });
    } else {
        var err = new Error('All fields required.');
        err.status = 400;
        err.message = 'All fields required.';
        req.session.sessionFlash = {
            type: 'error',
            message: err.message
        };
        res.redirect('/login-error');
    }

});
...
// POST /register
router.post('/register', function(req, res, next) {
    var body = _.pick(req.body, 'name', 'email', 'password');

    // Check if all fields are filled out
    if (req.body.name &&
        req.body.email &&
        req.body.password) {

        // // Check that passwords are the same
        if (req.body.password !== req.body.comf_password) {
            var err = new Error('Passwords do not match.');
            err.status = 400;
            err.message = 'Passwords do not match.';
            req.session.sessionFlash = {
                type: 'error',
                message: err.message
            };
            res.redirect('/register-error');
        } else {
            db.user.create(body).then(function(user) {
                //res.json(user.toPublicJSON());
                res.redirect('/login');
            }, function(e) {
                var err = new Error('Email or Shopping List Name in use.');
                err.status = 400;
                err.message = 'There is already a Shopping List with this name or email';
                req.session.sessionFlash = {
                    type: 'error-name',
                    message: err.message
                };
                res.redirect('/register-error');
            });
        }

    } else {
        var err = new Error('All fields required.');
        err.status = 400;
        err.message = 'All fields required.';
        req.session.sessionFlash = {
            type: 'error',
            message: err.message
        };
        res.redirect('/register-error');
    }


});
...

我正在使用 pug,所以这是我显示消息的方式:

if sessionFlash && sessionFlash.message
            .sessionflash
                p.bg-warning #{ sessionFlash.message }

这些是我的依赖项:

  "dependencies": {
    "bcrypt": "^0.8.7",
    "body-parser": "^1.15.2",
    "connect-session-sequelize": "^3.1.0",
    "cookie-parser": "^1.4.3",
    "crypto-js": "^3.1.6",
    "express": "^4.14.0",
    "express-flash": "0.0.2",
    "express-session": "^1.14.1",
    "jsonwebtoken": "^7.1.9",
    "pg": "^4.5.6",
    "pg-hstore": "^2.3.2",
    "pug": "^2.0.0-beta6",
    "sequelize": "^3.5.1",
    "sqlite3": "^3.1.4",
    "underscore": "^1.8.3"

为什么会这样?以及如何在 Heroku 上显示 flash 消息?

【问题讨论】:

  • 好的。如果我删除 delete req.session.sessionFlash; 在 res.locals 上提供的内容,则 Flash 消息将显示在 Heroku 上。但它会永远留在那里。
  • 我使用了 express-flash,现在它可以在 Heroku 上运行。它是相同的,只有我这样做:eq.flash('error', "Flash " + err.message);我不明白为什么一件事有效而另一件事无效,所以如果有人能解释它,我将不胜感激..或者指出相关知识的方向..跨度>
  • 我遇到了和你一样的问题。看来我需要切换到快速闪存?或者你知道它现在是如何工作的,所以我可以让它与 express-session 一起工作?

标签: node.js postgresql express heroku flash-message


【解决方案1】:

面对同样的问题,我意识到这与 Cloudflare 设置有关。每当我加载页面时,转发权限都会导致删除局部变量的问题。当我简单地将应用程序部署链接与 heroku 一起使用时,我就不再遇到问题了。如果您将来阅读本文,请使用命令行使用“NODE_ENV=production npm start”测试生产中的网站,使用“heroku local web”测试网站,如果两者都工作正常,问题可能出在您的身上DNS 管理器。

【讨论】:

  • 这并不能真正回答问题。如果您有其他问题,可以点击 进行提问。一旦你有足够的reputation,你也可以add a bounty 来引起对这个问题的更多关注。 - From Review
  • @bguiz 我编辑了我的答案,但我绝对认为它更适合作为评论而不是答案,不幸的是我没有足够的声誉来发表评论。我认为,无论哪种方式,让人们知道如果他们有类似的问题,这可能不是 Heroku 的问题。想一想,这些信息是否值得分享,以及我如何在无法发表评论的情况下分享这些信息。
猜你喜欢
  • 2016-06-27
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-23
  • 2018-01-22
相关资源
最近更新 更多