[英]exit from chain of route specific middleware in express/ nodejs
我为这条路线设置了一系列“路由特定的中间件”,如下所示:
var express = require('express');
var server = express();
var mw1 = function(req, resp, next) {
//do stuff
if (success) {
next();
} else {
req.connection.destroy(); //without calling next()
}
};
var mw2 = function(req, resp, next) {
//do stuff
if (success) {
next();
} else {
req.connection.destroy(); //without calling next()
}
};
server.post('/some/path', [mw1, mw2], function(req, resp) {
//write response
});
[mw1, mw2]
是特定于路由/some/path
的中间件。
这与服务器范围的中间件不同,如下所示:
server.use(mw1);
server.use(mw2);
它适用于所有定义的路线。
现在我的问题是我想退出链。 也就是说,如果success
是假的mw1
,我不希望为mw2
被调用。 如果在mw2
success
为假,我不会没有调用路由函数。 目前,无论是mw1
和mw2
似乎越来越称为与否next()
被调用-我不知道为什么。
我该怎么做呢?
您可以调用next( 'route' )
,如快速api参考, application routing
部分所述 :
可以给出多个回调,所有回调都是平等对待的,并且表现得像中间件一样,但有一个例外,即这些回调可以调用
next('route')
来绕过剩余的路由回调。
var express = require('express')
, app = express()
;
// keep an eye on the function names
app.post( '/some/path', middleware1, middleware2, function route1( req, res, next ) {
// write response
});
app.all( '*', function route2( req, res, next ) {
// do something like handle a 404 request
});
app.use(function errorHandler( err, req, res, next ) {
// handle error
});
function middleware1( req, res, next ) {
// ...
if ( !success ) {
// bypasses middleware2 and route1, route2 will be called
return next( 'route' );
}
// calls middleware2
next();
}
// intentionally similar to middleware1 to keep things clear
function middleware2( req, res, next ) {
if ( !success ) {
// bypasses route1 and route2
// errorHandler will be called with the error
return next( Error( 'middleware 2 failed' ) );
}
// calls route1
next();
}
我的印象是,如果你既不调用next()
也不在路由处理函数中发送响应,则表示只是挂起。 另外FWIW我没有使用过数组,我看起来像server.post('/some/path', mw1, mw2, function(req, resp) {...
无论如何。 一种替代方法可能是重构代码,这样您只需要一个处理函数。 你有充分的理由认为mw1和mw2是中间件而不是处理程序调用的常规异步函数吗?
var express = require('express');
var server = express();
var mw1 = function(req, res, callback) {
// do stuff with req/res if necessary but don't send a response
if (success) {
callback(null);
} else {
callback('Error');
}
};
var mw2 = function(req, res, callback) {
//do other stuff but don't send a response
if (success) {
callback(null);
} else {
callback('Error');
}
};
function mwBoth(req, res){
mw1(req, res, function(err){
if(err){ return res.send(500) };
mw2(req, res, function(err){
if(err){ return res.send(500) };
// neither had an error
res.redirect('/some/other/path');
});
});
};
server.post('/some/path', mwBoth);
更多的修修补补得出了答案:
var express = require('express');
var server = express();
var mw1 = function(req, resp, next) {
//do stuff
if (success) {
next();
} else {
resp.send(406, 'Invalid because of this');
req.connection.destroy(); //without calling next()
}
};
var mw2 = function(req, resp, next) {
//do stuff
if (success) {
next();
} else {
resp.send(406, 'Invalid because of that');
req.connection.destroy(); //without calling next()
}
};
server.post('/some/path', [mw1, mw2], function(req, resp) {
//write response
});
诀窍是发送一个响应: resp.send(406, 'Invalid because of this');
就在破坏连接之前: req.connection.destroy();
事实上,在一般情况下,我发现也没有破坏连接。
(但在我的具体情况下是必需的,并且超出了这个问题的范围。)
如果响应已经发送,那么express不会自动为您调用next()
,因为它似乎没有。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.