从Express堆栈中删除中间件的正确方法?

时间:2013-09-03 22:33:56

标签: node.js express connect

是否有规范的方法从堆栈中删除添加了app.use的中间件?它似乎是should be possible to just modify the app.stack array directly,但我想知道是否有一个我应该首先考虑的文件化方法。

6 个答案:

答案 0 :(得分:19)

use实际上来自Connect(不是Express)和all it really does is push the middleware function onto the app's stack

所以你应该很好地将该函数拼接出数组。

但是,请记住app.stack周围没有文档,也没有删除中间件的功能。您将面临Connect未来版本的风险,使更改与您的代码不兼容。

答案 1 :(得分:5)

似乎没有内置方法可以做到这一点,但你可以设法通过一个小技巧获得相同的结果。创建自己的中间件数组(让我们称之为dynamicMiddleware),但不要将其推送到express中,而是只推送1个中间件,它将异步执行dynamicMiddleware中的所有处理程序。按顺序。

const async = require('async')

// Middleware 
const m1 = (req, res, next) => {
    // do something here 
    next();
}

const m2 = (req, res, next) => {
    // do something here 
    next();
}

const m3 = (req, res, next) => {
    // do something here 
    next();
}

let dynamicMiddleware = [m1, m2, m3]

app.use((req, res, next) => {
    // execute async handlers one by one
    async.eachSeries(
        // array to iterate over
        dynamicMiddleware, 
        // iteration function
        (handler, callback) => {
            // call handler with req, res, and callback as next
            handler(req, res, callback)
        }, 
        // final callback
        (err) => {
            if( err ) {
            // handle error as needed

            } else {
                // call next middleware
                next()
            }
        }
    );
})

代码有点粗糙,因为我现在没有机会对其进行测试,但这个想法应该是明确的:将所有动态处理程序数组包装在1个中间件中,这将循环遍历数组。当您向数组添加或删除处理程序时,只会调用数组中剩余的处理程序。

答案 2 :(得分:2)

如果您要从基于express的框架继承一些不需要的中间件,则此功能很有用。

以我之前得到的一些答案为基础:在express 4.x中,可以在app._router.stack中找到中间件。请注意,中间件是按顺序调用的。

// app is your express service

console.log(app._router.stack)
// [Layer, Layer, Layer, ...]

提示:您可以在各个图层中搜索要删除/移动的图层

const middlewareIndex = app._router.stack.findIndex(layer => {
 // logic to id the specific middleware
});

然后,您可以使用诸如splice / unshift / etc之类的标准数组方法移动/删除它们

// Remove the matched middleware
app._router.stack.splice(middlewareIndex, 1);

答案 3 :(得分:0)

根据上面的提示,我在express 4.x上成功添加了以下内容。我的用例是记录Slack Bolt的功能,因此我可以捕获然后进行模拟:

// Define a handy function for re-ordering arrays
Array.prototype.move = function(from, to) {
  this.splice(to, 0, this.splice(from, 1)[0]);
};

// Use the normal use mechanism, so that 'extra' stuff can be done
// For example, to log further up the order, use app.use(morgan("combined"))
app.use([my-middleware]); 

// Now adjust the position of what I just added forward
const numElements = app._router.stack.length;
app._router.stack.move(numElements - 1, 1);

您可以使用     console.log("Stack after adjustment", app._router.stack) 确认您要的是新订单。 (对于Slack Bolt,我必须使用app.receiver.app,因为Bolt应用程序包装了快速应用程序。)

答案 4 :(得分:-1)

据我所知,无法删除中间件。但是,您可以随时指定一个布尔标志来“停用”中间件。

var middlewareA_isActivate = true;
//Your middleware code
function(req, res, next) {
   if (!middlewareA_isActivate) next();
   //.........
}
//Deactivate middleware
middlewareA_isActivate = false;

编辑:
在阅读了ExpressJs(4.x)代码之后,我注意到你可以通过app._router.stack访问中间件堆栈,操作从那里开始我想。尽管如此,我认为这种“技巧”可能无法在未来的Express中发挥作用 P / s:未测试Express直接操作中间件堆栈时的行为

答案 5 :(得分:-1)

我们可以这样写。

// route outside middleware

route.get("/list", (req, res)=>{
    res.send("from listing route");  
});

//use middleware

router.use(Middlewares.AuthMiddleware.isValidToken);

//routes inside the middleware

route.post("/create", (req, res)=>{
    res.send("from create route");  
});

route.delete("/delete", (req, res)=>{
    res.send("from delete route");  
});

因此,基本上,在将中间件注入您的路由之前,先编写路由。

相关问题