Экспресс-JS подстановочный маршрут, чтобы покрыть все под и включая путь


Я пытаюсь, чтобы один маршрут охватывал все под /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("Foon");
});

app.get("/foo/bar", function(req, res){
  res.end("Foo Barn");
});

app.listen(3000);

выходы:

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

Каковы мои варианты? Лучшее, что я придумал, это маршрут /fo* что, конечно, не очень оптимально, так как это будет соответствовать слишком много.

5 68

5 ответов:

Я думаю, что вы должны будете иметь 2 маршрута. Если вы посмотрите на строку 331 маршрутизатора connect, то * в пути заменяется .+ так будет соответствовать 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);

маршрутизатор подключения теперь удален (https://github.com/senchalabs/connect/issues/262), автор заявляет, что вы должны использовать фреймворк поверх connect (например, Express) для маршрутизации.

Экспресс в настоящее времяapp.get("/foo*") Как app.get(/\/foo(.*)/), устраняя необходимость в двух отдельных маршрутов. Это в отличие от предыдущего ответа (со ссылкой на Теперь удаленный маршрутизатор connect), который заявил, что"* в пути заменяется на .+".

обновление: Express теперь использует модуль" путь к регулярному выражению " (начиная с Express 4.0.0), который поддерживает такое же поведение в версию ссылка. Мне непонятно, сохраняет ли последняя версия этого модуля поведение, но на данный момент этот ответ стоит.

в массиве вы также можете использовать переменные, передаваемые в req.параметры:

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

для тех, кто изучает node / express (так же, как и я): не используйте подстановочный маршрут, если это возможно!

Я также хотел реализовать маршрутизацию для GET/users/: id / whatever с использованием подстановочной маршрутизации. Вот как я сюда попал.

к счастью, я также нашел эту статью:http://www.jongleberry.com/wildcard-routing-is-an-anti-pattern.html

Ура, Роберт

не обязательно иметь два маршрута.

просто добавить (/*)? в конце 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!'))