Ore*_*lev 5 javascript regex url
我想验证给定的字符串是否为URL.在文本中匹配URL也不错,但不是必需的.我进行了搜索和实验,但到目前为止我没有找到满足这些要求的东西:
不得接受字符串,这些字符串在被视为链接时会带来安全风险.例如,<a href="javascript:alert(document.cookie)">clickme</a>是一个有效的HTML元素,并且至少在某些浏览器中确实可以工作(引发警报等).我担心如果我允许任意方案(见下文),它可能会危及安全性(例如,如下所述:检查字符串是否为有效URL的最佳正则表达式是什么?).
必须在JavaScript中正常工作.
如果它在Java中的工作方式相同会很好 - 我正在开发GWT,所以这很好但不是绝对必要的.
必须接受在实践中使用的URL,而不仅仅是符合标准的URL.具体例子:
一个.我想接受http://fr.wikipedia.org/wiki/Français,这是不规范的,因为非英文字符的,但我的浏览器参考IE(7+)和Chrome接受.
湾 我想接受http://fr.wikipedia.org/wiki/Fran%c3%a7ais,这是不规范的,因为百分号十六进制编码应该是大写,而再由IE和Chrome接受.我想我可以做一个不区分大小写的比赛 - 你能想到的任何缺点吗?
C.我想接受http:// localhost/localpath/servlet #action?param = value,这是非标准的,因为片段部分(从'#'到结尾)不应该包含'?' 和其他字符,但有些应用程序生成这样的URL和浏览器接受它们.
d.我想接受任何方案/协议(不仅仅是http,https和ftp)的URL,因为我集成的各种应用程序及其用户可能需要传递此类URL.我可以禁止'javascript:'并允许其他所有内容; 如果你认为这会危及安全,请说出来.
在SO和其他地方有关于这个主题的大量问题,但我没有找到满足我所有要求的正则表达式.例子:
GWT中的正则表达式匹配URL - 非常好的和简单的正则表达式,但不接受非标准URL.我可以处理方案部分和百分比编码区分大小写,但不处理其他问题.
/sf/answers/13328381/ - 巨型正则表达式(我问自己,我使用的所有浏览器和框架是否可以处理这个大小)这看起来非常全面,但是它说它符合标准,我可以'做它的头或尾.
谢谢!:-)
必须接受在实践中使用的URL,而不仅仅是符合标准的URL
实际上,URI规范非常宽松,并且允许通常由于兼容性原因而要排除的构造...
我想接受http://fr.wikipedia.org/wiki/Français,这是非标准的
它不是URI,但它是一个非常标准的IRI.
- 非标准因为百分比编码十六进制应该是大写的
- 非标准,因为片段部分(从'#'到结尾)不应包含'?'
根据URI标准,这两者都是完全可以接受的.RFC 3986建议但不要求在创建百分比编码时使用大写.
我可以禁止'javascript:'并允许其他所有内容; 如果你认为这会危及安全,请说出来.
它会.遗憾的是,URI方案名称空间中存在多个潜在危险的附加内容,无疑将来会继续存在.此外,有可能使用编码字符和控制字符来规避黑名单功能.
此外,任意方案匹配意味着,在使用冒号的大多数情况下,检测文本中地址的次要目标将产生误报.
白名单是唯一合理的前进方式,因此您只需根据具体情况手动允许每个新方案.这需要一些照顾; 例如,该data:方案似乎无害且有用,但可能会遇到与XSS相同的问题javascript:.
您还需要了解有关每个方案的一些信息.方案喜欢http并ftp具有"基于服务器的命名权限":它们可以在该主机中包含单独的主机名和资源路径; 另外,您可能要求它们是绝对URI.如果要允许文件URI,则必须检查它是无主机(file:///).对于其他方案,URI标准本身可能不需要具体语法,但可能存在其他限制,例如mailto:必须采用有效的电子邮件地址.
巨型正则表达式(我问自己,我使用的所有浏览器和框架是否可以处理这个大小),这看起来非常全面
这在JavaScript中不起作用,因为它具有不受支持的\x{code point}语法.像JavaScript这样的语言,其正则表达式引擎使用UTF-16代码单元而不是完整的Unicode代码点,将无法处理BMP之外的字符范围.
你必须\x{A0}...\x{1FFFD}用更简单的东西替换长组\u00A0-\uFFFD,然后分别检查无效的代理对,以及0xnnFFFE-F非字符,如果你关心那些(可能不是).
可以说,在您获得IRI验证之前,您可能已经在一般输入扫描级别上删除了任何不良代理和非字符; 没有理由在任何文字输入中允许它们.在单独的步骤中执行该操作比尝试将所有内容整理成单个正则表达式更有意义.
取而代之的是,引用的正则表达式中最长的部分是试图验证数字IP地址的疯狂长数字检查串.这是正则表达式根本不擅长的事情.我强烈考虑不要担心IPv6和IPv6未来的数字地址:即使很快就会采用IPv6,但在可预见的未来,没有人会使用它们.(你甚至想要允许链接到数字地址吗?取决于你的应用程序在做什么,但往往不是.)
您可能还会考虑禁止使用userinfo @ hostname前缀(因为除了欺骗攻击它们一直没有用),以及百分比编码的主机名(因为它们没有任何用途,因为存在Punycode,并且在某些浏览器中不起作用) .
因此,IRI验证没有一个单一的答案,但这里有你可能会开始的地方:
(
https?://
(
([0-9]{1-3}(\.[0-9]{1-3}){3})|
([-0-9a-z\u00A0-\uFFFD]{1-63}(\.[-0-9a-z\u00A0-\uFFFD]{1-63})*)
)
(:[0-9]+)?/
(
%[0-9a-f][0-9a-f]|
[-._!$&'()*+,:;=@~0-9a-z\u00A0-\uFFFD/?#]
)*
)|(
ftp:// // same again but with no ?query
... // or port number
)|(
mailto: // specify requirements for
... // other accepted schemes
)
Run Code Online (Sandbox Code Playgroud)
(假设不区分大小写.这会应用不属于URI规范本身的DNS约束,但不完整,因为它不检查-DNS标签中的前导/尾随,或IPv4八位字节中的数字范围.验证电子邮件地址是否保留作为读者的练习,因为它本身是一项艰巨的任务,如果你想要严格执行它,就不适合正则表达式.)
| 归档时间: |
|
| 查看次数: |
2363 次 |
| 最近记录: |