一个人应该多远进行一次电子邮件地址验证?


101

我想知道人们应该花多长时间验证电子邮件地址。我的领域主要是网络开发,但这适用于任何地方。

我看过几种方法:

  • 只需检查是否存在“ @”,这很简单,但当然不是那么可靠。
  • 用于标准电子邮件格式的更复杂的正则表达式测试
  • 一个针对RFC 2822完整正则表达式 -问题在于通常一个电子邮件地址可能是有效的,但它可能不是用户的意思
  • DNS验证
  • SMTP验证

正如许多人可能知道(但许多人却不知道)一样,电子邮件地址可能具有很多人通常不考虑的许多奇怪变化(请参阅RFC 2822 3.4.1),但是您必须考虑以下目标:您的验证:您只是在尝试确保可以将电子邮件发送到某个地址,或者是用户可能要输入的电子邮件(在很多其他晦涩的情况下,否则“有效”是不可能的)的地址)。

我考虑过的一个选项只是用一个更加深奥的地址发出警告,但仍然允许请求通过,但这确实增加了表单的复杂性,并且大多数用户很可能会感到困惑。

虽然DNS验证/ SMTP验证似乎很容易,但我可以预见到DNS服务器/ SMTP服务器暂时关闭且用户无法在某处注册,或者用户的SMTP服务器不支持所需功能的问题。

一些经验丰富的开发人员将如何处理此问题?除了我列出的方法以外,还有其他方法吗?

编辑:我完全忘记了最显而易见的一切,发送确认电子邮件!感谢答复者指出这一点。是的,这很简单,但是涉及的每个人确实需要额外的麻烦。用户必须获取一些电子邮件,开发人员需要在甚至确认用户数据有效之前记住用户数据。


我个人将使用双重正则表达式“警告和拒绝”策略,然后再发送一封电子邮件以确认地址的所有权。
詹姆斯·斯内尔

最大的问题是询问您要求的地址是什么目的。例如,如果您要向用户发送验证电子邮件,则只需进行一次简单的检查就可以了,因为大概是出于激励用户提供有效地址的目的。
SDsolar

Answers:


80

像大多数论坛一样,除了向用户发送电子邮件并等待响应外,没有100%可靠的方法来确认有效的电子邮件地址。

我将使用简单的“ @”验证规则,然后向用户发送电子邮件以确认其电子邮件地址。

虽然,这是我的个人观点...我正在等待其他建议。


6
完全同意。您是否真的在乎那个地址,或者您不在乎。我看不到半心半意的理由。
Benjol 2011年

3
迄今为止最好的答案。 验证 @,然后验证地址(带有电子邮件)-那里有细微的差别。
billy.bob 2011年

...这就是多数论坛这样做的原因。
丹·雷

我同意@Billy Bob的观点,认为简单的验证以及随后的验证电子邮件是证明电子邮件准确无误的最有效方法。
SDsolar

“有效”电子邮件地址也可能发送给错误的人,因此,确认电子邮件确实是唯一可以确定的方法。每年,当有人为我自己输入自己的电子邮件地址错误时,我都会得到其中的一些信息。
axl

57

一个建议:不要拒绝地址中带有+的地址。拒绝它们是很烦人的事,但这是一个有效的字符,并且gmail用户可以使用address+label@gmail.com来更轻松地标记和分类传入的邮件。


8
+1 !!! 似乎不可能过滤来自所有站点的Facebook电子邮件!
jnylen

可以不进行过滤-仅使用发件人信息
Casebash

1
GMail从其他邮件服务器上将其提取。我相信qmail和postfix普及了它。

23
尽管我同意这种观点,但这甚至还没有开始回答这个问题。
Bryan Oakley

29

