如何在Javascript中从电子邮件地址获取域名?

16

我想在JavaScript中从电子邮件地址中获取域名部分。从电子邮件中提取域名很容易,比如使用 split 函数:对于"joe@example.com",提取出来的是 example.com

但是,电子邮件的形式也可能是"joe@subdomain1.example.com.uk"这样的形式,其中域名是 example.com.uk,而不是 subdomain1.example.com.uk。问题在于,subdomain1 可能会被错误地认为是域名的一部分。

如何可靠地解决这个问题呢?


不行。这种简单的方法无法处理我提到的第二种情况。 - lgc_ustc
6
好的,但是你需要知道所有领域,这显然是不可能的。那你又怎么知道什么是子域名,什么不是呢? - Mario Murrent
从子域名中提取顶级域名太宽泛了,需要进行特殊的检查。 - 31piy
2
@31piy 我读了那个答案,我没有看出来这是一个重复的问题。 - Matus Dubrava
3个回答

17

这并不是一个像一开始看起来那样微不足道的问题。幸运的是,有一些库可以解决这个问题,tld-extract 是一个流行的选择,它使用 Mozilla 的公共后缀列表(一个志愿者维护的列表)。使用方法如下:

var parser = require('tld-extract');

console.log( parser("www.google.com") );
console.log( parser("google.co.uk") );
/**
* >> { tld: 'com', domain: 'google.com', sub: 'www' }
* >> { tld: 'co.uk', domain: 'google.co.uk', sub: '' }
*/

要从电子邮件地址中提取服务器地址部分,首先按照 @ 字符进行拆分,如下所示:

拆分后得到的服务器地址部分即为所需内容。

```html

要从电子邮件地址中提取服务器地址部分,首先按照 @ 字符进行拆分,如下所示:

```
const email = "john@sub.domain.com"
const address = email.split('@').pop()
const domain = parser(address).domain

如果想要更深入地了解该问题的解决方案,请查看类似Python库的README

tldextract能够通过查阅Public Suffix List(PSL)中当前存在的所有通用顶级域名和国家及地区顶级域名,知道它们各自的样式。因此,根据URL,它可以从子域名得知域名,从域名得知国家代码。

请务必在Public Suffix List网站上了解该列表,并理解这是基于志愿工作的,不一定始终完整无遗漏。

Public Suffix List是一个跨供应商倡议,提供由Mozilla志愿者和注册表提交的准确的域名后缀列表,我们非常感谢他们的辛勤工作。

由于没有也仍然没有找到一种算法方法来查找特定顶级域名下可注册域名的最高级别(每个注册表的政策都不同),唯一的方法是创建一个列表。这就是Public Suffix List的目的。


唯一的问题是它不能处理电子邮件地址。 - Zoe Edwards
我会编辑我的答案并提到它,谢谢。对于电子邮件地址,请取@后面的部分并应用相同的方法。 - Moti Korets
3
唯一的问题是一个电子邮件地址可能有多个 @ - 所以最好把 最后一个 @ 作为保障! - Zoe Edwards
该问题也不适用于:user@gmail.com - iwaduarte
我认为解决电子邮件无法使用的问题的方法是在开头添加http://前缀。这对我有效:const address ='http://' + email.split('@') [1]} - Jassar

1
我认为解决这个问题的最佳方法是使用库,就像https://dev59.com/slUL5IYBdhLWcg3wt6EK#49893282中建议的那样。
但是,如果您有足够长的顶级域名和子域名列表,您可以编写一些代码来提取在“@”符号后找到的任何字符,然后从域中尝试找出您是否有一个顶级或子域名。当您知道您正在处理顶级域时,您就知道在哪里可以找到主域名,因此在它之前的所有内容必须是子域名。子域名也适用于同样的规则。
这是一个天真的实现,但您可以尝试这样做:

// TODO: needs to have an exhaustive list of top level domains
const topLevelDomains = ["com", "org", "int", "gov", "edu", "net", "mil"];

// TODO: Needs an exhaustive list of subdomains
const subdomains = ["co.uk", "org.uk", "me.uk", "ltd.uk", "plc.uk"];

function extract(str) {
  const suffix = str.match(/.+@(.+)/);
  if (suffix) {
    const groups = suffix.pop().split(".");
    const lastPart = groups[groups.length - 1];
    if (isSubDomain(groups[groups.length - 2] + "." + lastPart)) {
      console.log("Sub domain detected in: " + groups);
      if (groups.length > 3) {
        console.log("Possible subdomain: " + groups.splice(0, groups.length - 3));
        console.log();
      }
    } else if (isTopLevelDomain(lastPart)) {
      console.log("Top level domain detected in: " + groups);
      if (groups.length > 2) {
        console.log("Possible subdomain: " + groups.splice(0, groups.length - 2));
        console.log();
      }
    }
  }
}

function isTopLevelDomain(lastPart) {
  return (topLevelDomains.find(s => s === lastPart));
}

function isSubDomain(lastPart) {
  return (subdomains.find(s => s === lastPart));
}

extract("joe@example.com");
extract("joe@subdomain1.example.co.uk");
extract("joe@subdomain2.example.edu");
extract("joe@subdomain3.example.ltd.uk");
extract("joe@test.subdomain3.example.plc.uk");

请挑战这个逻辑,如果我理解错了。

-2
// Not a proper solution because of email pattern is not fixed. Use below if it is appropriate solution according to your problem .

    jQuery( document ).ready(function() {

    //var input = 'joe@subdomain1.com';
    var input = 'joe@subdomain1.example.com.uk';
    var first_split = input.split("@")[1];
    var second_split = first_split.split(".");
        if(second_split.length == 2) {

            console.log('domain is : '+first_split);

        } else if(second_split.length > 2) {
            var str = first_split.substring(first_split.indexOf(".") + 1);
            console.log('domain is : '+str);
        }


      }); 

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