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

问题描述 投票:17回答:5

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

node.js express connect
5个回答
20
投票

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

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

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


5
投票

似乎没有内置方法可以做到这一点,但你可以设法用一个小技巧获得相同的结果。创建你自己的中间件数组(让我们称之为dynamicMiddleware),但不要将其推送到express中,而是只推送一个中间件,它将异步并按顺序执行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个中间件中,这将循环遍历数组。当您向数组添加或删除处理程序时,只会调用数组中剩余的处理程序。


3
投票

如果您从基于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);

0
投票

您可以使用express-dynamic-middleware来实现此目的。

https://github.com/lanbomo/express-dynamic-middleware

像这样使用它

const express = require('express');

// import express-dynamic-middleware
const dynamicMiddleware = require('express-dynamic-middleware');


// create auth middleware
const auth = function(req, res, next) {
    if (req.get('Authorization') === 'Basic') {
        next();
    } else {
        res.status(401).end('Unauthorization');
    }
};

// create dynamic middleware
const dynamic = dynamicMiddleware.create(auth);

// create express app
const app = express();

// use the dynamic middleware
app.use(dynamic.handle());

// unuse auth middleware
dynamic.unuse(auth);

0
投票

根据上面的提示,我在快递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 app包装了快递应用程序。)


-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在直接操作中间件堆栈时的行为方式

© www.soinside.com 2019 - 2024. All rights reserved.