我試圖通過根據請求的路徑調用某些中間件功能來縮短我的Express/Connect中間件管道。快速/連接:撥打電話給redis後無法解析主體
然而,以下將失敗:
_cookieParser(req, res, function(err) {
if(err) return next(err);
_session(req, res, function(err) {
if(err) return next(err);
_csrf(req, res, function(err) {
if(err) return next(err);
loadUserFromSession(req, res, function(err) {
if(err) return next(err);
if(req.method == "POST") {
_bodyParser(req, res, next);
} else {
next();
}
});
});
});
});
但是,這將很好地工作:
_cookieParser(req, res, function(err) {
if(err) return next(err);
_session(req, res, function(err) {
if(err) return next(err);
_csrf(req, res, function(err) {
if(err) return next(err);
_bodyParser(req, res, function(err) {
if(err) return next(err);
loadUserFromSession(req, res, next);
});
});
});
});
其中loadUserFromSession是:
function loadUserFromSession(req, res, next) {
if(req.session && req.session.userId) {
userFunctions.getUserById(req.session.userId, function(err, user) {
if(err) return next(err);
if(user) {
req.user = user;
return next();
} else {
req.session.destroy();
return next(new Error('Unauthenticated'));
}
});
} else {
return next(new Error('Unauthenticated'));
}
};
我爲什麼不能叫bodyParser() loadUserFromSession()之後?
編輯
對不起,在故障/意想不到的結局缺乏細節。
如果我在loadUserFromSession()之後放了bodyParser()或者只是json()(因爲POST內容是json),調用永遠不會返回到json()的內部。如果我在res.on('data')或res.on('end')節點檢查器中放置斷點,則不會觸發。
的JSON中間件的源代碼如下:
exports = module.exports = function(options){
var options = options || {}
, strict = options.strict !== false;
var limit = options.limit
? _limit(options.limit)
: noop;
return function json(req, res, next) {
if (req._body) return next();
req.body = req.body || {};
if (!utils.hasBody(req)) return next();
// check Content-Type
if ('application/json' != utils.mime(req)) return next();
// flag as parsed
req._body = true;
// parse
limit(req, res, function(err){
if (err) return next(err);
var buf = '';
req.setEncoding('utf8');
req.on('data', function(chunk){
buf += chunk <==BREAKPOINT NEVER GETS CALLED
});
req.on('end', function(){
var first = buf.trim()[0]; <==BREAKPOINT NEVER GETS CALLED
if (0 == buf.length) {
return next(400, 'invalid json, empty body');
}
if (strict && '{' != first && '[' != first) return next(400, 'invalid json');
try {
req.body = JSON.parse(buf, options.reviver);
next();
} catch (err){
err.body = buf;
err.status = 400;
next(err);
}
});
});
}
};
請修改您的問題,並用實際的錯誤消息和堆棧跟蹤替換「會失敗」,或者如果失敗不是錯誤,請描述錯誤行爲。 – 2013-05-11 23:46:46
方面的評論,使用中間件的方式較少。你有什麼是明確的unidiomatic(禮貌地說)。如果你只想在某些路徑上使用某些東西,那麼嘗試'app.use('/ some/path',someMiddleware)',但是如果不適用於當前請求,那麼大多數中間件的成本確實很小。例如,bodyParser只需檢查請求方法,並在沒有主體的情況下立即調用next()。這是一個你不應該試圖解決的問題。 – 2013-05-11 23:50:34
@PeterLyons在我的問題上增加了更多細節。在結構上,我根本不反對你。我走在這條道路上,不是因爲性能,而是因爲安全。我不希望我的應用上傳每個可能發佈的文件。我有一些公開的端點,有些不是。我不想讓我的應用程序超負荷(或DDOS'd,如果它已知道),只是由人上傳文件到不允許上傳的端點。 – Dave 2013-05-13 15:28:14