如何在不发送电子邮件的情况下检查电子邮件地址是否存在?

How to check if an email address exists without sending an email?

提问人:php-guy 提问时间:2/19/2009 最后编辑:SagarPPanchalphp-guy 更新时间:6/9/2023 访问量:261829

问:

我遇到了这个PHP代码,可以在不发送电子邮件的情况下使用SMTP检查电子邮件地址

有没有人尝试过类似的东西,或者它对你有用吗?你能判断客户/用户输入的电子邮件是否正确并存在吗?

PHP SMTP Telnet 电子邮件验证

评论

0赞 sleske 7/24/2012
类似问题:我可以使用 .net 检查电子邮件地址是否存在吗?
3赞 Piccolo 3/14/2013
只是想知道,为什么它有Telnet标签?
2赞 Dan 6/10/2014
有一个PHP库可以做到这一点:github.com/kickboxio/kickbox-php
0赞 Ashit Vora 3/7/2016
Kickbox不是免费的。此 API 只是连接到其服务的包装器。

答:

6赞 l_39217_l 2/19/2009 #1

没有。。。。。某些服务器可能不检查“rcpt to:”

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

这样做会带来安全风险.....

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

评论

0赞 Janaka R Rajapaksha 6/13/2014
我也在想这个问题:)
10赞 kmkaplan 2/19/2009 #2

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

话虽如此,那里描述的方法非常有效。它在 ZoneCheck 的生产代码中使用,只不过它使用 RSET 而不是 QUIT。

在用户与其邮箱的交互成本并不高的情况下,许多站点实际上通过发送一个必须发送回发射器的秘密号码(通过转到秘密 URL 或通过电子邮件发回此秘密号码)来测试邮件是否到达某个地方。大多数邮件列表都是这样工作的。

5赞 Graeme Perrow 2/19/2009 #3

一些问题:

  1. 我敢肯定,如果您提供给它们的地址不存在,某些SMTP服务器会立即通知您,但有些则不会作为隐私措施。他们只会接受你给他们的任何地址,而默默地忽略那些不存在的地址。
  2. 正如文章所说,如果您经常使用某些服务器这样做,他们会将您列入黑名单。
  3. 对于某些SMTP服务器(如gmail),您需要使用SSL才能执行任何操作。 仅当使用 gmail 的 SMTP 服务器发送电子邮件时才如此。

评论

0赞 kmkaplan 2/19/2009
关于第三点,这只有在您想将其用作中继时才会发生。我不知道有任何需要SSL的邮件交换器。如果有人这样做,他们将停止接收来自许多用户的电子邮件。
0赞 Graeme Perrow 2/19/2009
对不起,我的错误。如果您想使用 gmail 的 SMTP 服务器发送电子邮件,则必须使用 SSL。
2赞 Learning 2/19/2009 #4

“你能判断客户/用户输入的电子邮件是否正确并存在吗?”

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

有时,您必须从表面上获取用户输入。否则,有很多方法可以击败系统。

评论

3赞 Daniel Daranas 6/22/2009
+1 如果不发送电子邮件并实际获得人工回复(例如单击链接),您永远无法确定它是否正确。
0赞 Janaka R Rajapaksha 6/13/2014
您可以在电子邮件正文中保留一个链接(用于图像等),并计算该链接的每次加载。无需等待点击
2赞 Austin Salonen 2/19/2009 #5

假设它是用户的地址,某些邮件服务器确实允许 SMTP VRFY 命令根据其邮箱实际验证电子邮件地址。大多数主要网站不会为您提供太多信息;Gmail的回复是“如果你尝试邮寄它,我们会尝试交付它”或类似的东西。

1赞 PhiLho 2/19/2009 #6

我认为你不能,在很多情况下,即使发送电子邮件也可能失败。例如。用户端的邮件服务器暂时关闭,邮箱存在但已满,因此无法传递邮件等。

这可能就是为什么这么多网站在用户确认他们已收到确认电子邮件后验证注册的原因。

3赞 Astra 2/19/2009 #7

您所能做的就是搜索 DNS 并确保电子邮件地址中的域具有 MX 记录,除此之外,没有可靠的方法来处理此问题。

某些服务器可能使用与 SMTP 服务器通信的 rcpt-to 方法,但这完全取决于服务器的配置。另一个问题可能是过载的服务器可能会返回一个 550 代码,说用户未知,但这是一个临时错误,有一个永久错误(我认为是 451?)可以返回。这完全取决于服务器的配置。

