Express-js通配符路由,涵盖路径下的所有内容

时间:2011-05-28 12:13:24

标签: node.js express

我正试图让一条路线覆盖/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*,这当然不是最优的,因为它太匹配了。

5 个答案:

答案 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!'))