2012-04-04 48 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來獲取剩餘的路徑。