我个人会检查 DNS MX 记录,然后发送电子邮件验证 MX 记录是否存在。

107赞 Joseph Tary 2/20/2009 #8

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

  1. 您可以连接到服务器,然后发出命令。很少有服务器支持此命令,但它正是为此目的而设计的。如果服务器使用 2.0.0 DSN 进行响应,则该用户存在。VRFY

    VRFY user
    
  2. 您可以发出 ,然后查看邮件是否被拒绝。RCPT

    MAIL FROM:<>
    RCPT TO:<user@domain>
    

如果用户不存在,你将获得 5.1.1 DSN。但是,仅仅因为电子邮件未被拒绝,并不意味着用户存在。某些服务器会以静默方式丢弃这样的请求,以防止枚举其用户。其他服务器无法验证用户,无论如何都必须接受消息。

还有一种称为灰名单的反垃圾邮件技术,它会导致服务器最初拒绝该地址,期望真正的 SMTP 服务器会在一段时间后尝试重新传递。这将扰乱验证地址的尝试。

老实说,如果您尝试验证地址,最好的方法是使用简单的正则表达式来阻止明显无效的地址,然后发送一封带有链接的实际电子邮件,该链接将验证电子邮件是否已收到。这也确保了他们用户输入了他们的实际电子邮件,而不是碰巧属于其他人的轻微拼写错误。

评论

12赞 David Mårtensson 2/28/2011
有些服务器甚至会接受邮件,但稍后会向信封发件人发送错误邮件,特别是如果它是一个大型组织,有许多内部部门和自己的邮件服务器。边界服务器甚至可能不知道其中的所有帐户。
4赞 Gelmir 3/1/2011
那么为什么垃圾邮件发送者不使用这种方法来验证电子邮件添加者呢?我的意思是,撇开很少有服务器支持这些方法的事实不谈。还是他们?
9赞 sleske 7/24/2012
@Shehi:实际上垃圾邮件发送者可能会使用这种方法,这很难说。但是,由于垃圾邮件发送者可能会使用它,因此几乎所有邮件服务器都禁用了 VRFY,因此在实践中 VRFY 可能毫无用处。
2赞 Papa De Beau 3/22/2013
您能否举一个代码示例来说明如何使用 RCPT TO:<user@domain> ?谢谢
6赞 Armel Larcier 6/26/2015
对于VRFY,gmail回复“发送一些邮件,我会尽力而为”;-)
56赞 Drew Noakes 12/19/2010 #9

这里的其他答案讨论了尝试这样做的各种问题。我想我会展示你如何尝试这个,以防你想通过自己动手来学习。

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

C:\>nslookup -q=mx stackoverflow.com
Non-authoritative answer:
stackoverflow.com       MX preference = 40, mail exchanger = STACKOVERFLOW.COM.S9B2.PSMTP.com
stackoverflow.com       MX preference = 10, mail exchanger = STACKOVERFLOW.COM.S9A1.PSMTP.com
stackoverflow.com       MX preference = 20, mail exchanger = STACKOVERFLOW.COM.S9A2.PSMTP.com
stackoverflow.com       MX preference = 30, mail exchanger = STACKOVERFLOW.COM.S9B1.PSMTP.com

C:\>telnet STACKOVERFLOW.COM.S9A1.PSMTP.com 25
220 Postini ESMTP 213 y6_35_0c4 ready.  CA Business and Professions Code Section 17538.45 forbids use of this system for unsolicited electronic mail advertisements.

helo hi
250 Postini says hello back

mail from: <[email protected]>
250 Ok

rcpt to: <[email protected]>
550-5.1.1 The email account that you tried to reach does not exist. Please try
550-5.1.1 double-checking the recipient's email address for typos or
550-5.1.1 unnecessary spaces. Learn more at
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: <[email protected]>\r\n");
fwrite($smtp_server, "rcpt to: <[email protected]>\r\n");

评论

