Node.js中如何匹配含通配符与无通配符的URL?
问题描述
我正在用Node.js开发程序,遇到如下场景:
- 我有一个包含通配符(
*)的URL数组,例如https://*.example.com/example/login、http://www.example2.com/*/example2/callback; - 同时有一个传入的重定向URL(
incomingRedirectUrl),需要验证其是否匹配数组中的任意URL; - 希望实现类似
arr.includes(incomingRedirectUrl)的便捷匹配方式,目前无通配符的URL已通过array.includes()实现匹配,但带通配符的URL匹配逻辑尚未解决(比如https://x.example.com/example/login应匹配数组中第一个URL)。
请问是否有办法实现该需求?还是必须通过拆分URL(如在*处切割)来进行比对?
以下是我的代码片段:
for (let i = 0; i < arr.length; i++) { if (arr[i].indexOf('*') !== -1) { wildcardArr.push(arr[i]); } else { noWildcardArr.push(arr[i]); } } // 注:先检查无通配符数组是因为大部分待验证的重定向URL不含通配符 if (noWildcardArr.includes(incomingRedirectUrl)) { // 验证通过,执行后续逻辑(这部分已正常工作) } else if (wildcardArr.includes(incomingRedirectUrl)) { // 需要实现带通配符的匹配逻辑,不确定是否能直接用includes实现 } else { log.error('authorize: Bad Request - Invalid Redirect URL'); context.res = { status: 400, body: 'Bad Request - Invalid Redirect URL', }; }
解决方案
无需拆分URL,将带通配符的URL转换为正则表达式进行匹配是更高效的方案,具体实现如下:
核心思路
- 预处理通配符URL:将URL中的
*替换为正则的.*(匹配任意长度的任意字符),同时转义URL中的正则特殊字符(如.、/、:),避免正则语法冲突; - 正则匹配验证:用转换后的正则对象测试传入的重定向URL,只要有一个规则匹配即通过验证。
修改后的完整代码
// 拆分并预处理URL数组 const noWildcardArr = []; const wildcardRegexes = []; for (const url of arr) { if (url.includes('*')) { // 转义正则特殊字符,再将*替换为.* const escapedUrl = url.replace(/[.+^${}()|[\]\\]/g, '\\$&'); const regexPattern = new RegExp(`^${escapedUrl.replace(/\*/g, '.*')}$`); wildcardRegexes.push(regexPattern); } else { noWildcardArr.push(url); } } // 验证逻辑 if (noWildcardArr.includes(incomingRedirectUrl)) { // 匹配无通配符URL,执行后续逻辑 } else if (wildcardRegexes.some(regex => regex.test(incomingRedirectUrl))) { // 匹配带通配符规则,执行后续逻辑 } else { log.error('authorize: Bad Request - Invalid Redirect URL'); context.res = { status: 400, body: 'Bad Request - Invalid Redirect URL', }; }
关键细节说明
- 转义特殊字符:
url.replace(/[.+^${}()|[\]\\]/g, '\\$&')将URL中的.、+等正则敏感字符转义,确保URL原义被保留; - 完全匹配约束:正则前后添加
^和$,确保只有整个URL完全符合规则时才匹配,避免部分匹配的误判; - 高效匹配:
Array.some()方法会在找到第一个匹配项后立即停止遍历,性能优于全量遍历。
内容的提问来源于stack exchange,提问作者camach28
相关产品推荐
相关产品推荐

