Express.js中Route Params的正则表达式

时间:2016-07-02 01:24:45

标签: node.js express

根据各种文档和博客,以及this question和其他人,我知道可以使用正则表达式验证路由参数。然而,这让我搜索了大约一个半小时:

app.get('/api/:url(/^http:\/\/(.+?)\.(.+?)$/)', (req, res) => {
  // do stuff with req.params.url
});

每当我在本地运行服务器并输入localhost://8000/api/http://www.google.com时,响应为Cannot GET /new/http://www.google.com

我知道正则表达式做我想做的事,因为:

/^http:\/\/(.+?)\.(.+?)$/.test('http://www.google.com');

...返回true。

我也尝试将路线字符串更改为......

'/api/:url(^http:\/\/(.+?)\.(.+?)$)'

'/api/:url(http:\/\/(.+?)\.(.+?))'

'/api/:url/^http:\/\/(.+?)\.(.+?)$/'

其他几种格式看起来像Stack Overflow线程和博客中给出的示例(Express文档绝对没有在第一个路径参数之外使用的正则表达式的示例)。也许有一些我不知道的格式限制,或者Express中对RegExp支持的限制?如果文档说什么的话会很棒。

我感谢能得到的任何帮助。

3 个答案:

答案 0 :(得分:6)

你的正则表达式是错误的,因为你正在努力实现的目标。

TL; DR使用此:

app.get('/api/:url(https?:\/\/?[\da-z\.-]+\.[a-z\.]{2,6}\/?)', (req, res) => {
});

一些解释:

首先,path-to-regexp,express使用的模块正如其名称所示:将路径转换为正则表达式。因此,^$锚点是非法的,或者放在:url()内容中时可以有不同的解释(路径到regexp已使用它们 )。另外,不要在JavaScript中使用斜杠来标识RegExp对象,而只包括表达式内容。

以下是express查看正则表达式的方式:

path: '/api/:url(/^http://(.+?).(.+?)$/)'
regexp: /^\/api\/(?:(\/^http:\/\/(?:\.+?))\.(\.+?)$\/)\/?$/i

path: '/api/:url(^http://(.+?).(.+?)$)'
regexp: /^\/api\/(?:(^http:\/\/(?:\.+?))\.(\.+?)$)\/?$/i

path: '/api/:url(http://(.+?).(.+?))'
regexp: /^\/api\/(?:(http:\/\/(?:\.+?))\.(\.+?))\/?$/i

path: '/api/:url/^http://(.+?).(.+?)$/
regexp: /^\/api\/(?:([^\/]+?))\/^http:\/\/(?:\.+?)\.(\.+?)$\/?$/i

并且,使用这样的代码片段,您可以看到没有匹配:

const url = 'http://www.google.com';
for (let layer of app._router.stack) {
  if (layer.name === 'bound dispatch') {
    console.log(layer.regexp + ': matches', url, '=', layer.regexp.test(url));
  }
}

建议避免在已命名的捕获中使用捕获括号。

示例(注意URI方案的额外括号,以及它们如何更改req.params.url值)

app.get('/api/:url((https?:\/\/)?[\da-z\.-]+\.[a-z\.]{2,6}\/?)', (req, res) => {})

> req.params: { '0': 'http://', url: 'http://' }

稍后编辑:请注意,此整篇文章仅涉及包含正则表达式的字符串路由,而不是使用RegExp对象定义的路由。

答案 1 :(得分:0)

尝试双反斜杠

app.get('/api/:url(/^http:\\/\\/(.+?)\\.(.+?)$/)', ...

答案 2 :(得分:0)

我认为您不能使用命名参数,但您可以直接传递正则表达式:

app.get(/^\/api\/http:\/\/(.+?)\.(.+?)$/, ...);

这将产生(作为req.params):

{ '0': 'www', '1': 'google.com' }