如何仅使用JavaScript获取域名?

13

我想要使用JavaScript仅获取域名。例如:

vn.search.yahoo.com -> yahoo
vn.search.yahoo.com.vn -> yahoo
sub1.sub2.sub3.abcdef.co.uk -> abcdef

谢谢!

编辑说明:"domain" = 不带扩展名的域名(例如:.com、.net、.co.uk...),不包括子域名(例如:www、email、cdn、support...)。


这个需要在所有域名上都能工作吗?如果不是,你正在处理哪些类型的域名?(subd.subd.domain.comdomain.comhttp://domain.com等) - Purag
你对“域名”有什么定义? - RobG
这个对你有用吗?http://jsfiddle.net/purmou/TzjJE/ - Purag
你的脚本是否在该域内执行?如果是,我可能有一种更简单的方法。 - Eduardo
OP应该回复对澄清请求的回应,... - That Realty Programmer Guy
12个回答

33

使用location.host并截取子域和顶级域名:

 var domain = (location.host.match(/([^.]+)\.\w{2,3}(?:\.\w{2})?$/) || [])[1]

更新: 正如@demix指出的那样,此方法无法处理2和3个字母的域名。它也无法处理像aerojobs等数十个其他域名。

唯一的解决方法是提前知道有效的顶级域名(TLDs),因此这里提供一个更为适当的函数:

// http://data.iana.org/TLD/tlds-alpha-by-domain.txt
var TLDs = ["ac", "ad", "ae", "aero", "af", "ag", "ai", "al", "am", "an", "ao", "aq", "ar", "arpa", "as", "asia", "at", "au", "aw", "ax", "az", "ba", "bb", "bd", "be", "bf", "bg", "bh", "bi", "biz", "bj", "bm", "bn", "bo", "br", "bs", "bt", "bv", "bw", "by", "bz", "ca", "cat", "cc", "cd", "cf", "cg", "ch", "ci", "ck", "cl", "cm", "cn", "co", "com", "coop", "cr", "cu", "cv", "cx", "cy", "cz", "de", "dj", "dk", "dm", "do", "dz", "ec", "edu", "ee", "eg", "er", "es", "et", "eu", "fi", "fj", "fk", "fm", "fo", "fr", "ga", "gb", "gd", "ge", "gf", "gg", "gh", "gi", "gl", "gm", "gn", "gov", "gp", "gq", "gr", "gs", "gt", "gu", "gw", "gy", "hk", "hm", "hn", "hr", "ht", "hu", "id", "ie", "il", "im", "in", "info", "int", "io", "iq", "ir", "is", "it", "je", "jm", "jo", "jobs", "jp", "ke", "kg", "kh", "ki", "km", "kn", "kp", "kr", "kw", "ky", "kz", "la", "lb", "lc", "li", "lk", "lr", "ls", "lt", "lu", "lv", "ly", "ma", "mc", "md", "me", "mg", "mh", "mil", "mk", "ml", "mm", "mn", "mo", "mobi", "mp", "mq", "mr", "ms", "mt", "mu", "museum", "mv", "mw", "mx", "my", "mz", "na", "name", "nc", "ne", "net", "nf", "ng", "ni", "nl", "no", "np", "nr", "nu", "nz", "om", "org", "pa", "pe", "pf", "pg", "ph", "pk", "pl", "pm", "pn", "pr", "pro", "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", "sy", "sz", "tc", "td", "tel", "tf", "tg", "th", "tj", "tk", "tl", "tm", "tn", "to", "tp", "tr", "travel", "tt", "tv", "tw", "tz", "ua", "ug", "uk", "us", "uy", "uz", "va", "vc", "ve", "vg", "vi", "vn", "vu", "wf", "ws", "xn--0zwm56d", "xn--11b5bs3a9aj6g", "xn--3e0b707e", "xn--45brj9c", "xn--80akhbyknj4f", "xn--90a3ac", "xn--9t4b11yi5a", "xn--clchc0ea0b2g2a9gcd", "xn--deba0ad", "xn--fiqs8s", "xn--fiqz9s", "xn--fpcrj9c3d", "xn--fzc2c9e2c", "xn--g6w251d", "xn--gecrj9c", "xn--h2brj9c", "xn--hgbk6aj7f53bba", "xn--hlcj6aya9esc7a", "xn--j6w193g", "xn--jxalpdlp", "xn--kgbechtv", "xn--kprw13d", "xn--kpry57d", "xn--lgbbat1ad8j", "xn--mgbaam7a8h", "xn--mgbayh7gpa", "xn--mgbbh1a71e", "xn--mgbc0a9azcg", "xn--mgberp4a5d4ar", "xn--o3cw4h", "xn--ogbpf8fl", "xn--p1ai", "xn--pgbs0dh", "xn--s9brj9c", "xn--wgbh1c", "xn--wgbl6a", "xn--xkc2al3hye2a", "xn--xkc2dl3a5ee0h", "xn--yfro4i67o", "xn--ygbi2ammx", "xn--zckzah", "xxx", "ye", "yt", "za", "zm", "zw"].join()

function getDomain(url){

    var parts = url.split('.');
    if (parts[0] === 'www' && parts[1] !== 'com'){
        parts.shift()
    }
    var ln = parts.length
      , i = ln
      , minLength = parts[parts.length-1].length
      , part

    // iterate backwards
    while(part = parts[--i]){
        // stop when we find a non-TLD part
        if (i === 0                    // 'asia.com' (last remaining must be the SLD)
            || i < ln-2                // TLDs only span 2 levels
            || part.length < minLength // 'www.cn.com' (valid TLD as second-level domain)
            || TLDs.indexOf(part) < 0  // officialy not a TLD
        ){
            return part
        }
    }
}

getDomain(location.host)

希望我没有错过太多的边角案例。这个应该可以在location对象中找到 :(

测试用例: http://jsfiddle.net/hqBKd/4/

可以在此处找到TLD列表:http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1


@demix 噢,需要验证 TLD:/ - Ricardo Tomasi
1
一些现实世界中的“边缘情况”,并不太难发现:www.epa.qld.gov.au 返回“qld”,而可能期望的是“epa”。www.edu.com 返回“www”,而可能期望的是“edu”。OP尚未解释“域名”是什么。 - RobG
1
我建议使用像URI.js这样的库(http://medialize.github.com/URI.js/)。它非常强大,并且有一个不错的社区支持。 - Georgii Ivankin
@Orwellophile如果你再读一遍这个答案,你会看到这是最初的方法。xxx.ukxxx.co.uk都是有效的,在两者中xxx是"域名"。另一方面,co.uk不是有效地址,而be.at可能是。除了查看注册的顶级域名和二级域名列表外,没有其他方法来解决这些差异。 - Ricardo Tomasi
显示剩余3条评论

11

我在寻找适用于大多数情况的解决方案,而不必维护顶级域名列表(以及跳过它的大小!)。据我看来,你可以通过查看常见的二级域名来相当准确地做到这一点:

function getDomainName(domain) {
    var parts = domain.split('.').reverse();
    var cnt = parts.length;
    if (cnt >= 3) {
        // see if the second level domain is a common SLD.
        if (parts[1].match(/^(com|edu|gov|net|mil|org|nom|co|name|info|biz)$/i)) {
            return parts[2] + '.' + parts[1] + '.' + parts[0];
        }
    }
    return parts[1]+'.'+parts[0];
}

试验和演示 @ http://jsfiddle.net/mZPaf/2/

欢迎评价和思考。


www.gov.comwww.edu.com以及类似的域名都无法访问。 - Ricardo Tomasi
是的 - 肯定不完美,但对我的情况足够了。我想你可以检查一下 parts[0] 也不是常见的 SLD。 - AcidPAT

2
var docdomain = document.domain.split('.');
var dom1 = "";
if (typeof (docdomain[docdomain.length - 2]) != 'undefined') dom1 = docdomain[docdomain.length - 2] + '.';
var domain = dom1 + docdomain[docdomain.length - 1];
console.log(domain);

//without subdomains

1
你应该在回答中添加一些解释/描述,以帮助提问者理解。 - Miguel-F

1

如果没有完整的顶级域名列表(会变得非常长)。如果您只需要从当前页面获取域名,可以使用我的技术(使用cookie查找根域名)

JavaScript-获取除子域名之外的域名

要删除扩展名,然后可以使用str.split('。')[0]的第一个元素。


这是一个非常优秀的解决方案,它涵盖了许多边角情况。您能否用代码示例格式化您的答案并回答问题?之后,此答案可以被接受。 - terales
此外,它缺乏一些解释,可能无法用于嵌入iframe的脚本:https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy - terales
我知道这是一个旧答案,但你应该在这里(回答中)包含代码,以防将来由于某种原因链接的网站无法访问 - 在这种情况下,这个答案就变得无用了。 - naththedeveloper

1

我能想到的唯一方法是列出所有的顶级域名。示例代码如下。

function getDomainName(){
    var domainList = ['com','org','net',...];//all  TLD
    var tokens = document.domain.split('.');
    while(tokens.length){
        var token = tokens.pop();
        if( domainList.indexOf(token) == -1 ){
            return token;
        }
    }
    return null;
}

在IE中,Array.prototype.indexOf需要进行一些修复。


0

我需要做这件事情,并设计了一个简单的东西来满足我的使用情况。

function stripSubDomainAndTLD (domain) {
    return domain.replace(/^(?:[a-z0-9\-\.]+\.)??([a-z0-9\-]+)(?:\.com|\.net|\.org|\.biz|\.ws|\.in|\.me|\.co\.uk|\.co|\.org\.uk|\.ltd\.uk|\.plc\.uk|\.me\.uk|\.edu|\.mil|\.br\.com|\.cn\.com|\.eu\.com|\.hu\.com|\.no\.com|\.qc\.com|\.sa\.com|\.se\.com|\.se\.net|\.us\.com|\.uy\.com|\.ac|\.co\.ac|\.gv\.ac|\.or\.ac|\.ac\.ac|\.af|\.am|\.as|\.at|\.ac\.at|\.co\.at|\.gv\.at|\.or\.at|\.asn\.au|\.com\.au|\.edu\.au|\.org\.au|\.net\.au|\.id\.au|\.be|\.ac\.be|\.adm\.br|\.adv\.br|\.am\.br|\.arq\.br|\.art\.br|\.bio\.br|\.cng\.br|\.cnt\.br|\.com\.br|\.ecn\.br|\.eng\.br|\.esp\.br|\.etc\.br|\.eti\.br|\.fm\.br|\.fot\.br|\.fst\.br|\.g12\.br|\.gov\.br|\.ind\.br|\.inf\.br|\.jor\.br|\.lel\.br|\.med\.br|\.mil\.br|\.net\.br|\.nom\.br|\.ntr\.br|\.odo\.br|\.org\.br|\.ppg\.br|\.pro\.br|\.psc\.br|\.psi\.br|\.rec\.br|\.slg\.br|\.tmp\.br|\.tur\.br|\.tv\.br|\.vet\.br|\.zlg\.br|\.br|\.ab\.ca|\.bc\.ca|\.mb\.ca|\.nb\.ca|\.nf\.ca|\.ns\.ca|\.nt\.ca|\.on\.ca|\.pe\.ca|\.qc\.ca|\.sk\.ca|\.yk\.ca|\.ca|\.cc|\.ac\.cn|\.com\.cn|\.edu\.cn|\.gov\.cn|\.org\.cn|\.bj\.cn|\.sh\.cn|\.tj\.cn|\.cq\.cn|\.he\.cn|\.nm\.cn|\.ln\.cn|\.jl\.cn|\.hl\.cn|\.js\.cn|\.zj\.cn|\.ah\.cn|\.gd\.cn|\.gx\.cn|\.hi\.cn|\.sc\.cn|\.gz\.cn|\.yn\.cn|\.xz\.cn|\.sn\.cn|\.gs\.cn|\.qh\.cn|\.nx\.cn|\.xj\.cn|\.tw\.cn|\.hk\.cn|\.mo\.cn|\.cn|\.cx|\.cz|\.de|\.dk|\.fo|\.com\.ec|\.tm\.fr|\.com\.fr|\.asso\.fr|\.presse\.fr|\.fr|\.gf|\.gs|\.co\.il|\.net\.il|\.ac\.il|\.k12\.il|\.gov\.il|\.muni\.il|\.ac\.in|\.co\.in|\.org\.in|\.ernet\.in|\.gov\.in|\.net\.in|\.res\.in|\.is|\.it|\.ac\.jp|\.co\.jp|\.go\.jp|\.or\.jp|\.ne\.jp|\.ac\.kr|\.co\.kr|\.go\.kr|\.ne\.kr|\.nm\.kr|\.or\.kr|\.li|\.lt|\.lu|\.asso\.mc|\.tm\.mc|\.com\.mm|\.org\.mm|\.net\.mm|\.edu\.mm|\.gov\.mm|\.ms|\.nl|\.no|\.nu|\.pl|\.ro|\.org\.ro|\.store\.ro|\.tm\.ro|\.firm\.ro|\.www\.ro|\.arts\.ro|\.rec\.ro|\.info\.ro|\.nom\.ro|\.nt\.ro|\.se|\.si|\.com\.sg|\.org\.sg|\.net\.sg|\.gov\.sg|\.sk|\.st|\.tf|\.ac\.th|\.co\.th|\.go\.th|\.mi\.th|\.net\.th|\.or\.th|\.tm|\.to|\.com\.tr|\.edu\.tr|\.gov\.tr|\.k12\.tr|\.net\.tr|\.org\.tr|\.com\.tw|\.org\.tw|\.net\.tw|\.ac\.uk|\.uk\.com|\.uk\.net|\.gb\.com|\.gb\.net|\.vg|\.sh|\.kz|\.ch|\.info|\.ua|\.gov|\.name|\.pro|\.ie|\.hk|\.com\.hk|\.org\.hk|\.net\.hk|\.edu\.hk|\.us|\.tk|\.cd|\.by|\.ad|\.lv|\.eu\.lv|\.bz|\.es|\.jp|\.cl|\.ag|\.mobi|\.eu|\.co\.nz|\.org\.nz|\.net\.nz|\.maori\.nz|\.iwi\.nz|\.io|\.la|\.md|\.sc|\.sg|\.vc|\.tw|\.travel|\.my|\.se|\.tv|\.pt|\.com\.pt|\.edu\.pt|\.asia|\.fi|\.com\.ve|\.net\.ve|\.fi|\.org\.ve|\.web\.ve|\.info\.ve|\.co\.ve|\.tel|\.im|\.gr|\.ru|\.net\.ru|\.org\.ru|\.hr|\.com\.hr)$/, '$1');
}

主要我只想删除所有子域名,不幸的是,对于一些新的 TLDs 来说这并不是百分之百有效的方法,但它的效果还是相当不错的,并且你随时可以添加正则表达式。

http://jsfiddle.net/icodeforlove/TzjJE/2/


0
通过上面其他朋友提供的代码示例,我创建了一个函数,它将仅返回域名,并且如果域名无效,例如缺少顶级域名,则会根据我的要求附加“.com”。
function getDomain(url){

var TLDs = ["ac", "ad", "ae", "aero", "af", "ag", "ai", "al", "am", "an", "ao", "aq", "ar", "arpa", "as", "asia", "at", "au", "aw", "ax", "az", "ba", "bb", "bd", "be", "bf", "bg", "bh", "bi", "biz", "bj", "bm", "bn", "bo", "br", "bs", "bt", "bv", "bw", "by", "bz", "ca", "cat", "cc", "cd", "cf", "cg", "ch", "ci", "ck", "cl", "cm", "cn", "co", "com", "coop", "cr", "cu", "cv", "cx", "cy", "cz", "de", "dj", "dk", "dm", "do", "dz", "ec", "edu", "ee", "eg", "er", "es", "et", "eu", "fi", "fj", "fk", "fm", "fo", "fr", "ga", "gb", "gd", "ge", "gf", "gg", "gh", "gi", "gl", "gm", "gn", "gov", "gp", "gq", "gr", "gs", "gt", "gu", "gw", "gy", "hk", "hm", "hn", "hr", "ht", "hu", "id", "ie", "il", "im", "in", "info", "int", "io", "iq", "ir", "is", "it", "je", "jm", "jo", "jobs", "jp", "ke", "kg", "kh", "ki", "km", "kn", "kp", "kr", "kw", "ky", "kz", "la", "lb", "lc", "li", "lk", "lr", "ls", "lt", "lu", "lv", "ly", "ma", "mc", "md", "me", "mg", "mh", "mil", "mk", "ml", "mm", "mn", "mo", "mobi", "mp", "mq", "mr", "ms", "mt", "mu", "museum", "mv", "mw", "mx", "my", "mz", "na", "name", "nc", "ne", "net", "nf", "ng", "ni", "nl", "no", "np", "nr", "nu", "nz", "om", "org", "pa", "pe", "pf", "pg", "ph", "pk", "pl", "pm", "pn", "pr", "pro", "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", "sy", "sz", "tc", "td", "tel", "tf", "tg", "th", "tj", "tk", "tl", "tm", "tn", "to", "tp", "tr", "travel", "tt", "tv", "tw", "tz", "ua", "ug", "uk", "us", "uy", "uz", "va", "vc", "ve", "vg", "vi", "vn", "vu", "wf", "ws", "xn--0zwm56d", "xn--11b5bs3a9aj6g", "xn--3e0b707e", "xn--45brj9c", "xn--80akhbyknj4f", "xn--90a3ac", "xn--9t4b11yi5a", "xn--clchc0ea0b2g2a9gcd", "xn--deba0ad", "xn--fiqs8s", "xn--fiqz9s", "xn--fpcrj9c3d", "xn--fzc2c9e2c", "xn--g6w251d", "xn--gecrj9c", "xn--h2brj9c", "xn--hgbk6aj7f53bba", "xn--hlcj6aya9esc7a", "xn--j6w193g", "xn--jxalpdlp", "xn--kgbechtv", "xn--kprw13d", "xn--kpry57d", "xn--lgbbat1ad8j", "xn--mgbaam7a8h", "xn--mgbayh7gpa", "xn--mgbbh1a71e", "xn--mgbc0a9azcg", "xn--mgberp4a5d4ar", "xn--o3cw4h", "xn--ogbpf8fl", "xn--p1ai", "xn--pgbs0dh", "xn--s9brj9c", "xn--wgbh1c", "xn--wgbl6a", "xn--xkc2al3hye2a", "xn--xkc2dl3a5ee0h", "xn--yfro4i67o", "xn--ygbi2ammx", "xn--zckzah", "xxx", "ye", "yt", "za", "zm", "zw"].join()

    url = url.replace(/.*?:\/\//g, "");
    url = url.replace(/www./g, "");
    var parts = url.split('/');
    url = parts[0];
    var parts = url.split('.');
    if (parts[0] === 'www' && parts[1] !== 'com'){
        parts.shift()
    }
    var ln = parts.length
      , i = ln
      , minLength = parts[parts.length-1].length
      , part

    // iterate backwards
    while(part = parts[--i]){
        // stop when we find a non-TLD part
        if (i === 0                    // 'asia.com' (last remaining must be the SLD)
            || i < ln-2                // TLDs only span 2 levels
            || part.length < minLength // 'www.cn.com' (valid TLD as second-level domain)
            || TLDs.indexOf(part) < 0  // officialy not a TLD
        ){
            var actual_domain = part;
            break;
            //return part
        }
    }
    //console.log(actual_domain);
    var tid ;
    if(typeof parts[ln-1] != 'undefined' && TLDs.indexOf(parts[ln-1]) >= 0)
    {
        tid = '.'+parts[ln-1];
    }
    if(typeof parts[ln-2] != 'undefined' && TLDs.indexOf(parts[ln-2]) >= 0)
    {
        tid = '.'+parts[ln-2]+tid;
    }
    if(typeof tid != 'undefined')
        actual_domain = actual_domain+tid;
    else
        actual_domain = actual_domain+'.com';


    return actual_domain;
}

0

您可以使用document.domain来确定当前页面的域名。

设置document.domain时,如果新值无效,则会抛出错误。纯eTLD是无效的,而eTLD+1是有效的。下面的函数循环查找有效值,然后返回域名部分。

这是全面的,因为浏览器使用公共后缀列表来验证新值。

function getDomainName() {
    const original = document.domain;
    const parts = location.hostname.split('.');
    let etld = parts.pop();
    while (parts.length) {
        const name = parts.pop();
        const test = name + '.' + etld;
        try {
            document.domain = test;
            // we found the eTLD+1
            
            // reset before returning
            document.domain = original;

            return name;
        } catch (e) {
            // eTLDs and eTLD fragments fail
            etld = test;
        }
    }
}

0

很简单:

    var tokens = document.domain.split('.');
    var domain = tokens[tokens.length - 2];

我测试了两种方式,都可以。至少在FF中是可以的。也许是某些浏览器的小问题? - ioseb
我正在使用Chrome浏览器...你看到我的链接了吗? - Purag
明白了。尽管如此,在这种域中不起作用,抓取域名并分割它以及检索实际名称是两个不同的任务。我认为这可以用来进一步优化“算法”在我看来。 - ioseb
那么 www.epa.qld.gov.au 中的域名是什么? - RobG
@RobG 之所以不能注册 'qld',是因为它不是一个顶级域名。他要找的定义可以参考 http://en.wikipedia.org/wiki/Second-level_domain。 - Ricardo Tomasi
显示剩余5条评论

-1

我使用的正则表达式仅获取域名: ([^.]*[.]){0,}([^.]*)(\.[^.]*) 域名可以在第二部分中找到。


www.example.co.uk 上失败了。第二部分是 co - Quentin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接