使用 JavaScript 获取不带子域的域名

Get domain name without subdomains using JavaScript?

本文关键字:域名 JavaScript 获取 使用      更新时间:2023-09-26

如何获取没有子域名的域名?

例如,如果URL是"http://one.two.roothost.co.uk/page.html",如何获得"roothost.co.uk"?

以下是提取没有任何子域的域名的解决方案。此解决方案不对 URL 格式做出任何假设,因此它应该适用于任何 URL。由于有些域名有一个后缀(.com(,有些域名有两个或更多(.co.uk(,为了在所有情况下获得准确的结果,我们需要使用公共后缀列表解析主机名,其中包含所有公共域名后缀的列表。


溶液

首先,在 HTML 的脚本标记中包含公共后缀列表 js api,然后在 JavaScript 中获取可以调用的主机名:

var parsed = psl.parse('one.two.roothost.co.uk');
console.log(parsed.domain);

。这将返回"roothost.co.uk"。若要从当前页获取名称,可以使用 location.hostname 而不是静态字符串:

var parsed = psl.parse(location.hostname);
console.log(parsed.domain);

最后,如果您需要直接从完整的 URL 字符串中解析域名,您可以使用以下内容:

var url = "http://one.two.roothost.co.uk/page.html";
url = url.split("/")[2]; // Get the hostname
var parsed = psl.parse(url); // Parse the domain
document.getElementById("output").textContent = parsed.domain;

JSFiddle 示例(它包括 jsFiddle 中的整个缩小库,所以向下滚动!(: https://jsfiddle.net/6aqdbL71/2/

您可以使用

parse-domain为您完成繁重的工作。此包考虑public suffix list并返回一个易于使用的对象分解域。

以下是他们自述文件中的示例:

  npm install parse-domain
  import { parseDomain, ParseResultType } from 'parse-domain';
  const parseResult = parseDomain(
    // should be a string with basic latin characters only. more details in the readme
    'www.some.example.co.uk',
  );
  // check if the domain is listed in the public suffix list
  if (parseResult.type === ParseResultType.Listed) {
    const { subDomains, domain, topLevelDomains } = parseResult;
    console.log(subDomains); // ["www", "some"]
    console.log(domain); // "example"
    console.log(topLevelDomains); // ["co", "uk"]
  } else {
    // more about other parseResult types in the readme
  }
这对

我有用:

const firstTLDs = "ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|be|bf|bg|bh|bi|bj|bm|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|cl|cm|cn|co|cr|cu|cv|cw|cx|cz|de|dj|dk|dm|do|dz|ec|ee|eg|es|et|eu|fi|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jo|jp|kg|ki|km|kn|kp|kr|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|na|nc|ne|nf|ng|nl|no|nr|nu|nz|om|pa|pe|pf|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|yt".split('|');
const secondTLDs = "com|edu|gov|net|mil|org|nom|sch|caa|res|off|gob|int|tur|ip6|uri|urn|asn|act|nsw|qld|tas|vic|pro|biz|adm|adv|agr|arq|art|ato|bio|bmd|cim|cng|cnt|ecn|eco|emp|eng|esp|etc|eti|far|fnd|fot|fst|g12|ggf|imb|ind|inf|jor|jus|leg|lel|mat|med|mus|not|ntr|odo|ppg|psc|psi|qsl|rec|slg|srv|teo|tmp|trd|vet|zlg|web|ltd|sld|pol|fin|k12|lib|pri|aip|fie|eun|sci|prd|cci|pvt|mod|idv|rel|sex|gen|nic|abr|bas|cal|cam|emr|fvg|laz|lig|lom|mar|mol|pmn|pug|sar|sic|taa|tos|umb|vao|vda|ven|mie|北海道|和歌山|神奈川|鹿児島|ass|rep|tra|per|ngo|soc|grp|plc|its|air|and|bus|can|ddr|jfk|mad|nrw|nyc|ski|spy|tcm|ulm|usa|war|fhs|vgs|dep|eid|fet|fla|flå|gol|hof|hol|sel|vik|cri|iwi|ing|abo|fam|gok|gon|gop|gos|aid|atm|gsm|sos|elk|waw|est|aca|bar|cpa|jur|law|sec|plo|www|bir|cbg|jar|khv|msk|nov|nsk|ptz|rnd|spb|stv|tom|tsk|udm|vrn|cmw|kms|nkz|snz|pub|fhv|red|ens|nat|rns|rnu|bbs|tel|bel|kep|nhs|dni|fed|isa|nsn|gub|e12|tec|орг|обр|упр|alt|nis|jpn|mex|ath|iki|nid|gda|inc".split('|');
const knownSubdomains = "www|studio|mail|remote|blog|webmail|server|ns1|ns2|smtp|secure|vpn|m|shop|ftp|mail2|test|portal|ns|ww1|host|support|dev|web|bbs|ww42|squatter|mx|email|1|mail1|2|forum|owa|www2|gw|admin|store|mx1|cdn|api|exchange|app|gov|2tty|vps|govyty|hgfgdf|news|1rer|lkjkui";
function removeSubdomain(s) {
    const knownSubdomainsRegExp = new RegExp(`^(${knownSubdomains})'.`, 'i');
    s = s.replace(knownSubdomainsRegExp, '');
    const parts = s.split('.');
    while (parts.length > 3) {
        parts.shift();
    }
    if (parts.length === 3 && ((parts[1].length > 2 && parts[2].length > 2) || (secondTLDs.indexOf(parts[1]) === -1) && firstTLDs.indexOf(parts[2]) === -1)) {
        parts.shift();
    }
    return parts.join('.');
};

var tests = {
  'www.sidanmor.com':             'sidanmor.com',
  'exemple.com':                  'exemple.com',
  'argos.co.uk':                  'argos.co.uk',
  'www.civilwar.museum':          'civilwar.museum',
  'www.sub.civilwar.museum':      'civilwar.museum',
  'www.xxx.sub.civilwar.museum':  'civilwar.museum',
  'www.exemple.com':              'exemple.com',
  'main.testsite.com':            'testsite.com',
  'www.ex-emple.com.ar':          'ex-emple.com.ar',
  'main.test-site.co.uk':         'test-site.co.uk',
  'en.tour.mysite.nl':            'tour.mysite.nl',
  'www.one.lv':                   'one.lv',
  'www.onfdsadfsafde.lv':         'onfdsadfsafde.lv',
  'aaa.onfdsadfsafde.aa':         'onfdsadfsafde.aa',
};
const firstTLDs = "ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|be|bf|bg|bh|bi|bj|bm|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|cl|cm|cn|co|cr|cu|cv|cw|cx|cz|de|dj|dk|dm|do|dz|ec|ee|eg|es|et|eu|fi|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jo|jp|kg|ki|km|kn|kp|kr|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|na|nc|ne|nf|ng|nl|no|nr|nu|nz|om|pa|pe|pf|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|yt".split('|');
const secondTLDs = "com|edu|gov|net|mil|org|nom|sch|caa|res|off|gob|int|tur|ip6|uri|urn|asn|act|nsw|qld|tas|vic|pro|biz|adm|adv|agr|arq|art|ato|bio|bmd|cim|cng|cnt|ecn|eco|emp|eng|esp|etc|eti|far|fnd|fot|fst|g12|ggf|imb|ind|inf|jor|jus|leg|lel|mat|med|mus|not|ntr|odo|ppg|psc|psi|qsl|rec|slg|srv|teo|tmp|trd|vet|zlg|web|ltd|sld|pol|fin|k12|lib|pri|aip|fie|eun|sci|prd|cci|pvt|mod|idv|rel|sex|gen|nic|abr|bas|cal|cam|emr|fvg|laz|lig|lom|mar|mol|pmn|pug|sar|sic|taa|tos|umb|vao|vda|ven|mie|北海道|和歌山|神奈川|鹿児島|ass|rep|tra|per|ngo|soc|grp|plc|its|air|and|bus|can|ddr|jfk|mad|nrw|nyc|ski|spy|tcm|ulm|usa|war|fhs|vgs|dep|eid|fet|fla|flå|gol|hof|hol|sel|vik|cri|iwi|ing|abo|fam|gok|gon|gop|gos|aid|atm|gsm|sos|elk|waw|est|aca|bar|cpa|jur|law|sec|plo|www|bir|cbg|jar|khv|msk|nov|nsk|ptz|rnd|spb|stv|tom|tsk|udm|vrn|cmw|kms|nkz|snz|pub|fhv|red|ens|nat|rns|rnu|bbs|tel|bel|kep|nhs|dni|fed|isa|nsn|gub|e12|tec|орг|обр|упр|alt|nis|jpn|mex|ath|iki|nid|gda|inc".split('|');
const knownSubdomains = "www|studio|mail|remote|blog|webmail|server|ns1|ns2|smtp|secure|vpn|m|shop|ftp|mail2|test|portal|ns|ww1|host|support|dev|web|bbs|ww42|squatter|mx|email|1|mail1|2|forum|owa|www2|gw|admin|store|mx1|cdn|api|exchange|app|gov|2tty|vps|govyty|hgfgdf|news|1rer|lkjkui";
function removeSubdomain(s) {
const knownSubdomainsRegExp = new RegExp(`^(${knownSubdomains})'.`, 'i');
s = s.replace(knownSubdomainsRegExp, '');
const parts = s.split('.');
while (parts.length > 3) {
    parts.shift();
}
if (parts.length === 3 && ((parts[1].length > 2 && parts[2].length > 2) || (secondTLDs.indexOf(parts[1]) === -1) && firstTLDs.indexOf(parts[2]) === -1)) {
    parts.shift();
}
return parts.join('.');
};
for (var test in tests) {
  if (tests.hasOwnProperty(test)) {
    var t = test;
    var e = tests[test];
    var r = removeSubdomain(test);
    var s = e === r;
    if (s) {
      console.log('OK: "' + t + '" should be "' + e + '" and it is really "' + r + '"');
    } else {
      console.log('Fail: "' + t + '" should be "' + e + '" but it is NOT "' + r + '"');
    }
  }
}

参考资料:

psl.min.js文件

马克西米利安·劳迈斯特 回答这个问题

互联网上最受欢迎的子域名

这个呢?

function getCanonicalHost(hostname) {
  const MAX_TLD_LENGTH = 3;
  
  function isNotTLD(_) { return _.length > MAX_TLD_LENGTH; };
  hostname = hostname.split('.');
  hostname = hostname.slice(Math.max(0, hostname.findLastIndex(isNotTLD)));
  hostname = hostname.join('.');
  return hostname;
}
console.log(getCanonicalHost('mail.google.com'));
console.log(getCanonicalHost('some.google.com.ar'));
console.log(getCanonicalHost('some.another.google.com.ar'));
console.log(getCanonicalHost('foo.bar.google.com'));
console.log(getCanonicalHost('foo.bar.google.com.ar'));
console.log(getCanonicalHost('bar.google.ar'));

自 https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_is_a_domain_name 以来的作品说:

TLD 可以包含特殊字符和拉丁字符。TLD 的最大长度为 63 个字符,尽管大多数都在 2-3 个字符左右。

https://data.iana.org/TLD/tlds-alpha-by-domain.txt 是 1481 个 TLD,其中 466 个的长度约为 2-3,最常用的 TLD 不超过 3 个。

如果您需要一个适用于所有 TLDS 的解决方案,这里有一个更复杂的方法:

function getCanonicalHost(hostname) {
  return getCanonicalHost.tlds.then(function(tlds) {   
    function isNotTLD(_) { return tlds.indexOf(_) === -1; };
    hostname = hostname.toLowerCase();
    hostname = hostname.split('.');
    hostname = hostname.slice(Math.max(0, hostname.findLastIndex(isNotTLD)));
    hostname = hostname.join('.');
    return hostname; 
  });
}
getCanonicalHost.tlds = new Promise(function(res, rej) {
  const TLD_LIST_URL= 'https://data.iana.org/TLD/tlds-alpha-by-domain.txt';
  const xhr = new XMLHttpRequest();
  xhr.addEventListener('error', rej);
  xhr.addEventListener('load', function() { 
    const MAX_TLD_LENGTH = 63;
    var tlds = xhr.responseText.split(''n');
    tlds = tlds.map(function(_) { return _.trim().toLowerCase(); });
    tlds = tlds.filter(Boolean);
    tlds = tlds.filter(function(_) { return _.length < MAX_TLD_LENGTH; });
    res(tlds);
  });
  xhr.open('GET', TLD_LIST_URL);
  xhr.send();
})
getCanonicalHost('mail.google.com').then(console.log);
getCanonicalHost('some.google.com.ar').then(console.log);
getCanonicalHost('some.another.google.com.ar').then(console.log);
getCanonicalHost('foo.bar.google.com').then(console.log);
getCanonicalHost('foo.bar.google.com.ar').then(console.log);
getCanonicalHost('bar.google.ar').then(console.log);

只需使用下面的代码片段。

/(?<='.).+/.exec(location.hostname)[0]

最简单的解决方案:

var domain='https://'+window.location.hostname.split('.')[window.location.hostname.split('.').length-2]+'.'+window.location.hostname.split('.')[window.location.hostname.split('.').length-1];
alert(domain);

我创建了这个使用 URL 解析的函数。它通过假设所有主机名都有 4 个或更少的部分来作弊。

const getDomainWithoutSubdomain = url => {
  const urlParts = new URL(url).hostname.split('.')
  return urlParts
    .slice(0)
    .slice(-(urlParts.length === 4 ? 3 : 2))
    .join('.')
}
[
  'https://www.google.com',
  'https://www.google.co.uk',
  'https://mail.google.com',
  'https://www.bbc.co.uk/news',
  'https://github.com',
].forEach(url => {
  console.log(getDomainWithoutSubdomain(url))
})

这是一个工作的 JSFiddle

我的解决方案假设您要查找的根主机名类型为"abc.xyz.pp"。

extractDomain()返回包含所有子域的主机名。 getRootHostName().拆分主机名,然后基于上述假设,它使用shift()删除每个子域名。最后,parts[]中剩余的内容,它通过.将它们连接起来以形成根主机名。

爪哇语

var urlInput = "http://one.two.roothost.co.uk/page.html";
function extractDomain(url) {
    var domain;
    //find & remove protocol (http, ftp, etc.) and get domain
    if (url.indexOf("://") > -1) {
        domain = url.split('/')[2];
    } else {
        domain = url.split('/')[0];
    }
    //find & remove port number
    domain = domain.split(':')[0];
    return domain;
}
function getRootHostName(url) {
    var parts = extractDomain(url).split('.');
    var partsLength = parts.length - 3;
    //parts.length-3 assuming root hostname is of type abc.xyz.pp
    for (i = 0; i < partsLength; i++) {
        parts.shift(); //remove sub-domains one by one
    }
    var rootDomain = parts.join('.');
    return rootDomain;
}
document.getElementById("result").innerHTML = getRootHostName(urlInput);

.HTML

<div id="result"></div>

编辑 1:更新了 JSFiddle 链接。它反映了不正确的代码。

怎么样...

    function getDomain(){
        if(document.domain.length){
            var parts = document.domain.replace(/^(www'.)/,"").split('.');
            //is there a subdomain? 
            while(parts.length > 2){
                //removing it from our array 
                var subdomain = parts.shift();
            }
            //getting the remaining 2 elements
            var domain = parts.join('.');
            return domain.replace(/(^'.*)|('.*$)/g, "");
        }
        return '';
    }

我的解决方案对我有用:从"shop.gocustom.com"中获取"gocustom.com">

var site_domain_name = 'shop.gocustom.com';
alert(site_domain_name);
var strsArray = site_domain_name.split('.');
var strsArrayLen = strsArray.length;
alert(strsArray[eval(strsArrayLen - 2)]+'.'+strsArray[eval(strsArrayLen - 1)])

您可以在JavaScript中尝试此操作:

alert(window.location.hostname);

它将返回主机名。