如何检查电子邮件地址是否存在,而不发送电子邮件?

我遇到这个PHP代码来检查使用SMTP的电子邮件地址,而不发送电子邮件 。

有没有人尝试类似的东西,或为你工作? 你可以告诉一个电子邮件客户/用户input是否正确和存在?

有时可以使用两种方法来确定收件人实际上是否存在:

  1. 您可以连接到服务器,并发出一个VRFY命令。 很less有服务器支持这个命令,但它是专门为此而devise的。 如果服务器以2.0.0 DSN响应,则该用户存在。

    VRFY用户

  2. 您可以发出RCPT,并查看邮件是否被拒绝。

    邮件来自:<>

    RCPT TO:<user @ domain>

如果用户不存在,您将获得5.1.1 DSN。 但是,仅仅因为电子邮件不被拒绝,并不意味着用户存在。 有些服务器会默默地放弃这样的请求来阻止用户的枚举。 其他服务器无法validation用户,并且无论如何都必须接受该消息。

还有一种称为灰名单(greylisting)的反垃圾邮件技术,会导致服务器最初拒绝地址,期待真正的SMTP服务器在一段时间后尝试重新递送。 这将弄乱尝试validation地址。

老实说,如果你试图validation一个地址,最好的办法是使用一个简单的正则expression式来阻止显然无效的地址,然后发送一个带有链接的实际的电子邮件回到你的系统,validation收到的电子邮件。 这也确保了用户input了真实的电子邮件,而不是属于别人的轻微错字。

其他答案在这里讨论尝试这样做的各种问题。 我想我会告诉你,如果你想亲自学习,你可以试试这个。

您可以通过telnet连接到邮件服务器,询问是否存在电子邮件地址。 以下是一个testing电子邮件地址为stackoverflow.com的例子:

 C:\> nslookup -q = mx stackoverflow.com
非权威的回答:
 stackoverflow.com MX首选项= 40,邮件交换器= STACKOVERFLOW.COM.S9B2.PSMTP.com
 stackoverflow.com MX首选项= 10,邮件交换器= STACKOVERFLOW.COM.S9A1.PSMTP.com
邮件交换器= STACKOVERFLOW.COM.S9A2.PSMTP.com
邮件交换器= STACKOVERFLOW.COM.S9B1.PSMTP.com

 C:\> telnet STACKOVERFLOW.COM.S9A1.PSMTP.com 25
 220 Postini ESMTP 213 y6_35_0c4就绪。  CA Business and Professions Code部分17538.45禁止将此系统用于未经请求的电子邮件广告。

 helo嗨
 250 Postini说回你好

邮件来自:<me@myhost.com>
 250好的

 rcpt to:<fake@stackoverflow.com>
 550-5.1.1您尝试访问的电子邮件帐户不存在。 请尝试
 550-5.1.1重复检查收件人的电子邮件地址是否有拼写错误或
 550-5.1.1不必要的空间。 了解更多信息
 550 5.1.1 http://mail.google.com/support/bin/answer.py?answer=6596 w41si3198459wfd.71

以数字代码为前缀的行是来自SMTP服务器的响应。 我添加了一些空行,使其更具可读性。

许多邮件服务器不会返回这些信息作为阻止垃圾邮件发送者收集邮件地址的手段,所以你不能依赖这种技术。 但是,通过检测无效的邮件服务器,或者收件人地址如上所述,您可能会清除一些明显不良的电子邮件地址。

还要注意,如果你的请求过多,邮件服务器可能会将你列入黑名单。


在PHP中,我相信你可以使用fsockopenfwritefread以编程方式执行上述步骤:

 $smtp_server = fsockopen("STACKOVERFLOW.COM.S9A1.PSMTP.com", 25, $errno, $errstr, 30); fwrite($smtp_server, "helo hi\r\n"); fwrite($smtp_server, "mail from: <me@myhost.com>\r\n"); fwrite($smtp_server, "rcpt to: <fake@stackoverflow.com>\r\n"); 

一般的答案是,如果您发送电子邮件到邮件地址,您不能检查是否存在邮件地址事件:它可能会进入黑洞。

