【问题标题】:Expressjs: How to share route middleware accross routesExpressjs:如何跨路由共享路由中间件
【发布时间】:2012-07-27 15:52:44
【问题描述】:

我已经定义了多个路由中间件,并希望在多个路由/控制器之间共享它们。

这是我的设置:

app.js 需要 ./routes/index.js:

// load fs module
var fs = require('fs');

// import routing files
module.exports = function(app){
    fs.readdirSync(__dirname).forEach(function(file) {
        if (file == "index.js") return;
        var name = file.substr(0, file.indexOf('.'));
        require('./' + name)(app);
    });
};

index.js 会自动加载目录中的所有路由。可能的路由文件如下所示:

module.exports = function(app) {

    app.get('/contacts', function(req, res, next) {
       // routing stuff
    });

};

现在我得到了路由中间件:

function isAuthenticated(req, res, next) {
    if (!req.session.authenticated) return next(new Error('user not authenticated'));
};

function loadUser(req, res, next) {
    var query = User.findById(req.session.user_id);
    query.populate('contacts');
    query.exec(function(err, user) {
        if (err) return next(err);
        req.user = user;
        next();
    });
}

我想像这样使用:

var User = require('../models/user');

module.exports = function(app) {

    app.get('/contacts', isAuthenticated, loadUser, function(req, res, next) {
       res.json(req.user.contacts);
    });

};

我还想避免在所有路由文件中要求它们。

一个可能的解决方案也是:

// load fs module
var fs = require('fs');

var routeMiddleware = {
    loadUser: function(req, res, next) { // logic },
    isAuthenticated: function(req, res, next) { // logic },
};


// import routing files
module.exports = function(app){
    fs.readdirSync(__dirname).forEach(function(file) {
        if (file == "index.js") return;
        var name = file.substr(0, file.indexOf('.'));
        require('./' + name)(app, routeMiddleware);
    });
};

但我认为不是最好的......

【问题讨论】:

    标签: javascript node.js express middleware


    【解决方案1】:

    我个人会在应用程序中声明共享中间件,而不是在控制器中,即:

    routes/home.js:

    module.exports = function(req, res, next) { \\ Code }
    

    app.js:

    app.get('/', thisMiddleware, thatMiddleware, require('./routes/home'))
    

    你也可以做一个栈(数组,不是对象):

    theseMiddlewares = [thisMiddleware, thatMiddleware]
    app.get('/', theseMiddlewares, require('./routes/home'))
    

    如果这些中间件用于除少数几个以外的所有路由,您可以执行以下操作:

    theseMiddlewares = function(req, res, next) {
      if (req.url.match(some_regex_for_urls_to_skip)) next()
      else {
        \\ do stuff...
        next()
      }
    }
    

    现在你可以app.use(theseMiddlewares)那个中间件,或者如果它需要以相对于其他中间件的特定顺序发生,你可以使用app.all('*', theseMiddlewares)

    【讨论】:

    • 您好,有趣的解决方案。还有一种方法可以将中间件本身保存在应用程序中吗?我想手动使用它们,而不必担心需要它们。
    • 就像我说的,我会在应用程序中声明路由和中间件,并使路由中的每个模块成为中间件,而不是像你这样的路由。这样你只需要在你的应用中使用中间件,而不是每个路由模块。
    猜你喜欢
    • 2019-03-04
    • 2017-09-18
    • 2023-01-21
    • 2017-11-07
    • 2017-03-28
    • 1970-01-01
    • 2016-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多