2012-04-04 145 views
58

我有一个看起来像这样的路线:Express.js路由:可选的spat参数?

app.all('/path/:namedParam/*splat?',function(req,res,next){ 
    if(!req.params.length){ 
    // do something when there is no splat 
    } else { 
    // do something with splat 
    } 
}); 

但是,这并不工作 - 如果我叫path/foo/bar它击中了路线,但如果我叫path/foo,事实并非如此。

是否有可能有一个可选的图示参数,或者我必须使用正则表达式来检测?

编辑

更清晰,这里有我想要达到的要求:

  • 第一和第二PARAMS是需要
  • 的第一个参数是静态的,第二个是一个命名参数。
  • 任意数量的可选附加的参数可以被追加并仍然命中该路线。
+1

你想做什么?如果你不需要知道splat,只需执行''/ path /:firstParam/*''。如果你需要它,请执行'/ path /:firstParam /:secondParam?/ *''。 – 2012-04-05 02:53:21

+0

我正在寻找splat是可选的 - 你给的第一个例子不匹配'/ path/foo',(这是我的路线最初看起来像我想要一个可选的图示)。另外,在第二个例子中,添加splat实际上否定了可选的第二个参数 - '/ path/foo'将不会匹配你的第二个模式(对于这个问题,'/ path/foo/bar'也不会) - 其中之一表示'路由器'更烦人的部分。 – Jesse 2012-04-05 07:14:49

+1

我个人只想把'/ path /:firstParam'和'/ path /:firstParam /:secondParam /'作为具有共享控制器的两个独立路由器。没有必要让你的网址混淆 – 2012-04-05 16:31:29

回答

66

这适用于快递4上的/ path和/ path/foo,请注意?之前的*

router.get('/path/:id*?', function(req, res, next) { 
    res.render('page', { title: req.params.id }); 
}); 
+20

请注意,虽然这可行,但如果您访问'/ path/foo/bar/bazzle','req.params.id'将等于'foo',和'req.params [0]'等于'/ bar/bazzle',这可能会让某些人绊倒。一个更清洁的解决方案可能是将路径定义为'/ path/*?',在express 4中将'req.params [0]'设置为'foo/bar/bazzle',这可能更接近你寻找。 – Jesse 2015-06-02 06:18:43

12

这会做你以后的事情吗?

app.all('/path/:namedParam/:optionalParam?',function(req,res,next){ 
    if(!req.params.optionalParam){ 
    // do something when there is no optionalParam 
    } else { 
    // do something with optionalParam 
    } 
}); 

更多关于Express的路由这里,如果你没有看过:http://expressjs.com/guide/routing.html

+1

这个解决方案可以匹配'/ path/foo/bar',而不是'/ path/foo/bar/baz' - '*'splat匹配'。+ ,这是我在做什么必要的 - 我绝对是rtfm,似乎没有提及它,所以也许这是不可能的... – Jesse 2012-04-04 22:58:38

2

下面是我解决这个问题目前的方式,它不会出现Express支持任意数量的图示则params的一个可选的名为PARAM:

app.all(/\/path\/([^\/]+)\/?(.+)?/,function(req,res,next){ 
    // Note: this is all hacked together because express does not appear to support optional splats. 
    var params = req.params[1] ? [req.params[1]] : [], 
     name = req.params[0]; 
    if(!params.length){ 
    // do something when there is no splat 
    } else { 
    // do something with splat 
    } 
}); 

我很想有保证可读性和一致性名为PARAMS这种使用 - 如果另一个答案表面,使这个我会接受它。

62

我刚刚遇到了同样的问题并解决了它。这是我用:

app.get('path/:required/:optional?*', ...) 

这应该path/meow工作,path/meow/voofpath/meow/voof/moo/etc ...

似乎通过删除?*之间的/,最后/成为可选的同时也:optional?依然可选。

+0

酷!我只是测试了这个(在Express 3.0.0中,没有在2.x中测试过),它的工作原理。这绝对比我的RegEx黑客清洁。 – Jesse 2013-01-23 20:39:03

+5

您是否知道我可以在哪里阅读更多关于这些预定义关键字的内容? – 2014-04-14 15:42:27

+7

在Express 4.0x中,这似乎不再起作用 – regretoverflow 2015-01-03 04:38:11

0

使用可选的上述解决方案在Express 4中不起作用。我尝试了几种使用搜索模式的方法,但都无法正常工作。然后我发现这个方法似乎解雇无限嵌套的路径,http://expressjs.com/api.html#router

// this will only be invoked if the path starts with /bar from the mount point 
router.use('/bar', function(req, res, next) { 
    // ... maybe some additional /bar logging ... 

    // to get the url after bar, you can try 
    var filepath = req.originalUrl.replace(req.baseUrl, ""); 

    next(); 
}); 

它匹配所有/条,/酒吧/ Z,/酒吧/ A/B/C等,而在这之后,你可以阅读req.originalUrl,因为params没有被填充,所以前。你可以尝试比较baseUrl和originalUrl来获取剩余的路径。