在您的帖子中,似乎当您说“ SMTP验证”时,是指连接到服务器并尝试RCPT TO以查看它是否被接受。由于您将其与实际发送确认电子邮件区分开来,因此,我假设您希望根据用户操作内联处理。除了网络问题,DNS故障等问题之外,此方法还会对灰色列表造成严重破坏。方法各不相同,但从本质上讲,灰色列表始终会阻止按连接IP向收件人发送邮件的首次尝试。就像我说的那样,这可能会有所不同,有些主机可能会在初次尝试时拒绝无效地址,而只会推迟有效地址,但是没有可靠的方法可以通过编程方式来选择不同的实现。

您唯一可以确定地址有效且真正由其所有者确实希望将其用于您的应用程序的所有者提交的方法是发送验证电子邮件。好吧,只要它没有被垃圾邮件过滤掉,我猜=)。


25

使用正则表达式进行电子邮件验证的另一个缺点是,几乎不可能捕获所有有效的顶级域名,同时拒绝所有无效的顶级域名

例如,Jeff Atwood回复中的基本电子邮件正则表达式:

\ b [A-Z0-9 ._%+-] + @ [A-Z0-9 .-] +。[AZ] {2,4} \ b

将接受任何2到4个字符的TLD。因此,例如,.spam将被接受,但.museum和.travel(均为有效TLD)将被拒绝。

还有一个原因是,最好只查找@,然后发送确认电子邮件。


24

使用国际域名,几乎一切皆有可能:

  • Håkan.Söderström@malmö.se
  • punnycode@XN--0ZWM56D.XN--HGBK6AJ7F53BBA
  • 试@示例。测试.مثال.آزمایشی

如果要进行任何测试,则应首先将其转换为punycode。

没有punycode,您要做的就是在此进行测试:

  • 至少是一个@
  • 在本地至少是一个字符
  • 在域部分至少是一个点
  • 是域中的至少四个字符(假设没有人在tld上有地址,并且tld至少为2个字符)
function isEmail(address) {
    var pos = address.lastIndexOf("@");
    return pos > 0 && (address.lastIndexOf(".") > pos) && (address.length - pos > 4);
}

1
如果你想使用JavaScript来转换为Punycode,您可以在以下答案中使用的代码:stackoverflow.com/questions/183485/...

足够真实-然后确保@符号可能是确保其“看起来”像电子邮件地址的唯一方法。
SDsolar

19

最好只检查诸如@和的简单内容。使用JavaScript,然后将验证发送给他们的电子邮件。如果他们验证了他们的帐户,则您将拥有一个有效的电子邮件地址。这样,您就可以确定自己有一个工作地址,而不必过于专横。


这是一个很好的解决方案。这是一个正则表达式,以查找@后跟一个点:/.+@.+\..+/
Evan Moran 2013年

11

使用不会给出假阴性的开源验证器。您的零工作和对应用程序的强大验证。

我现在整理了Cal Henderson,Dave Child,Phil Haack,Doug Lovell和RFC 3696的测试用例。总共有158个测试地址。

我对所有可以找到的验证器进行了所有这些测试。比较在这里:http : //www.dominicsayers.com/isemail

当人们增强其验证器时,我将尝试使此页面保持最新。感谢Cal,Dave和Phil在汇编这些测试和对我自己的验证程序的建设性批评方面所提供的帮助和合作。

人们应该特别注意针对RFC 3696勘误表。实际上,其中三个规范示例是无效地址。地址的最大长度为254或256个字符,而不是 320。


