簡體   English   中英

在 express.js 中使用一組中間件

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

我正在嘗試使用一系列中間件。 好吧,更像是函數名和數組的組合。

而不是:

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

我想要類似的東西:

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

那看起來像:

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

其中doAction將是這樣的數組:

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

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

但它似乎失敗並在doAction的第一個函數中的next()之后返回到validate步驟。

我正在尋找一種簡化中間件鏈接的方法,包括一些同名的中間件步驟。

我認為您希望它看起來那樣的原因不僅是為了讓它看起來像樣,而且是為了能夠重用其他中間件。 在這種情況下,您可以創建一個中間件來運行所有其他中間件來為您進行檢查,並且只有在所有驗證都成功時才調用下一個函數。

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!')
})

您可以通過運行它然后查看http://localhost:3000/?num=3來測試這個應用程序,將值 3 更改為較小的數字,或刪除 num 參數。

我不確定這是否是正確的方法,但這就是我處理其他項目的方式。 讓我知道你的想法。

注意:請參閱用例的注釋。 @robertklep 可能有更好的解決方案,具體取決於您希望如何使用中間件

最新版本的 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')
})

您可以從此鏈接查看更多信息

多搜索一下^^:比以前的答案不那么難看,更容易理解

https://github.com/blakeembrey/compose-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();
}

這里的目的是在調用next之后其余的代碼不會被執行,但它會。 next沒有什么特別的,所以當你調用它時,它返回后中間件代碼繼續運行(導致“某些條件為真”“某些條件為假”都被記錄)。

這就是為什么你經常看到這個:

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

return導致中間件函數在調用next后返回,所以函數中的其余代碼不會被執行。

此功能已作為數組或中間件內置在 express 中:

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

完整示例

"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