我在Express路由器中有以下两条路由:
router.get("/v|verses", (req, res) => ...
router.get("/v|verses/:book", (req, res) => ....
为什么调用/verses/john
会路由到第一个带有req.params
空对象的对象?
如果我不使用正则表达式,但是为/v
和/verses
设置了单独的路由,则效果很好。
答案 0 :(得分:1)
您需要更改为以下/v(?:|erses)?/:book
。
从Express文档中:
Express使用path-to-regexp来匹配路由路径;有关定义路由路径的所有可能性,请参见正则表达式路径文档。 Express Route Tester是测试基本Express路线的便捷工具,尽管它不支持模式匹配。
通过Express Route Tester工具评估/v|verses/:book
时,生成的正则表达式为/^\/v\|verses\/((?:[^\/]+?))(?:\/(?=$))?$/i
,由于使用更改的方式而失败-正则表达式表示 修补以^\/v\
(简单的/v
)开头的内容 OR 以verses\/((?:[^\/]+?))(?:\/(?=$))
(基本上为verses/<anything>
)结尾。
更改按顺序进行,并且与找到的第一个匹配,因此对于So来说,输入“ / v erses / john”仅匹配第一个更改,而不匹配第二个。您也可以see this on Regex101。
需要记住的一件事是Express使用正则表达式路径的 old 版本-Express依赖项为0.1.7
,而当前软件包的版本为6.1.0
。我不确定Express为什么不使用较新的版本-较旧的版本似乎不完全支持某些分组,因此会为它们生成无效的正则表达式。
一种选择是直接传递正则表达式,因此您可以可以使用app.get(/^\/(?:v\|verses)\/((?:[^\/]+?))(?:\/(?=$))?$/, (req, res) => {})
-与应该生成但手工完成的类似。但是,它不可读,您不会得到req.params.book
的映射,只是得到了。
另一个选择是提供路径数组:app.get(['/verses/:book', '/v/:book'], (req, res) => {})
。这是映射多个路径的有效方法。如果您愿意,可以这样做。
最后,要修复语法,您需要/v(?:|erses)?/:book
-一个v
,然后可选地erses
,或者在非捕获组中不包含任何内容。如果您使用普通捕获组,那么/verses/john
会产生类型为req.params
的{{1}}。这样一来,您可以在{0: erses, book: john}
处获得正确的模式。 See on Regex101。