Маршрутизація підстановочних символів Express-js для покриття всього, що міститься, включаючи шлях


96

Я намагаюся, щоб один маршрут охоплював усе, /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*який, звичайно, не дуже оптимальний, оскільки він би занадто збігався.


Якщо ви перехоплюєте всі /foo*подібні маршрути, чи не хочете ви зробити його проміжним?
Райнос

3
Будьте уважні, що ви просите: /foo*матчі, /foo/barале також матчі, /foolishякі ви, мабуть, не мали наміру.
Вік

Відповіді:


111

Я думаю, вам доведеться мати 2 маршрути. Якщо ви подивитеся на рядок 331 маршрутизатора підключення, * у шляху буде замінено на. + Так буде відповідати 1 або більше символів.

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

Якщо у вас є два маршрути, які виконують одну й ту саму дію, ви можете виконати наступні дії, щоб зберегти СУХУ .

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

101
app.get(["/foo", "/foo*"], /* function */);може бути також пільговим!
Кріс Фостер

9
Передача в масив рядків також є переважним для мене. На жаль: передача масиву до app.VERB () застаріла і буде видалена в 4.0
CodeWarrior

10
Проходження в масив рядків було відновлено в Express 4.9.1.
Піт ТНТ

30

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

Наразі експрес трактуєapp.get("/foo*") як app.get(/\/foo(.*)/), усуваючи необхідність у двох окремих маршрутах. Це на відміну від попередньої відповіді (маючи на увазі вже видалений маршрутизатор connect), який заявив, що " *у шляху замінено на .+".

Оновлення: Express тепер використовує модуль "шлях до повторного виведення" (оскільки Express 4.0.0), який підтримує таку саму поведінку у поточній версії. Мені незрозуміло, чи підтримує поведінку остання версія цього модуля, але наразі ця відповідь стоїть.


Тож чи слід використовувати. + Або *?
Тайлер Ланган

2
Використовуйте, /\/foo(.+)/якщо ви хочете відповідати, /fooза яким слід один чи більше символів, /foo*або /\/foo(.*)/якщо ви хочете відповідати, /fooа потім - нуль чи більше символів.
Йоганн

12

Не обов’язково мати два маршрути.

Просто додайте (/*)?в кінці pathрядка.

Наприклад, app.get('/hello/world(/*)?' /* ... */)

Ось повністю працюючий приклад, сміливо скопіюйте та вставте це у .js-файл для запуску із вузлом та пограйте з ним у браузері (або згорнувшись):

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

9

У масиві ви також можете використовувати змінні, що переходять до req.params:

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

3

Для тих, хто вивчає вузол / експрес (як і я): не використовуйте макіяж маршрутизації, якщо це можливо!

Я також хотів реалізувати маршрутизацію для GET / користувачів /: id / що завгодно, використовуючи маршрутизацію підстановки. Ось як я сюди потрапив.

На щастя, я також знайшов цю статтю: http://www.jongleberry.com/wildcard-routing-is-an-anti-pattern.html

Ура, Роберте


2
Посилання наразі померло. Можливо, це було так само, як: jonathanong.github.io/wildcard-routing-is-an-anti-pattern.html
Рон Берк,

@RonBurk ваша URL-адреса, здається, також мертва. Як я можу отримати додатковий підстановочний код після названого параметра? "/ щось /: id (/ *)?" не працює ..
Soichi Hayashi

Ймовірно, він ще деякий час буде в кеші Google: webcache.googleusercontent.com/…
Рон Берк,

чи існує альтернатива маршрутизації підстановки, якщо я не маю уявлення, що з’явиться після початкової частини URL-адреси?
Майкл

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.