根据各种文档和博客,以及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支持的限制?如果文档说什么的话会很棒。
我感谢能得到的任何帮助。
答案 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' }