如何在JavaScript中验证一个电子邮件地址的方法

155 阅读3分钟

电子邮件地址的验证是处理表单时的常见操作之一。

它在联系表单、注册和登录表单等方面很有用。

有些人建议,你根本就不应该验证电子邮件。我认为,在不试图过度热衷的情况下,进行一点验证会更好。

邮件验证应该遵循哪些规则呢?

一个电子邮件地址由两部分组成:本地部分和域名部分。

本地部分可以包含

  • 任何字母数字字符。a-zA-Z0-9
  • 标点符号。"(),:;<>@[\]
  • 特殊字符。!#$%&'*+-/=?^_``{|}~
  • 一个点. ,如果它不是第一个或最后一个字符。此外,它不能重复。

域名部分可以包含

  • 任何字母数字字符。a-zA-Z0-9
  • 连字符- ,如果它不是第一个或最后一个字符。它可以重复

使用Regex

验证电子邮件地址的最佳选择是通过使用一个 正则表达式.

没有通用的电子邮件检查正则。每个人似乎都在使用不同的,而且你在网上找到的大多数正则表达式都会在最基本的电子邮件情况下失败,原因是不准确或没有计算新引进的域名,或国际化的电子邮件地址。

不要盲目地使用任何正则表达式,要先检查。

在Glitch上做了这个例子,它将根据一个正则表达式检查一个被认为有效的电子邮件地址列表。你可以改变这个正则表达式,并与你想使用的其他表达式进行比较。

目前添加的这个是我认为我找到的最准确的一个,稍加编辑,以修复一个多点的问题。

注意:这不是我想出来的。我在Quora的一个答案中发现了它,但我不确定那是原始来源。

这是一个使用该重码验证的函数。

const validate = (email) => {
  const expression = /(?!.*\.{2})^([a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+(\.[a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)*|"((([ \t]*\r\n)?[ \t]+)?([\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*(([ \t]*\r\n)?[ \t]+)?")@(([a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.)+([a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.?$/i

  return expression.test(String(email).toLowerCase())
}

所有常见的情况都得到了满足,我们可以假设99.9%的人要添加的电子邮件地址都被成功验证了。

这个故障的代码包含了其他的正则表达式,你可以通过改造项目轻松尝试。

虽然相当准确,但这个正则表达式在一些边缘情况下有几个问题,你可以根据你的需要来接受(或不接受)。

对于奇怪的地址来说,假性否定,例如

"very.(),:;<>[]".VERY."very@\ "very".unusual"@strange.example.com

one."more\ long"@example.website.place

对本地地址的假阴性。

admin@mailserver1
user@localserver

在公开访问的网站中没有什么用处(实际上,在公开访问的网站中,拒绝这些地址是一个优点)。

另外,对基于IP的电子邮件也是假阴性。

user@[2001:DB8::1]
user@128.0.0.1

对于本地部分过长的地址,会出现假阳性。

1234567890123456789012345678901234567890123456789012345678901234+x@example.com

你想要一个更简单的重码吗?

上面的重码是非常复杂的,以至于我甚至不会尝试去理解它。正则表达式大师创造了它,它在互联网上传播,直到我发现它。

在这一点上,使用它是一个复制/粘贴的问题。

一个更简单的解决方案只是检查输入的地址是否包含什么,然后是一个@ 符号,然后是其他东西。

在这种情况下,这个词组将起到作用。

const expression = /\S+@\S+/
expression.test(String('my-email@test.com').toLowerCase())

这将导致许多误报,但毕竟对电子邮件地址有效性的最终测试发生在你要求用户点击电子邮件中的东西来确认地址时,我宁愿尝试发送一个无效的电子邮件,而不是因为我的重码错误而拒绝一个有效的电子邮件。

这在上面的Glitch中列出,所以你可以很容易地尝试。

直接验证HTML字段

HTML5为我们提供了email 字段类型,所以别忘了你也可以用它来验证邮件。

<input type="email" name="email" placeholder="Your email" />

根据浏览器的实现,这种验证也会给你不同的结果。

这个Glitch显示了我测试的同样的邮件,以及通过HTML表单验证的结果。

结果很有趣,在这里我们也有通过的无效邮件,和没有通过的有效邮件。我们的重词实际上比浏览器内置的HTML过滤功能做得更准确。

验证服务器端

如果你的应用程序有一个服务器,服务器也需要验证电子邮件,因为你永远不能相信客户端代码,而且用户浏览器上的JavaScript可能被禁用。

使用Node.js,你有一个优势,就是可以原封不动地重用前端代码。在这种情况下,验证的函数可以在客户端和服务器端工作。

你也可以使用预先制作的软件包,如isemail,但在这种情况下,结果也是不同的。下面是我们上面使用的相同电子邮件的isemail基准:https://glitch.com/edit/#!/flavio-email-validation-node-isemail