从URL中获取子域名一开始听起来很容易。
http://www.domain.example
查找第一个句点,然后返回“http://”之后的任何内容...
然后你记住了
http://super.duper.domain.example
哦,那么你认为,好的,找到最后一个句号,往回走一个单词并获取前面的所有内容!
然后你记得了
http://super.duper.domain.co.uk
你回到了起点。除了存储所有顶级域名的列表之外,还有没有其他好的想法?
从URL中获取子域名一开始听起来很容易。
http://www.domain.example
查找第一个句点,然后返回“http://”之后的任何内容...
然后你记住了
http://super.duper.domain.example
哦,那么你认为,好的,找到最后一个句号,往回走一个单词并获取前面的所有内容!
然后你记得了
http://super.duper.domain.co.uk
你回到了起点。除了存储所有顶级域名的列表之外,还有没有其他好的想法?
这段代码返回正确的域名。
InternetDomainName foo = InternetDomainName.from("foo.item.shopatdoor.co.uk").topPrivateDomain(); System.out.println(foo.topPrivateDomain());
它并不能完全解决问题,但你可以尝试逐个获取域名的部分并检查响应,例如获取 'http://uk',然后是 'http://co.uk',最后是 'http://domain.co.uk'。当你获得非错误响应时,你就得到了域名,其余部分则是子域名。
有时候你只需要试一试 :)
编辑:
Tom Leys在评论中指出,有些域名仅在www子域名上设置,这将导致我们在上述测试中得到不正确的答案。好点子!也许最好的方法是使用 'http://www' 和 'http://' 检查每个部分,并将任何一个命中视为该域名部分的命中?我们仍然会错过一些“替代”安排,例如 'web.domain.com',但我已经很久没有遇到这种情况了 :)
.DK
和其他一些情况,因为http://dk/
可以直接使用。这种启发式方法并不可取... - Patrick Mevzekecho tld('http://www.example.co.uk/test?123'); // co.uk
/**
* http://publicsuffix.org/
* http://www.alandix.com/blog/code/public-suffix/
* http://tobyinkster.co.uk/blog/2007/07/19/php-domain-class/
*/
function tld($url_or_domain = null)
{
$domain = $url_or_domain ?: $_SERVER['HTTP_HOST'];
preg_match('/^[a-z]+:\/\//i', $domain) and
$domain = parse_url($domain, PHP_URL_HOST);
$domain = mb_strtolower($domain, 'UTF-8');
if (strpos($domain, '.') === false) return null;
$url = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1';
if (($rules = file($url)) !== false)
{
$rules = array_filter(array_map('trim', $rules));
array_walk($rules, function($v, $k) use(&$rules) {
if (strpos($v, '//') !== false) unset($rules[$k]);
});
$segments = '';
foreach (array_reverse(explode('.', $domain)) as $s)
{
$wildcard = rtrim('*.'.$segments, '.');
$segments = rtrim($s.'.'.$segments, '.');
if (in_array('!'.$segments, $rules))
{
$tld = substr($wildcard, 2);
break;
}
elseif (in_array($wildcard, $rules) or
in_array($segments, $rules))
{
$tld = $segments;
}
}
if (isset($tld)) return $tld;
}
return false;
}
private String getSubDomain(Uri url) throws Exception{
String subDomain =url.getHost();
String fial=subDomain.replace(".","/");
String[] arr_subDomain =fial.split("/");
return arr_subDomain[0];
}
第一个索引总是子域名
sudo apt install psl
获取域名后缀(最长的后缀):
domain=example.com.tr
output=$(psl --print-unreg-domain $domain)
output
是:
example.com.tr: com.tr
domain
中提取后缀(com.tr),并测试它是否仍然有超过一个点。# split output by colon
arr=(${output//:/ })
# remove the suffix from the domain
name=${1/${arr[1]}/}
# test
if [[ $name =~ \..*\. ]]; then
echo "Yes, it is subdomain."
fi
将所有内容放在一个Bash函数中:
is_subdomain() {
local output=$(psl --print-unreg-domain $1)
local arr=(${output//:/ })
local name=${1/${arr[1]}/}
[[ $name =~ \..*\. ]]
}
使用方法:
d=example.com.tr
if is_subdomain $d; then
echo "Yes, it is."
fi
您可以使用此库tld.js: JavaScript API来处理复杂的域名、子域名和URI。
tldjs.getDomain('mail.google.co.uk');
// -> 'google.co.uk'
如果您想在浏览器中获取根域名,可以使用这个库 AngusFu/browser-root-domain。
var KEY = '__rT_dM__' + (+new Date());
var R = new RegExp('(^|;)\\s*' + KEY + '=1');
var Y1970 = (new Date(0)).toUTCString();
module.exports = function getRootDomain() {
var domain = document.domain || location.hostname;
var list = domain.split('.');
var len = list.length;
var temp = '';
var temp2 = '';
while (len--) {
temp = list.slice(len).join('.');
temp2 = KEY + '=1;domain=.' + temp;
// try to set cookie
document.cookie = temp2;
if (R.test(document.cookie)) {
// clear
document.cookie = temp2 + ';expires=' + Y1970;
return temp;
}
}
};
使用Cookie有些棘手。
常见后缀列表(.co.uk,.com等)需要去除以及http://,这样你就只剩下“sub.domain”可以使用了,而不是“http://sub.domain.suffix”,至少我会这么做。
最大的问题在于可能的后缀列表。毕竟有很多种类。
快速查看publicsuffix.org清单后,我发现您可以通过移除域名的最后三个片段(“片段”在此处指两个点之间的一部分)来合理地近似,如果最后一个片段为两个字符长,则假设它是国家代码并将被进一步细分。如果最后一个片段是“us”,而倒数第二个片段也是两个字符,则移除最后四个片段。在所有其他情况下,删除最后两个片段。例如:
""example"不是两个字符,因此删除"domain.example",只留下"www"
" ""example"不是两个字符,因此删除"domain.example",只留下"super.duper"
" ""uk"是两个字符(但不是"us"),因此删除"domain.co.uk",只留下"super.duper"
" ""us"是两个字符,表示"我们",再加上"wy"也是两个字符,所以删除"pvt.k12.wy.us",只留下"foo"。
请注意,虽然这对我迄今为止在回复中看到的所有示例都有效,但它仅仅是一个合理的近似值。它并不完全正确,尽管我认为这是你在没有制作/获取实际列表用于参考的情况下可能得到的最接近的结果。
".NAME
开始时就是这种情况,那时你只能购买firstname.lastname.name
域名。而在相反的方向上,现在.US
也是平的,因此您可以通过仅购买注册表中的whatever.us
来拥有x.y.z.whatever.us
,然后您的算法将在其上失败。 - Patrick Mevzek