我正试图让一条路线覆盖/foo
下的所有内容,包括/foo
本身。我尝试使用适用于所有内容的/foo*
,但与/foo
不匹配。观察:
var express = require("express"),
app = express.createServer();
app.get("/foo*", function(req, res, next){
res.write("Foo*\n");
next();
});
app.get("/foo", function(req, res){
res.end("Foo\n");
});
app.get("/foo/bar", function(req, res){
res.end("Foo Bar\n");
});
app.listen(3000);
输出:
$ curl localhost:3000/foo
Foo
$ curl localhost:3000/foo/bar
Foo*
Foo Bar
我有什么选择?我提出的最好的方法是路由/fo*
,这当然不是最优的,因为它太匹配了。
答案 0 :(得分:97)
我认为你必须拥有2条路线。如果查看连接路由器的第331行,路径中的*将替换为。+ so将匹配1个或多个字符。
https://github.com/senchalabs/connect/blob/master/lib/middleware/router.js
如果您有两条执行相同操作的路线,则可以执行以下操作以保持DRY。
var express = require("express"),
app = express.createServer();
function fooRoute(req, res, next) {
res.end("Foo Route\n");
}
app.get("/foo*", fooRoute);
app.get("/foo", fooRoute);
app.listen(3000);
答案 1 :(得分:30)
现在已经删除了连接路由器(https://github.com/senchalabs/connect/issues/262),作者声明你应该在连接(如Express)之上使用框架进行路由。
快递currently treats app.get("/foo*")
为app.get(/\/foo(.*)/)
,无需两条独立的路线。这与之前的答案(指现已删除的连接路由器)形成对比,后者声明路径中的“*
已替换为.+
”。
更新: Express现在使用“path-to-regexp”模块(自Express 4.0.0起),该模块在当前引用的版本中维护the same behavior。我不清楚该模块的最新版本是否能保持这种行为,但现在这个答案仍然存在。
答案 2 :(得分:8)
在数组中,您还可以使用传递给req.params的变量:
app.get(["/:foo", "/:foo/:bar"], /* function */);
答案 3 :(得分:2)
对于那些正在学习node / express(就像我一样)的人:如果可能的话,不要使用通配符路由!
我还想使用通配符路由实现GET / users /:id /的路由。这就是我到达这里的方式。
幸运的是,我还发现了这篇文章:http://www.jongleberry.com/wildcard-routing-is-an-anti-pattern.html
干杯, 罗伯特
答案 4 :(得分:2)
不必有两条路线。
只需在
(/*)?
字符串的末尾添加path
。例如,
app.get('/hello/world(/*)?' /* ... */)
这是一个可以正常工作的示例,可以将其复制并粘贴到.js文件中以与node一起运行,然后在浏览器(或curl)中进行播放:
const app = require('express')()
// will be able to match all of the following
const test1 = 'http://localhost:3000/hello/world'
const test2 = 'http://localhost:3000/hello/world/'
const test3 = 'http://localhost:3000/hello/world/with/more/stuff'
// but fail at this one
const failTest = 'http://localhost:3000/foo/world'
app.get('/hello/world(/*)?', (req, res) => res.send(`
This will match at example endpoints: <br><br>
<pre><a href="${test1}">${test1}</a></pre>
<pre><a href="${test2}">${test2}</a></pre>
<pre><a href="${test3}">${test3}</a></pre>
<br><br> Will NOT match at: <pre><a href="${failTest}">${failTest}</a></pre>
`))
app.listen(3000, () => console.log('Check this out in a browser at http://localhost:3000/hello/world!'))