NodeJS / Express如何创建2条路径,类似路径但不同类型的参数?

时间:2013-12-23 22:19:07

标签: regex node.js express

我尝试创建两条不同的路线:

  1. / path / 1234(4位数或更少)
  2. / path / 123456789(超过4个)
  3. 我正在尝试:

    app.param(function (name) {
      return function(req,res,next,id) {
        //do some stuff here with id
        next();
      };
    });
    app.param('shortId', /[0-9]{0,4}/);
    app.param('longId', /[0-9]{5,20}/);
    
    app.get('/path/:shortId', function(req, res){
      res.send('ShortID:' + req.params.shortId);
    });
    
    app.get('/path/:longId', function(req, res){
      res.send('LongId:' + req.params.longId);
    });
    

    即使数字长度超过4位,我也总是从第一条路径(shortId)获得命中。有人知道我在这里做错了吗?

3 个答案:

答案 0 :(得分:3)

你真的不需要express-params,你可以直接将带括号的正则表达式附加到参数中;

app.get('/path/:shortId([0-9]{0,4})', function(req, res){
  res.send('ShortID:' + req.params.shortId);
});

app.get('/path/:longId([0-9]{5,20})', function(req, res){
  res.send('LongId:' + req.params.longId);
});

编辑:

要使express-params工作,有两件事会导致你现有的例子出现问题。

  • 正如其他人所指出的那样,您需要使用/^...$/来锚定正则表达式,否则第一个表达式将部分匹配参数并始终被采用。

  • 你的第一个app.param调用(传递函数的地方)总是返回一个函数,这意味着覆盖其他app.param调用以使用该函数进行匹配而不是正则表达式。由于该函数始终调用无参数next(),因此它始终接受所有模式。

改变这会导致像;

app.param(function (name, param) {
  if(name != 'veryshortid')           // Use this function for veryshortid only
    return;
  return function(req,res,next,id) {
    if(id.length > param) next('route');       // No match, skip
    else next();                               // Accept
  };
});

app.param('veryshortid', 1);
app.param('shortid', /^[0-9]{2,4}$/);
app.param('longid', /^[0-9]{5,20}$/);

app.get('/path/:veryshortid', function(req, res, next){
  res.send('VeryShortID:' + req.params.veryshortid);
});

app.get('/path/:shortid', function(req, res, next){
  res.send('ShortID:' + req.params.shortid);
});

app.get('/path/:longid', function(req, res, next){
  res.send('LongId:' + req.params.longid);
});

答案 1 :(得分:1)

这是因为在Express逻辑中,第一个正则表达式与longId匹配,但部分匹配。限制更多,一切都会顺利:

  app.param('shortId', /^[0-9]{0,4}$/);
  app.param('longId', /^[0-9]{5,20}$/);

编辑:

此外,您可以更改加载路线的顺序,但它既麻烦又便宜。永远是限制性的,标记正则表达式的开头和结尾。

答案 2 :(得分:1)

似乎Express部分匹配第一个表达式。它不直观,但仍可通过“手动”检查获得所需结果:

app.param(function (name,fn) {
  if (fn instanceof RegExp) {

    //fn is the regexp that I can use here
    return function(req,res,next,id) {

      if ( String(id).match(fn) ) {
        //do some stuff here with id
        next();
      }
      else {
        next('route');
      }
    };
  }
});

正如bduran所说,正确的正则表达式是:

app.param('shortId', /^[0-9]{0,4}$/);
app.param('longId', /^[0-9]{5,20}$/);