PAC 文件的 js 脚本中, dnsDomainIs()中的匹配到底是什么语法?

2017-11-27 14:25:49 +08:00
 pq

如果写成 dnsDomainIs(host, "v2ex.com")的话,那么,当 host=="www.v2ex.com"或 host=="v2ex.com"时,是否都为 true ?我在 Chrome 上测试时,确实是如此,但是,网上大量的文档,包括一些很权威性的网站,Mozilla、Oracle、websense 之类的,都没有详细说明这一点,从列出的例子来看,应该是不包含 www 时才为真,有些例子则是当匹配串为".v2ex.com"时,www 为真,不带 www 则为假,真的有点混乱了。。。

本站上有些人认为的这么牛 B 的 js,语法难道这么不严谨?还是我没找到真正的网站?

4014 次点击
所在节点    JavaScript
11 条回复
pq
2017-11-27 14:33:20 +08:00
我目前的 pac 中写法是这样的:
shExpMatch(host, "(*.ggpht.com|ggpht.com)")

这是照网上的例子写的,可以正常工作,但我觉得不够优雅,一个域名重复写了两遍,浪费存贮器,作为强迫症,于是我才上网找语法,结果发现另一个函数 dnsDomainIs 或许可以直接搞定,我的想法是,匹配串只写一个 domain_name,不管 host 有或没有二级域名甚至更多级域名,都返回真。
yangg
2017-11-27 14:35:36 +08:00
源码
"function dnsDomainIs(host, domain) {\n"
" return (host.length >= domain.length &&\n"
" host.substring(host.length - domain.length) == domain);\n"
"}\n"

see https://github.com/ldx/libpac/blob/master/nsProxyAutoConfig.h
pq
2017-11-27 14:44:23 +08:00
@yangg 这么说来,匹配串直接写成"v2ex.com"的话,完全可以匹配 www.v2ex.comv2ex.com 了?那各网站的那些例子为嘛要脱裤子放屁,还在后面加一个 || host == 'v2ex.com'呢? websense 上有关 pac 的例子就那样写的。
pq
2017-11-27 14:47:37 +08:00
@yangg 你引的这个代码库不像是官方代码,后面好多\n,在 windows 下写的,没搞好就提交上去了。。。
pq
2017-11-27 15:01:40 +08:00
@yangg 下面这个例子加上你贴的源码提醒了我,匹配串开头还是要加上'.':
dnsDomainIs("www.notmycompany.com", "mycompany.com") returns true dnsDomainIs("www.myCompany.com", "mycompany.com") returns false

否则会出问题。

不过,我加上.后在 Chrome 里试了一下,居然仍能匹配不带 www 的 host,按照你的源码,这种情况下 host.length 是小于 domain.length 的,host=="v2ex.com"; domain==".v2ex.com";
yangg
2017-11-27 15:51:59 +08:00
autoxbc
2017-11-28 03:57:53 +08:00
function dnsDomainIs(host, domain)
{
   return new RegExp('\\b'+domain+'$').test(host);
}

>>> dnsDomainIs('v2ex.com','v2ex.com')
true
>>> dnsDomainIs('www.v2ex.com','v2ex.com')
true
>>> dnsDomainIs('notv2ex.com','v2ex.com')
false
>>> dnsDomainIs('v2ex.com.cn','v2ex.com')
false
pq
2017-11-28 10:56:37 +08:00
@autoxbc 这个太完美了!那么,可以直接在 pac 文件中重新定义 dnsDomainIs 这个函数么?
autoxbc
2017-11-28 21:33:18 +08:00
@pq #8 我测试可以的
autoxbc
2017-11-29 03:12:15 +08:00
仔细看了一下,#7 的代码没有对 "." 转义,匹配边界有问题
>>> dnsDomainIs('v2exycom.cn','v2ex.com.cn')
true

应该改成这样
function dnsDomainIs(host,domain)
{
   return new RegExp( '\\b' + domain.replace(/\./g,'\\.') + '$' ).test(host);
}

考虑到正则的性能问题,又写了个非正则版,实测性能好 1~3 倍
function dnsDomainIs(host,domain)
{
   var idx = host.length - domain.length ;
   return (host == domain) || (idx > 0 && host.lastIndexOf('.' + domain) == idx - 1);
}
pq
2017-11-29 13:24:08 +08:00
@autoxbc 这个真的好,我也正是因为考虑到正则表达式的性能可能不太好,所以才从 shExpMatch 换成 dnsDomainIs 的,而原版的 dnsDomainIs,实现虽然简单高效,但没有考虑到不带二级域名的域名本体,你后边的这个实现,看来是比较完美的,可以考虑向 Chrome 提交修正代码。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/409913

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX