简体   繁体   English

在 express.js 中使用一组中间件

[英]Use an array of middlewares at express.js

I'm trying to use an array of middlewares.我正在尝试使用一系列中间件。 Well, more like a combination of function names and arrays.好吧,更像是函数名和数组的组合。

Instead of having:而不是:

router.post('/editPassword', validate, changePassword, sendConfirmation);

I would like to have something like:我想要类似的东西:

router.post('/editPassword', validate, [changePassword, sendConfirmation] ); 

That would look like:那看起来像:

router.post('/editPassword', validate, doAction ); 

Where doAction would be an array like this:其中doAction将是这样的数组:

var doAction = [
   //equivalent of changePassword
   function(req, res, next){
      //whatever
      next();
   },

   //equivalent to the previous sendConfirmation
   function(req, res, next){
      //whatever
   }
]

But it seems it is failing and going back to the validate step after the next() within the first function in doAction .但它似乎失败并在doAction的第一个函数中的next()之后返回到validate步骤。

I'm looking for a way to simplify the middleware chaining including some middleware steps under the same name.我正在寻找一种简化中间件链接的方法,包括一些同名的中间件步骤。

I assume the reason you wanted it to look that way is not only for it to appear presentable, but also to be able to reuse the other middleware.我认为您希望它看起来那样的原因不仅是为了让它看起来像样,而且是为了能够重用其他中间件。 In that case, you can create a middleware which runs all other middlewares to do the check for you, and only calls the next function if all validations succeed.在这种情况下,您可以创建一个中间件来运行所有其他中间件来为您进行检查,并且只有在所有验证都成功时才调用下一个函数。

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

function middleware1(req, res, next) {
    if(req.query.num >= 1) {
        next();
    } else {
        res.json({message: "failed validation 1"});
    }
}

function middleware2(req, res, next) {
    if(req.query.num >= 2) {
        next();
    } else {
        res.json({message: "failed validation 2"});
    }
}

function middleware3(req, res, next) {
    if(req.query.num >= 3) {
        next();
    } else {
        res.json({message: "failed validation 3"});
    }
}

function combination(req, res, next) {
    middleware1(req, res, function () {
        middleware2(req, res, function () {
            middleware3(req, res, function () {
                next();
            })
        })
    })
}


app.get('/', combination, function (req, res) {
  res.send('Passed All Validation!');
})

app.listen(3000, function () {
  console.log('Example app listening on port 3000!')
})

You can test this app by running it then viewing http://localhost:3000/?num=3 , changing the value 3 to a lower number, or removing the num parameter.您可以通过运行它然后查看http://localhost:3000/?num=3来测试这个应用程序,将值 3 更改为较小的数字,或删除 num 参数。

I'm not sure if this is the proper way to do it, but this is how I've handled my other projects.我不确定这是否是正确的方法,但这就是我处理其他项目的方式。 Let me know what you think.让我知道你的想法。

note : see comments for use case.注意:请参阅用例的注释。 @robertklep may have a better solution depending on how you want to use middlewares @robertklep 可能有更好的解决方案,具体取决于您希望如何使用中间件

Latest version of Express can handle this:最新版本的 Express 可以处理这个问题:

function logOriginalUrl (req, res, next) {
  console.log('Request URL:', req.originalUrl)
  next()
}

function logMethod (req, res, next) {
  console.log('Request Type:', req.method)
  next()
}

var logStuff = [logOriginalUrl, logMethod]
app.get('/user/:id', logStuff, function (req, res, next) {
  res.send('User Info')
})

You can review more from this link您可以从此链接查看更多信息

Just search a little more ^^ : Less ugly and more understandable than previous answer多搜索一下^^:比以前的答案不那么难看,更容易理解

https://github.com/blakeembrey/compose-middleware https://github.com/blakeembrey/compose-middleware

Be careful that you're not doing (the equivalent of) this in your validate middleware:请注意,您没有在validate中间件中执行此操作(相当于):

function middleware(req, res, next) {
  if (someCondition) {
    console.log('some condition is true');
    next();
  }
  console.log('some condition is false');
  res.status(400).end();
}

The intention here is that after calling next the rest of the code isn't executed, but it will.这里的目的是在调用next之后其余的代码不会被执行,但它会。 There's nothing really special about next , so when you call it, after it returns the middleware code continues to run (causing both "some condition is true" and "some condition is false" to be logged). next没有什么特别的,所以当你调用它时,它返回后中间件代码继续运行(导致“某些条件为真”“某些条件为假”都被记录)。

That's why you often see this:这就是为什么你经常看到这个:

  if (someCondition) {
    console.log('some condition is true');
    return next();
    // Or, alternatively:
    // next();
    // return;
  }

The return causes the middleware function to return after calling next , so the rest of the code in the function won't be executed. return导致中间件函数在调用next后返回,所以函数中的其余代码不会被执行。

This functionality is already built into express as an array or middleware:此功能已作为数组或中间件内置在 express 中:

let combined = express.Router()
    .use(
        [
            middleware1,
            middleware2,
            middleware3,
        ],
    );
let combined = express.Router()
    .use(
        middleware1,
        middleware2,
        middleware3,
    );

Full Example完整示例

"use strict";

let Http = require("http");
let Express = require("express");

let server = Express();
let app = Express.Router();
let combined = Express.Router();

combined.use(
    function (req, res, next) {
        console.log("huzzah!");
        next();
    },
    function (req, res, next) {
        res.json({ success: true });
    }
);

function middleware0(req, res, next) {
    console.log('ground zero');
    next();
}

app.get("/combined", middleware0, combined);
server.use("/", app);

Http.createServer(server).listen(3000);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM