在ExpressJS中为特定路由链接多个中间件


72

我只想验证一下内容,但无法在Express文档或在线文档中找到与此相关的内容(尽管我知道这是一个功能)。

我可以对其进行测试,但我实际上并没有一个很好的模板,希望听到社区的意见。

如果我这样定义快递路线:

app.get('/', function (req, res) {
  res.send('GET request to homepage');
});

我还可以定义一个中间件并直接加载它,例如

middleware = function(req, res){
  res.send('GET request to homepage');
});

app.get('/', middleware)

但是,我也可以链接这些路由中的至少一个来运行额外的中间件,例如身份验证,如下所示:

app.get('/', middleware, function (req, res) {
  res.send('GET request to homepage');
});

这些是无限连锁的吗?如果愿意,可以在给定的路由上添加10个中间件功能吗?我想查看app.get可以接受的参数,但是就像提到的那样,我在文档中找不到它。


是的,它们是无限可链接的,AFAIK Express将第一个参数“ get”作为模式匹配,所有后续参数均为中间件。按照编码,您的中间件将始终发送响应,因此不会再运行以下中间件。使用function(req, res, next){ ... next() }屈服于链中的下一个中间件。
柏拉图

Answers:


62

这并不是说“无限”,而是说您可以在此处添加多个中间件功能(在文档中称为“回调”):

router.METHOD(path,[callback,...]回调)

...

您可以提供多个回调,并且所有回调均被同等对待,并且行为与中间件相同,不同之处在于这些回调可以调用next('route')绕过其余的路由回调。您可以使用此机制在路由上执行前提条件,然后在没有理由继续进行匹配的路由时将控制权传递给后续路由。

如您所见,中间件功能和通常处理请求的功能(通常是添加到列表中的最后一个功能)之间没有区别。

拥有10个不是问题(如果您确实需要)。


1
好的谢谢!您在文档中找到了我找不到的那一部分。不,我什至不需要链接两个以上,但我只想知道API的结构。再次感谢!
安东尼

1
教程和文档完全需要对此进行更多地认识。非常感谢您的建议!
SeedyROM '19

112

考虑以下示例:

var middleware = {
    requireAuthentication: function(req, res, next) {
        console.log('private route list!');
        next();
    },
    logger: function(req, res, next) {
       console.log('Original request hit : '+req.originalUrl);
       next();
    }
}

现在,您可以使用以下代码添加多个中间件:

app.get('/', [middleware.requireAuthentication, middleware.logger], function(req, res) {
    res.send('Hello!');
});

因此,从上面的代码片段中,您可以看到“ requireAuthentication”和“ logger”是添加的两个不同的中间件。


5
谢谢您想知道我是否可以在其中传递数组
teebo

1
嗨-使用此方法时,是否适合将内容添加到req对象中以便在以后的中间件中访问?例如,在第一个示例中:req.user = User.find ...
James Trickey

3

Express版本“ express”:“ ^ 4.17.1”或更高版本

来自文档:中间件系列

var r1 = express.Router();
r1.get('/', function (req, res, next) {
  next();
});

var r2 = express.Router();
r2.get('/', function (req, res, next) {
  next();
});

app.use(r1, r2);

让我们尝试一个现实的例子:

tourController.js

 exports.checkBody = (req, res, next)=>{ // middleware 1
    if (!req.body.price){
        return res.status(400).json({
            status:'fail',
            message:'Missing price!!!'
        })
    }
    next();
  }

 exports.createTour = (req, res) => { // middleware 2
    tours.push(req.body);
    fs.writeFile(
      `${__dirname}/dev-data/data/tours-simple.json`,
      JSON.stringify(tours),
      (err) => {
        res.status(201).json({
          status: 'success',
          data: {
            tour: newTour,
          },
        });
      }
    );
  };

tourRouter.js

const express = require('express');
const tourController = require('./../controller/tourController')
const router = express.Router();

router.route('/')
.get(tourController.getAllTours)
.post(tourController.checkBody, tourController.createTour); 
//muliple Middleware in post route

app.js

const express = require('express');
const tourRouter = require('./route/tourRouter');
const app = express();

app.use(express.json());
app.use('/api/v1/tours', tourRouter);
module.exports = app;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.