node.js Express-js 通配符路由以覆盖路径下和包括路径下的所有内容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6161567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 14:14:28  来源:igfitidea点击:

Express-js wildcard routing to cover everything under and including a path

node.jsexpress

提问by Kit Sunde

I'm trying to have one route cover everything under /fooincluding /fooitself. I've tried using /foo*which work for everything exceptit doesn't match /foo. Observe:

我试图让一条路线涵盖/foo包括/foo自身在内的所有内容。我试过使用/foo*which work 来处理所有事情,除了它不匹配/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);

Outputs:

输出:

$ curl localhost:3000/foo
Foo
$ curl localhost:3000/foo/bar
Foo*
Foo Bar

What are my options? The best I've come up with is to route /fo*which of course isn't very optimal as it would match way too much.

我有哪些选择?我想出的最好的方法是路由/fo*这当然不是非常理想,因为它会匹配太多。

回答by serby

I think you will have to have 2 routes. If you look at line 331 of the connect router the * in a path is replaced with .+ so will match 1 or more characters.

我认为你必须有2条路线。如果您查看连接路由器的第 331 行,路径中的 * 将替换为 .+,因此将匹配 1 个或多个字符。

https://github.com/senchalabs/connect/blob/master/lib/middleware/router.js

https://github.com/senchalabs/connect/blob/master/lib/middleware/router.js

If you have 2 routes that perform the same action you can do the following to keep it DRY.

如果您有 2 条执行相同操作的路由,您可以执行以下操作以使其保持干燥

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);

回答by Johann

The connect router has now been removed (https://github.com/senchalabs/connect/issues/262), the author stating that you should use a framework on top of connect (like Express) for routing.

现在连接路由器已被删除(https://github.com/senchalabs/connect/issues/262),作者指出您应该在连接(如 Express)之上使用框架进行路由。

Express currently treatsapp.get("/foo*")as app.get(/\/foo(.*)/), removing the need for two separate routes. This is in contrast to the previous answer (referring to the now removed connect router) which stated that "*in a path is replaced with .+".

Express目前将其app.get("/foo*")视为app.get(/\/foo(.*)/),从而无需两条单独的路线。这与之前的答案(指现在删除的连接路由器)形成对比,后者指出“*在路径中被替换为.+”。

Update:Express now uses the "path-to-regexp" module (since Express 4.0.0) which maintains the same behaviorin the version currently referenced. It's unclear to me whether the latest version of that module keeps the behavior, but for now this answer stands.

更新:Express 现在使用“path-to-regexp”模块(自 Express 4.0.0),它在当前引用的版本中保持相同的行为。我不清楚该模块的最新版本是否保留了该行为,但现在这个答案成立。

回答by Somo S.

It is not necessary to have two routes.

Simply add (/*)?at the end of your pathstring.

For example, app.get('/hello/world(/*)?' /* ... */)

没有必要有两条路线。

只需(/*)?path字符串的末尾添加。

例如, app.get('/hello/world(/*)?' /* ... */)

Here is a fully working example, feel free to copy and paste this into a .js file to run with node, and play with it in a browser (or curl):

这是一个完整的示例,您可以随意将其复制并粘贴到 .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!'))

回答by DrDimedrol

In array you also can use variables passing to req.params:

在数组中,您还可以使用传递给 req.params 的变量:

app.get(["/:foo", "/:foo/:bar"], /* function */);

回答by throbi

For those who are learning node/express (just like me): do not use wildcard routing if possible!

对于那些正在学习 node/express 的人(就像我一样):如果可能,不要使用通配符路由!

I also wanted to implement the routing for GET /users/:id/whatever using wildcard routing. This is how I got here.

我还想使用通配符路由实现 GET /users/:id/whatever 的路由。这就是我到这里的方式。

Fortunately I have also found this article: http://www.jongleberry.com/wildcard-routing-is-an-anti-pattern.html

幸运的是我也找到了这篇文章:http: //www.jongleberry.com/wildcard-routing-is-an-anti-pattern.html

Cheers, Robert

干杯,罗伯特