是否有规范的方法来从堆栈中删除添加app.use
的中间件?它似乎是should be possible to just modify the app.stack
array directly,但我想知道是否有一个记录的方法我应该首先考虑。
use
实际上来自Connect(不是Express)和all it really does is push the middleware function onto the app's stack
。
所以你应该很好地将函数拼接出数组。
但是,请记住,没有关于app.stack
的文档,也没有删除中间件的功能。您将面临Connect未来版本的风险,使更改与您的代码不兼容。
似乎没有内置方法可以做到这一点,但你可以设法用一个小技巧获得相同的结果。创建你自己的中间件数组(让我们称之为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个中间件中,这将循环遍历数组。当您向数组添加或删除处理程序时,只会调用数组中剩余的处理程序。
如果您从基于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);
您可以使用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);
根据上面的提示,我在快递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包装了快递应用程序。)
据我所知,没办法删除中间件。但是,您可以随时指定一个布尔标志来“停用”中间件。
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在直接操作中间件堆栈时的行为方式