我正在尝试根据请求查询参数决定使用中间件。
在主模块中我有这样的东西:
app.use(function(req, res){
if (req.query.something) {
// pass req, res to middleware_a
} else {
// pass req, res to middleware_b
}
});
middleware_a
和middleware_b
两个表达应用本身由express()
函数创建,而不是常规中间件函数(function(req, res, next)
)
无法找到办法
答案 0 :(得分:24)
连接/表达'中间件'并不神奇:它们只是功能 - 您可以像调用任何其他功能一样调用它们。
所以在你的例子中:
app.use(function(req, res, next){
if (req.query.something) {
middlewareA(req, res, next);
} else {
middlewareB(req, res, next);
}
});
也就是说,可能有更优雅的方式来构建分层表达应用程序。查看TJ's video
答案 1 :(得分:8)
我知道这个问题已经过时了,但我想分享一下我的解决方案。我通过创建一个返回带有回调的中间件的函数来解决这个问题。
示例中间件:
function isAdminUser(callback){
return function(req, res, next){
var userId = callback(req);
// do something with the userID
next();
}
}
然后,您可以在快速路由器对象
中执行以下操作app.use(isAdminUser(function(res){
return res.body.userId
});
答案 2 :(得分:6)
我不会使用该中间件 - 而是在中间件A和B中检查以下内容:
//Middleware A
app.use(function(req, res){
// If it doesn't match our condition then send to next middleware
if (!req.query.something) {
next();
} else {
// We're good - let this middleware do it's thing
...
next();
}
});
与中间件B相同
//Middleware B
app.use(function(req, res){
if (req.query.something) {
...
});
答案 3 :(得分:1)
看起来你可能错过了这个伎俩。 每个中间件都是请求处理程序。首先查看第一个请求处理程序,然后查看下一个请求处理程序,然后查看下一个,依此类推。
以下是中间件的基本外观:
function myFunMiddleware(request, response, next) {
// Do stuff with the request and response.
// When we're all done, call next() to defer to the next middleware.
next();
}
我建议你修改你的代码。
app.use(function(request, response, next) {
if (request.url == "/") {
response.writeHead(200, { "Content-Type": "text/plain" });
response.end(".. Any custom msg..\n");
// The middleware stops here.
}
else {
next();
}});
请通过此tutorial,我相信您将对使用中间件有一个很好的概述。有一个快乐的编码。
答案 4 :(得分:1)
我知道我对这个帖子有点迟,但你可以使用这个插件 Express Conditional Tree Middleware
它允许您组合多个和异步中间件。
具体来说,您可以创建两个代表中间件的类(middleware_a,middleware_b),并且驻留在这些类中的applyMiddleware
方法内部将返回由中间件函数创建的承诺或自定义解析的承诺。你的中间件功能了。
然后在你的主js文件中,你可以创建一个chainer,根据你的需要有条件地组合这些中间件!查看文档以获取更多信息,检查代码后会更清楚。
答案 5 :(得分:0)
如果您像我一样在这里着陆,希望在有条件的中间件(例如护照或会议)下使用第三方中间件,这是您的操作方式:
app.use((req, res, next) => {
// your condition
if (req.url !== 'no-session') {
// Your middleware
session()(req, res, next);
} else {
next();
}
})
这仅在满足条件时触发会话。您必须将(req,res,next)作为第二个函数的参数发送给第二个函数,始终将其返回以连接中间件。对于任何中间件,无论是您自己的还是第三方的,它都适用。
答案 6 :(得分:0)
我也有同样的需求,所以我创建了一个包装程序来创建条件中间件。
const conditionalMiddleWare = function(condition) {
return function(middleware) {
return function(req, res, next) => {
if (
(typeof condition == 'boolean' && condition) ||
(typeof condition == 'function' && condition(req, res, next))
) {
return middleware(req, res, next);
}
next();
};
}
}
您可以将其与布尔值一起使用
// Only use this middleware on production environment
forProduction = conditionalMiddleWare(server.settings.env === 'production');
server.use(forProduction(auth.connect()));
您可以根据要求使用功能即时决定
// Only use this middleware when it's not the `/api/` folder that is requested
const forNotApi = conditionalMiddleWare(function(req) {
return !req.path.startsWith('/api/');
});
server.use(forNotApi(express.static(rootDir)));
我希望它能有所帮助!
答案 7 :(得分:0)
对于异步函数,你可以这样做:
// Generic middleware style function.
const processData = async(data) => {
// Do some processing.
const processedData = await something(data);
if (response.error) {
return [{message: "There was an error"}];
}
return [ false, processedData ]
}
const routeMiddleware = async(req, res, next) => {
if (req.body.data.property === 'a') {
const [ err, processedData] = await processData(req.body.data);
if (err) next(err);
return res.json({ message: 'Successfully processed', processedData});
} else {
return res.json({ message: 'Not processed'});
}
}
这种模式的优点:
在异步函数调用周围包裹一个 try/catch 块也可能是一个好主意,或者使用 @awaitjs/express。