sailsjs router regex

相信很多人都有在 sailsjs 的 config/router.js 中看到下面這段,這問題就是當 controller 與 static directory 衝突時 router 該如何處理,官方其實在下面這段有寫出解決方案,但實際使用上沒辦法正常運作。

// What about the ever-popular "vanity URLs" aka URL slugs?
// (you remember doing this with `mod_rewrite` in PHP)
//
// This is where you want to set up root-relative dynamic routes like:
// http://yourwebsite.com/twinkletoezz993
//
// You still want to allow requests through to the static assets,
// So we need to set up this route to allow URLs through that have a trailing ".":
// (e.g. your javascript, CSS, and image files)
'get /*(^.*)': 'UserController.profile'

如果想要達到相同的效果可以使用另一個方式如下:
'get /[^.?]+?': 'UserController.profile'

但這時可能會遇上另一個問題,原本 sailsjs 的 router 設計為 :controller/:action,所以如果是想要把所有 '/XXXXXXXXX' 都對應到 UserController 的 action,就沒辦法在 controller 的 req 拿到 req.param('action') 取得要對應的 action,因此可以將上方這段修改為:
'get /:action([^.?]+?)': 'UserController.profile'

修改完後只要是連到 '/XXXXXXXXX' 都會被指向 UserController 的 profile action,而 UserController.profile 的 req.param('action') 就會是 XXXXXXXXX 的名稱,如果是連到 '/logo.png' 等連結會被指向 static directory,這邊也建議如果要使用這種方式請把 profile 改為 index,由 index 來做處理,畢竟 profile 這字這樣使用不太恰當。


如果是想要只開放幾個特殊狀況才進行上面這段可以修改為:
'get /:action(profile|page)': 'UserController.profile'

這樣修改後會發現只有 '/profile', '/page' 會指向 UserController 的 profile,而 req.param('action') 也會拿到 profile/ page,其他的如果沒有 static file 就會被導到 404。


-------- update 2013-11-11 -------
其實這段 regex 跟原本的寫出來會略有不同,真正原因是 sails 會對這段 regex 作些調整:
如果你寫 /:action(*) 會被 sails 轉譯為「^\/(?:( YOUR_REGEX ))\/?$」,而「*」會被改為「.*」也就是所有字元都可以,這部份目前看起來是直接將轉譯後的 regex 對應到 expressjs 的 router。
-------- update 2013-11-11 -------


相關連結
sailsjs document - router

沒有留言:

張貼留言