【问题标题】:Express : How to Add Middleware Exclusively to a Large List of Routes in a Router Object?Express : 如何将中间件独占添加到路由器对象中的大量路由中?
【发布时间】:2016-06-12 11:35:07
【问题描述】:

我想通过堆叠路由器对象来模块化我的所有路由。

堆叠路由器的问题(使用 index.js 初始化并使用 router.use) 是当您想为特定路由器中的每个路由添加中间件调用(仅)但如果路由列表很大 - 尝试将中间件放在路由前面以避免必须将其插入到每个路线。

例如:将middleware.doSomething 应用于所有路由。

other.js

var express = require('express');
var router = express.Router();
var middleware = require("./middleware");


router.use(middleware.doSomething);

router.get('/routeC', function(req, res){
    ... 
});

router.get('/routeD', function(req, res){
    ... 
});

router.get('/routeE', function(req, res){
    ... 
});

exports.module = router;

问题

一个路由器的中间件处理程序,如middleware.doSomething,可能会被意外调用,因为 express 经历了从一般到特定的路径匹配过程(例如,“/”然后是“/routeA”,然后是“/routeA/:paramA” )。

例如:当尝试处理“/routeA”时,路由器特定的中间件router.use(middleware.doSomething); 将被意外调用。

路由结构

/routes
 -index.js
 -other.js

index.js

var express = require('express');
var router = express.Router();


router.use(require(./other));

router.get('/', function(req, res){
    ... 
});

router.get('/routeA', function(req, res){
    ... 
});

router.get('/routeB', function(req, res){
    ... 
});

exports.module = router;

server.js

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

问题:

我们如何将router.use(middleware.doSomething); 设为其路由器对象的私有(而不将其添加到每个单独的路由),或者通过在我们堆叠其他路由器时很好地扩展的设计/模式来避免这个问题? (我对使用前缀的任何想法持开放态度,我只是避免使用它们,因为我也不想为 ajax 调用添加前缀)。

【问题讨论】:

  • 您的代码中是否有某些部分无法按您的意愿工作? middleware.doSomething 现在只有在你在 other.js 中点击路由时才会调用。
  • 例如,如果您尝试路由到“/routeA”,middleware.doSomething 将被命中。
  • 我的机器上没有你的代码。
  • 什么?诡异的!您使用什么版本的节点/快递?按照设计,middlewar.doSomething 应该是其路由器对象 other.js 独有的吗?
  • node@v5.4.1,express@4.13.4。是的。当您将中间件添加到路由器时,它是专用的。对于一般中间件,您通常使用app.use 将其添加到 express 对象上

标签: javascript node.js express


【解决方案1】:

我相信你可以,不仅仅是设计上的,你的代码模式也是如此,方法如下:

假设你有这个 main.js

var app = require('express')();

// add universal middle ware
app.use(function(req,res,next){
    console.log("universal");
    next();
    });
// lets assume you have 2 groups of routes, then you pass your express to them.
require('./route01.js')(app);
require('./route02.js')(app);

app.listen(4321);

假设这也是一个 route01 组文件文件

module.exports = function(app)
{
    // universal middleware for routes1
    app.use('/route01',function(req, res, next){
        console.log("universal middleware for routes1")
        next();
        });

    app.get('/route01/option01',function(req,res,next){
        console.log("specific middleware for route 1 option 1");
        next();
        },function(req,res){res.send("OK")});

    app.get('/route01/option02',function(req,res,next){
        console.log("specific middleware for route 1 option 2");
        next();
        },function(req,res){res.send("OK")});
}

这是route02组文件文件

module.exports = function(app)
{
    // universal middleware for routes2
    app.use('/route02',function(req, res, next){
        console.log("universal middleware for routes2")
        next();
        });
    // pass specific middle ware for the routes
    app.get('/route02/option01',function(req,res,next){
        console.log("specific middleware for route 2 option 1");
        next();
        },function(req,res){res.send("OK")});

    app.get('/route02/option02',function(req,res,next){
        console.log("specific middleware for route 2 option 2");
        next();
        },function(req,res){res.send("OK")});
}

例如,你点击http://127.0.0.1:4321/route01/option02,输出将是

通用

路由1的通用中间件

路由 1 选项 2 的特定中间件

如果点击http://127.0.0.1:4321/route02/option01,例如你会得到

通用

routes2 的通用中间件

路由 2 选项 1 的特定中间件

【讨论】:

  • 您提供的解决方案强制您使用路由前缀。
  • @jared_flack 您是否在“我对使用前缀的任何想法持开放态度”的问题中阅读了此声明?或者你有没有读过这个问题:)
  • 这迅速升级。 @abdullah-shahin,你是对的,我没有阅读 OP 问题的那一部分。
猜你喜欢
  • 2017-03-08
  • 1970-01-01
  • 2015-11-16
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 2020-09-28
  • 2015-09-28
  • 2016-04-11
相关资源
最近更新 更多