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

Bra*_*rad 20 connect node.js express

有没有规范的方法来删除app.use从堆栈中添加的中间件?似乎应该可以app.stack直接修改数组,但我想知道是否有一个我应该首先考虑的文档化方法.

jos*_*736 21

use实际上来自Connect(而不是Express),它真正做的就是将中间件功能推送到应用程序上stack.

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

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

  • 或者"表达"使更改与您的代码不兼容.`express`不再依赖于`connect`,所以我认为这不再适用了. (4认同)

Gaa*_*far 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()
            }
        }
    );
})
Run Code Online (Sandbox Code Playgroud)

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


小智 5

如果您从基于 express 构建的框架继承一些不需要的中间件,那么这是一个有用的功能。

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

// app is your express service

console.log(app._router.stack)
// [Layer, Layer, Layer, ...]
Run Code Online (Sandbox Code Playgroud)

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

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

然后您可以使用标准数组方法(如 splice/unshift/etc)移动/删除它们

// Remove the matched middleware
app._router.stack.splice(middlewareIndex, 1);
Run Code Online (Sandbox Code Playgroud)