使用 Express.js 的路由器级中间件顺序
Router-level middleware order using Express.js
我有以下路由器:
/* GET /users/username */
router.get("/:username", function(req, res, next) {
User.findOne({
username: req.params.username
}).exec(function(err, user) {
if (err) return next(error);
res.json(user);
});
});
/* GET /users/id */
router.get("/:id", function(req, res, next) {
User.findById(req.params.id, function(err, user) {
if (err) return next(err);
res.json(user);
});
});
在上面的顺序中,/* GET /users/id */
将 return 为空,如果我交换顺序 /* GET /users/username */
将导致此错误:
Cast to ObjectId failed for value "Guest" at path "_id" for model "User"
基本上,第二个中间件被忽略了。但是,不同的行为需要两者。我正在使用 AngularJS $resource
与 RESTful 服务器端数据源进行交互。
- 为什么我不能同时使用两者?为什么第二个中间件被忽略了?
- 这两个路由器应该以什么顺序工作?
最好通过以下方式进行路由:
router.route('your/route').get(aJsFile.function);
然后,不用exec,只写
属性:['id', 'username']
其中:{用户名:用户名}
或者像这样的东西。
第二个中间件被忽略,因为 url 模式是相同的...你希望路由器如何区分 'username' 或 'id';
你必须首先检查它是否是一个 id。
router.get("/:username", function(req, res, next) {
const username = req.params.username;
if (!isNaN(parseInt(username)) { // <------ Check if it's an ID
next();
} else {
User.findOne({
username: req.params.username
}).exec(function(err, user) {
if (err) return next(error);
res.json(user);
});
}
});
/* GET /users/id */
router.get("/:id", function(req, res, next) {
User.findById(req.params.id, function(err, user) {
if (err) return next(err);
res.json(user);
});
});
我有以下路由器:
/* GET /users/username */
router.get("/:username", function(req, res, next) {
User.findOne({
username: req.params.username
}).exec(function(err, user) {
if (err) return next(error);
res.json(user);
});
});
/* GET /users/id */
router.get("/:id", function(req, res, next) {
User.findById(req.params.id, function(err, user) {
if (err) return next(err);
res.json(user);
});
});
在上面的顺序中,/* GET /users/id */
将 return 为空,如果我交换顺序 /* GET /users/username */
将导致此错误:
Cast to ObjectId failed for value "Guest" at path "_id" for model "User"
基本上,第二个中间件被忽略了。但是,不同的行为需要两者。我正在使用 AngularJS $resource
与 RESTful 服务器端数据源进行交互。
- 为什么我不能同时使用两者?为什么第二个中间件被忽略了?
- 这两个路由器应该以什么顺序工作?
最好通过以下方式进行路由: router.route('your/route').get(aJsFile.function);
然后,不用exec,只写 属性:['id', 'username'] 其中:{用户名:用户名} 或者像这样的东西。
第二个中间件被忽略,因为 url 模式是相同的...你希望路由器如何区分 'username' 或 'id';
你必须首先检查它是否是一个 id。
router.get("/:username", function(req, res, next) {
const username = req.params.username;
if (!isNaN(parseInt(username)) { // <------ Check if it's an ID
next();
} else {
User.findOne({
username: req.params.username
}).exec(function(err, user) {
if (err) return next(error);
res.json(user);
});
}
});
/* GET /users/id */
router.get("/:id", function(req, res, next) {
User.findById(req.params.id, function(err, user) {
if (err) return next(err);
res.json(user);
});
});