Express-js 通配符路由覆盖路径下的所有内容(包括路径)

发布于 2024-11-10 05:51:06 字数 643 浏览 0 评论 0原文

我试图让一条路线覆盖 /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* 这当然不是很理想,因为它会匹配太多。

I'm trying to have one route cover everything under /foo including /foo itself. I've tried using /foo* which work for everything except it doesn't match /foo. Observe:

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

善良天后 2024-11-17 05:51:06

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

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

如果您有 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);

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.

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.

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);
燕归巢 2024-11-17 05:51:06

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

Express 当前处理 app.get("/foo*")app.get(/\/foo(.*)/),删除需要两条单独的路线。这与之前的答案(指现已删除的连接路由器)形成对比,后者指出路径中的“* 被替换为 .+”。

更新: Express 现在使用“path-to-regexp”模块(自 Express 4.0.0 起),该模块维护 与当前引用的版本中的行为相同。我不清楚该模块的最新版本是否保留了该行为,但目前这个答案仍然有效。

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.

Express currently treats app.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 .+".

Update: Express now uses the "path-to-regexp" module (since Express 4.0.0) which maintains the same behavior in 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.

请恋爱 2024-11-17 05:51:06

没有必要有两条路线。

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

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

这是一个完整的示例,请随意将其复制并粘贴到 .js 文件中以与节点一起运行,并在浏览器(或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!'))

It is not necessary to have two routes.

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

For example, 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):

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!'))
树深时见影 2024-11-17 05:51:06

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

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

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

app.get(["/:foo", "/:foo/:bar"], /* function */);
你的背包 2024-11-17 05:51:06

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

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

更多信息:https://blog.praveen.science/wildcard-路由是一种反模式/

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

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

More info: https://blog.praveen.science/wildcard-routing-is-an-anti-pattern/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文