这就是说所描述的方法是相当有效的。 它用在ZoneCheck中的生产代码中,只是它使用RSET而不是QUIT。

在用户与他的邮箱进行交互的情况下,许多站点通过发送必须发回给发射器的秘密号码(通过转到秘密URL或通过电子邮件发回该秘密号码)来实际testing邮件到达某处。 大部分的邮件列表都是这样的。

不是真的…..有些服务器可能不检查“rcpt:”

http://www.freesoft.org/CIE/RFC/1123/92.htm

这样做是安全风险…..

如果服务器这样做,你可以写一个机器人来发现服务器上的每个地址….

一些问题:

  1. 我敢肯定,一些SMTP服务器会立即让你知道,如果你给他们的地址不存在,但有些不会作为隐私措施。 他们只会接受你给他们的任何地址,并默默地忽略那些不存在的地址。
  2. 正如文章所说,如果你经常在一些服务器上这样做,他们会将你列入黑名单。
  3. 对于某些SMTP服务器(如Gmail),您需要使用SSL才能做任何事情。 这只有在使用Gmail的SMTP服务器发送邮件时才是正确的。

当目标邮件服务器使用灰名单时,这将失败(在其他情况下)。

灰名单 :SMTP服务器拒绝传递第一次以前未知的客户端连接,允许下次(S); 这可以保留一定比例的垃圾邮件,同时允许合法使用 – 因为预计合法的邮件发件人将会重试 ,这是正常的邮件传输代理所要做的。

但是,如果您的代码仅在服务器上进行一次检查,则具有灰名单的服务器将拒绝交付(因为您的客户端是第一次连接); 除非您稍后再次检查,否则您可能会错误拒绝有效的电子邮件地址。

“你可以告诉一个电子邮件客户/用户input是否正确和存在?

其实这是两件不同的事情。 它可能存在,但可能不正确。

有时你必须以用户的input面值。 否则就有很多方法来打败这个系统。

假设这是用户的地址,一些邮件服务器确实允许SMTP VRFY命令实际validation邮箱的邮箱地址。 大部分的主要网站不会给你太多的信息; Gmail的回应是“如果你试图邮寄,我们会尽力提供”,或者这样的聪明。

我认为你不能,有太多的情况下甚至发送电子邮件可能会失败。 例如。 用户端邮件服务器暂时closures,邮箱存在但已满,邮件无法发送等。

这可能是为什么很多网站在用户确认收到确认电子邮件后validation注册。

关于您所能做的只是searchDNS,并确保电子邮件地址中的域名具有MXlogging,除此之外没有可靠的方式来处理此问题。

有些服务器可能与SMTP服务器交谈的rcpt-to方法一起工作,但完全取决于服务器的configuration。 另一个问题可能是服务器超载,可能会返回一个550代码,说用户是未知的,但这是一个临时的错误,有一个永久性的错误(451我认为?),可以返回。 这完全取决于服务器的configuration。

我个人会检查DNS MXlogging,如果MXlogging存在,则发送电子邮件validation。

虽然这个问题有点老,但这个服务提示可能会帮助用户在发送之前search类似的解决scheme来检查超出语法validation的电子邮件地址。

我一直在使用这个开放源代码的服务来进行更深入的电子邮件validation(检查电子邮件地址域中的mxlogging等)。 它也检查常见的错字女巫是相当有用的。 在这里演示。

 function EmailValidation($email) { $email = htmlspecialchars(stripslashes(strip_tags($email))); //parse unnecessary characters to prevent exploits if (eregi('[az||0-9]@[az||0-9].[az]', $email)) { //checks to make sure the email address is in a valid format $domain = explode( "@", $email ); //get the domain name if (@fsockopen ($domain[1],80,$errno,$errstr,3)) { //if the connection can be established, the email address is probably valid echo "Domain Name is valid "; return true; } else { echo "Con not a email domian"; return false; //if a connection cannot be established return false } return false; //if email address is an invalid format return false } } 
 <?php $email = "someone@exa mple.com"; if(!filter_var($email, FILTER_VALIDATE_EMAIL)) echo "E-mail is not valid"; else echo "E-mail is valid"; ?>