Express中的中间件声明是否需要订单?

时间:2014-08-08 17:03:01

标签: node.js express

我发现,如果app.js中的中间件顺序错误,则效果不佳。

例如:

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');  //
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());  //
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);
//the codes below don't work 
//set Cookie
app.use(cookieParser());
app.use(session({
    secret:setting.cookieSecret,
    key: setting.db,
    cookie:{maxAge:1000*3600*24*30},
    store: new MongoStore({db:setting.db}),
    saveUninitialized: true,
    resave: true
}) );
//use 'connect-flash'
app.use(flash());      

如果在app.use(flash())之后未移动代码app.set('view engine', 'ejs');,则该页面将显示TypeError: Object #<IncomingMessage> has no method 'flash'

更重要的是,如果我只是移动app.use(flash()),则会产生错误req.flash() requires sessions,但如果我移动cookieParse()session()跟随urlencoded(),错误就会消失

编辑第一个代码示例不再会产生错误:

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
//changed
app.use(flash());
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
//changed
app.use(cookieParser());
app.use(session({
    secret:setting.cookieSecret,
    key: setting.db,
    cookie:{maxAge:1000*3600*24*30},
    store: new MongoStore({db:setting.db}),
    saveUninitialized: true,
    resave: true
}) );

app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);

所以我想知道:    app.js中的中间件和配置是否必须遵循强制性命令?

1 个答案:

答案 0 :(得分:2)

是。您在Express中调用中间件或配置的顺序非常重要。来自express api docs

  

使用app.use()“定义”中间件的顺序非常好   重要的是,它们是按顺序调用的,因此它定义了中间件   优先级。

这就是为什么在移动不同的app.use行时会出现不同的错误。

例如,如果您对flash()函数使用connect-flash,则connect-flash需要先加载cookieparsersession中间件。存在订单依赖关系 - cookieparser,然后是session,然后是flash

订单对于路由也很重要。有关详细信息和讨论,请参阅New features in Express 4.x和此stackoverflow answer

因此,在使用express时,请检查文档以确保您满足中间件路由(如果适用)的基于订单的依赖关系。