Маршрут регулярного выражения не проходит req.params - PullRequest
0 голосов
/ 30 марта 2020

У меня есть следующие два маршрута в Express маршрутизаторе:

router.get("/v|verses", (req, res) => ...

router.get("/v|verses/:book", (req, res) => ....

Почему вызов /verses/john направляет к первому с req.params пустой объект?

Работает нормально, если я не использую регулярное выражение, но у меня есть отдельные маршруты для /v и /verses.

1 Ответ

1 голос
/ 30 марта 2020

Вам необходимо перейти на следующее /v(?:|erses)?/:book.

Из документации Express:

Express использует path-to-regexp для сопоставления маршрутов; см. документацию path-to-regexp обо всех возможностях определения путей маршрутов. Express Route Tester - удобный инструмент для тестирования основных маршрутов c Express, хотя он не поддерживает сопоставление с образцом.

Когда /v|verses/:book оценивается с помощью инструмент Express Route Tester, в результате чего регулярное выражение равно /^\/v\|verses\/((?:[^\/]+?))(?:\/(?=$))?$/i, которое не удастся из-за способа использования изменения - регулярное выражение говорит, что либо исправит что-то, что начинается с ^\/v\ (обычный /v) ИЛИ оканчивается на verses\/((?:[^\/]+?))(?:\/(?=$)) (в основном verses/<anything>).

Изменение идет по порядку и соответствует первому, что он находит, поэтому для So с вводом " / v erses / john" in соответствует только первое изменение, а не второе. Вы также можете увидеть это на Regex101 .

Одна вещь, которую вы должны иметь в виду, это то, что Express использует старую версию пути к библиотека regexp - зависимость Express равна 0.1.7, тогда как текущая версия пакета 6.1.0. Я не уверен, почему Express не использует более новую версию - более старая версия, по-видимому, не полностью поддерживает некоторые группировки, поэтому она создает недопустимое регулярное выражение для них.

Один из вариантов - передать прямое регулярное выражение, так что вы могли бы go для app.get(/^\/(?:v\|verses)\/((?:[^\/]+?))(?:\/(?=$))?$/, (req, res) => {}) - аналогично тому, что СЛЕДУЕТ генерировать, но делать вручную. Однако он не читается, и вы не получаете отображение req.params.book, вы просто получаете.

Другой вариант - указать массив путей: app.get(['/verses/:book', '/v/:book'], (req, res) => {}). Это правильный способ сопоставить несколько путей. Если вы будете sh, вы можете go с этим.

Наконец, однако, чтобы исправить синтаксис, вам нужно /v(?:|erses)?/:book - v, за которым может следовать erses или ничего в группа захвата. Если вы используете обычную группу захвата, то /verses/john создает req.params типа: {0: erses, book: john}. Таким образом, здесь вы получите правильный шаблон /^\/((?:v|verses))\/((?:[^\/]+?))(?:\/(?=$))?$/i. См. На Regex101 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...