比较链接已关闭:(
Zero3 '17

10

考虑到答案(因为我完全忘记了确认电子邮件),在我看来,低摩擦解决方案的合适折衷办法是:

  1. 使用正则表达式检查电子邮件地址看起来是否有效,如果它比较晦涩,则发出警告,但请避免直接拒绝。
  2. 使用SMTP验证来确保电子邮件地址有效。
  3. 如果SMTP验证失败,则(仅在此之后)使用确认电子邮件作为最后的手段。确认电子邮件似乎需要在应用程序之外进行过多的交互,才能被认为具有低摩擦性,但是它们是一个完美的备用。

1
您如何在不发送确认的情况下检查用户是否拥有电子邮件地址?例如,假设他们输入了您的电子邮件地址。您是否会因为开发人员决定不提供确认电子邮件而感到恼火,因此允许知道您地址的任何人在您的网站上进行签名?
Rupert Madden-Abbott

1
SMTP验证?询问服务器地址是否存在?垃圾邮件摆脱了很久以前。

6

RegexBuddy从其库中提供以下与电子邮件相关的正则表达式:

电子邮件地址(基本)

\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b

电子邮件地址(RFC 2822,简化)

[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?

但是我倾向于同意Peter和SuperJoe的回答。唯一真正的“测试”实际上是发送验证电子邮件。


1
您的基本电子邮件检查无法通过进行检查bob@mydivision.mycompany.com。您还应该说不区分大小写的匹配是必需的,因为您仅使用大写ASCII码。
Unpythonic 2011年

为什么拒绝大写字符(使用第二个正则表达式)?在接受MTA之前不应该对本地部分进行验证吗?除空格和引号外。
德克·雅克(DirkJäckel)2012年

@dirk如标记所示,运行此正则表达式时,应将“不区分大小写”标志应用于此正则表达式。
杰夫·阿特伍德

基本的级别不好,因为有几个TLD> 4个字符。我要让它成为最小2,而不是最大{2,}
EkriirkE 2014年

4

我曾在4家不同的公司工作过,那里的服务台有人叫O'Malley或O'Brien或其他带有撇号的电子邮件地址大喊大叫。如前所述,并非所有的正则表达式都能抓住一切,但可以为自己节省一些麻烦并接受撇号,而不会产生警告。

-
BMB


但愿如此。顺便说一句,哈希符号(#)也是如此。
Tomalak

2
人们的名字不包含井号,并不表示他们在电子邮件地址中无效。
戴夫·谢罗曼


3

如果要验证电子邮件(即确保用户拥有该电子邮件地址),则只能执行确认电子邮件。然后,许多人再次拥有专用的垃圾邮件地址或使用诸如OneWayMail之类的服务,如果他们不想给您实际的电子邮件地址,则不会。因此,基本上,您是在制造用户障碍。

当涉及验证时,以确保用户不会无意中输入错误的电子邮件地址,这绝对是正确的动机。但是,至少对于HTML表单(这是迄今为止最常用的收集电子邮件地址的方式),它并不是正确的工具。

首先,您将无法在电子邮件地址的实际“单词”中识别拼写错误。您back2dso@example.com仅凭格式无法找出错误。
但更重要的是,从用户的角度来看,您可能只想输入一个(或一手)电子邮件地址。您可能已经输入了。
因此,您应该着重确保所有浏览器都可以识别电子邮件字段,而不是尝试验证地址,从而无需首先输入电子邮件地址。当然,如果您要建立的网站以前从未在浏览器中输入过电子邮件地址的用户访问过,那么这将不适用。但是我想我们当中至少有一个这样的职位。


2

我认为这取决于您使用电子邮件的上下文。更严肃的项目需要更严格的验证,但我认为对于大多数情况,使用构型链接将电子邮件发送到提供的地址将确保电子邮件地址有效。


2

@ Mike-我认为发送确认电子邮件的部分原因不仅在于确保电子邮件地址有效,还在于提交电子邮件的用户可以访问该电子邮件地址。一个人可以很容易地在电子邮件地址中输入一个字母的错字,这将导致一个不同的有效电子邮件地址,但这仍然是一个错误,因为它是错误的地址。


2

我在电子邮件验证中遇到的最完整,最准确的正则表达式是这里记录的内容。这不是为了胆小的人;它非常复杂,因此将其分解成多个部分,以使人类更容易解析(示例代码是Java)。但是,如果必须进行验证,我认为它不会变得更好。

无论如何,我建议您使用单元测试来确认您的表达涵盖了您认为重要的情况。这样,当您仔细研究它时,可以确保您没有破坏过以前可以解决的问题。


2

无论你选择,我认为你需要宁可认为的99%的时间,用户侧确实知道他们的电子邮件地址是什么。作为来自澳大利亚的某人,我仍然偶尔会发现一个非常聪明的电子邮件验证,该验证告诉我我不可能拥有.com.au域。在互联网初期,这种事情在您看来早已发生了很多。

这些天发送确认电子邮件对于用户来说是可以接受的,并且对于选择加入以及验证其提供的地址也很有用。


2

在我工作过的地方开发的一些网站上,我们一直使用确认电子邮件。但是,对于用户来说,以无法正常工作的方式错误地键入他们的电子邮件地址,然后继续等待不会收到确认电子邮件,这是令人惊讶的普遍现象。在这些情况下,添加临时代码(或对于域名部分,则是DNS验证)来警告用户可能是一个好主意。

我见过的常见情况:

  • 在域名中间放置一个字母,或其他几个简单的拼写错误。
  • TLD混乱(例如,将a添加.br.com域中,或将其.br.com.br域中删除)。
  • www.在电子邮件地址的本地部分的开头添加一个(我没有做这个;我看到表单的几个电子邮件地址www.username@example.com)。

甚至还有更多奇怪的案例。像完整的域名作为本地部分,带有两个地址@(类似username@domain.tld@example.com)的地址等等。

当然,其中大多数仍然是有效的RFC-822地址,因此从技术上讲,您可以让MTA处理它们。但是,警告用户输入的电子邮件地址很可能是虚假的,这可能会有所帮助,特别是如果您的目标受众不是很懂计算机的人。


这些网站的问题听起来像是用户被迫输入他们真正不理解的信息。并非所有站点都需要与其用户进行电子邮件联系,即使这会使站点变得更容易。
bzlm


2

取决于目标。如果您是ISP,并且需要验证用户是否正在创建有效的电子邮件地址,请使用可对所有可能的内容进行验证的Regex。如果您只想捕获用户错误,请遵循以下模式:

[所有字符,无空格] @ [字母和数字](。[字母和数字]),最后一组至少出现一次。

正则表达式如下所示:

[\S]+@[\w]+(.[\w-]+)+

然后发送确认电子邮件以确保。


2
有一个拼写错误(除非您只希望允许“ w”作为TLD),并且它不会将带连字符(-)的域匹配。效果更好:[\ S] + @ [\ w-] +(。[\ w-] +)+

1

@ Yaakov(可以在此处回复某种“回复”)

我认为发送确认电子邮件的部分原因不仅在于确保电子邮件地址有效,而且在于提交电子邮件的用户可以访问。一个人可以很容易地在电子邮件地址中输入一个字母的错字,这将导致一个不同的有效电子邮件地址,但这仍然是一个错误,因为它是错误的地址。

我同意,但是我不确定是否值得。我们也有用于此目的的确认字段(再次重复您的电子邮件地址)。网站类型可能需要采用不同方法的另一种情况。

此外,发送确认电子邮件本身无法向原始用户表明他们输入的地址错误。在未收到确认电子邮件后,他们可能会认为您的应用程序/网站有问题;至少允许用户立即开始使用其帐户,他们可以更正其电子邮件地址,尤其是如果该电子邮件地址显示在适当明显的位置。


1

马课程。

所有这些本身就是有效的,完整的电子邮件验证系统,对于一个给定的网站,一个将比其他网站更合适(或完全保证)。在许多情况下,验证的几个步骤可能会有用。

如果您要为银行开发网站,那么除了这些之外,还需要蜗牛邮件或电话验证。

如果您要为竞赛开发网站,则可能不需要任何一个-验证电子邮件是否在后期处理中,如果电子邮件失败,对于进入该网站的人来说太糟糕了-考虑到大量的用户,您可能会评价服务器的性能(例如电视大赛),以确保每个人都正确地在线验证。

一个人应该多远进行一次电子邮件验证?

在必要和有保证的情况下。

再也没有(吻)


1

我见过一些网站也可以防止使用临时丢弃的垃圾桶站点的人,例如MailinatorMyTrashMail,它们避开了确认电子邮件。我并不是说您应该将这些过滤掉,而是说。


它以什么方式“绕开”电子邮件确认?Mailinator和MyTrashMail都将接受后续到同一地址的邮件。如果用户不愿意检查它们,那就是另一回事了。
bzlm

1

您想在电子邮件验证中抓住什么?

电子邮件地址的正则表达式验证最多可以验证该地址在语法上正确且相对合理。如果正则表达式不太正确,它也有可能拒绝实际的,可交付的地址(已经多次提到)。

SMTP验证可以确定该地址是否可交付,这取决于灰名单或服务器的配置限制,服务器被配置为尽可能少地提供有关其用户的信息。您无法知道MTA是否只是声称接受虚假地址的邮件,然后将其作为反垃圾邮件策略的一部分放到地板上。

但是,发送确认消息是验证地址是否属于输入用户的唯一方法。如果我要填写您的表格,我可以很容易地告诉您我的电子邮件地址是president@whitehouse.gov。正则表达式会告诉您它在语法上是有效的,SMTP RCPT TO会告诉您这是一个可交付的地址,但可以肯定的是,这不是我的地址。


1

随着HTML5的到来,至少增加了一种新方法:使用类型为email的输入,该输入允许在客户端进行验证。当前版本的Firefox,Chrome,Safari和Opera确实支持此功能(其他浏览器只是将其视为type = text,因此可以毫无问题地使用它,当然您也无需进行验证。)

它永远无法保证(如几次指出的那样)地址可用,但是在您只需要捕获可能的用户错误的地方,它可能会非常有益(最终取代服务器端检查)。


<input type="email">HTMLElement 的Firefox实现:dxr.mozilla.org/mozilla-central/source/dom/html/…–
tiffon

0

电子邮件验证的三个主要级别:

1)正则表达式检查格式正确的电子邮件地址email@email.com

2)通过MX记录检查电子邮件域,以查看域名是否具有电子邮件服务

3)发送带有确认链接或代码的确认电子邮件