0赞 Dhruvenkumar Shah 12/4/2012
脱帽致敬!我发现的一个问题是,端口 25 是否始终适用于低优先级 mx 记录?
0赞 Drew Noakes 12/4/2012
@DhruvenkumarShah,对不起,我不知道。如果您发现,请再次评论。
0赞 Dhruvenkumar Shah 12/6/2012
嗨,我只是想用我自己的大学帐户来了解所有关于 MX 记录的信息,但它在 25 小时内不起作用。但是在线 verify-email.org 类型的网站确实有效。他们是如何做到的......如果我发现它,我会让你知道的
1赞 Janaka R Rajapaksha 6/13/2014
@DhruvenkumarShah它提供的邮件交换服务器名称很少。请参阅邮件交换器的答案。因此,如果一个失败,列表中的其他应该可以工作。
0赞 Mohammed Sufian 9/26/2014
真的非常帮助我。谢谢你,先生。。我在腻子中尝试过,效果像吊饰一样。谢谢。。
8赞 Piskvor left the building 5/21/2011 #10

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

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

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

评论

0赞 Piskvor left the building 5/21/2011
(个人经验:我不得不与我的电子邮件提供商来回争论,是的,我知道我在做什么,是的,我需要关闭灰名单 - 因为来自第三方服务的这些检查失败了
3赞 Sachin 2/11/2014 #11
function EmailValidation($email)
{
    $email = htmlspecialchars(stripslashes(strip_tags($email))); //parse unnecessary characters to prevent exploits
    if (eregi('[a-z||0-9]@[a-z||0-9].[a-z]', $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
    }
}

评论

1赞 jrosell 9/29/2015
端口 80 没有意义
6赞 The Angry Saxon 5/10/2016
我认为这只是检查域名是否存在,而不是检查电子邮件本身。
1赞 jchook 3/26/2018
这可能更有用:getmxrr
0赞 Sebi2020 10/21/2022
并非每个域背后都有 Web 服务器......
-12赞 user4314333 12/2/2014 #12
<?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";

?>

评论

0赞 10/19/2017
用户要求的是 .Net 解决方案,而不是 php。
3赞 Henkealg 6/16/2016 #13

虽然这个问题有点老了,但此服务提示可能会帮助用户搜索类似的解决方案,在发送之前检查语法验证之外的电子邮件地址。

我一直在使用这个开源服务对电子邮件进行更深入的验证(检查电子邮件地址域上的 mx 记录等),以取得一些良好的结果。它还检查常见的错别字女巫非常有用。演示在这里

评论

0赞 jeanpaul62 6/14/2020
您声称此服务是开源的。你能提供一个来源的链接吗?
0赞 Henkealg 6/14/2020
对不起@amaurymartiny我不能。在撰写本文时,如果我没记错的话,Mailgun 项目是开源的,但在此之后我找不到指向任何提供源代码的存储库的链接。
7赞 jeanpaul62 6/14/2020 #14

我可以确认约瑟夫和德鲁的答案。我想在这些答案的基础上添加一些小附录。RCPT TO: <address_to_check>

包罗万象的提供程序

某些邮件提供商实施了 catch-all 策略,这意味着该策略将返回 positive。但这并不一定意味着邮箱“存在”,如“属于人类”。这里无能为力,只是要注意。*@mydomain.comRCPT TO:

IP 灰名单/黑名单

灰名单:来自未知 IP 的第一个连接被阻止。解决方案:重试至少 2 次。

黑名单:如果您从同一 IP 发送的请求过多,则该 IP 将被阻止。解决方案:使用 IP 轮换。

注册表单上的 HTTP 请求

这是非常特定于提供程序的,但有时您可以使用精心设计的 HTTP 请求,并解析这些请求的响应,以查看用户名是否已经注册了此提供程序。密码恢复页面上的无头浏览器自动化也可以解决问题。

完整的收件箱

这可能是一种极端情况,但当用户的收件箱已满时,将返回一条错误消息,指出收件箱已满。这意味着该帐户确实存在!RCTP TO:5.1.1 DSN

评论

0赞 Chau Giang 5/15/2021
您的代码很好,但是对于我测试的一些电子邮件,结果与预期不符!
0赞 tripleee 5/23/2021
如果你不拼写错误(“re-ci-pien-t”的缩写),它会有所帮助。RCPT
0赞 Denis Petrov 5/21/2022 #15

您有许多简单的在线工具,例如 https://mail7.net

此服务会检查电子邮件地址格式,然后确保域名有效并提取 MX 记录。 因此,在 90% 中,您可以确定它是否有效。90%,因为某些邮件服务器不参与该过程。