1级:

在Visual Studio中,可以使用“正则表达式验证器”。在“ ValidationExpression”属性中,您可以单击“ ...”按钮,该按钮具有一个向导,可以为电子邮件地址添加正则表达式格式。

2级:

这是我下面的C#代码,用于使用nslookup验证电子邮件域是否具有有效的MX记录。在Win 2008 R2和Win 7上运行正常。

using System.Net.Mail;
using System.Diagnostics;

public static bool checkMXRecords(string email) 
    {
        MailAddress addr = new MailAddress(email);
        string domain = addr.Host;

        string command = "nslookup -querytype=mx " + domain;
        ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", "/c " + command);

        procStartInfo.RedirectStandardOutput = true;
        procStartInfo.UseShellExecute = false;

        procStartInfo.CreateNoWindow = true;

        Process proc = new Process();
        proc.StartInfo = procStartInfo;
        proc.Start();
        string result = proc.StandardOutput.ReadToEnd();

        if (result.ToLower().Contains("mail exchanger"))
        {
            return true;
        }
        else return false;

     } // checkMXRecords

另一个选择是使用Arsofttools nuget程序包,但据我所知,它在Windows Server 2008 R2上可能会变慢,但在Win 7上运行速度很快。

3级:

对于电子邮件确认,您可以生成电子邮件特定的十六进制url(使用加密功能)等http://domain.com/validateEmail?code=abcd1234以在用户单击时验证电子邮件地址。无需将该URL存储在内存中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.