【问题标题】:How to check if an email address exists without sending an email?如何在不发送电子邮件的情况下检查电子邮件地址是否存在?
【发布时间】:2010-10-08 14:34:38
【问题描述】:

我遇到过这个PHP code to check email address using SMTP without sending an email

有没有人尝试过类似的方法或对你有用?您能否判断客户/用户输入的电子邮件是否正确且存在?

【问题讨论】:

标签: php email smtp telnet email-validation


【解决方案1】:

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

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

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

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

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

还有一种称为灰名单的反垃圾邮件技术,它会导致服务器最初拒绝该地址,期望真正的 SMTP 服务器稍后会尝试重新发送。这会打乱验证地址的尝试。

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

【讨论】:

  • 有些服务器甚至会接受该邮件,但随后会向信封发件人发送一条错误消息,特别是如果它是一个拥有许多内部部门并拥有自己的邮件服务器的大型组织。边界服务器甚至可能不知道其中的所有帐户。
  • 那么为什么垃圾邮件发送者不使用这种方法来验证电子邮件地址呢?我的意思是除了很少的服务器支持这些方法这一事实之外。还是他们?
  • @Shehi:实际上垃圾邮件发送者可能使用这种方法,这很难说。但是,由于垃圾邮件发送者可能使用它,几乎所有邮件服务器都禁用 VRFY,因此实际上 VRFY 可能毫无用处。
  • 你能给出一个如何使用 RCPT TO: 的代码示例吗?谢谢
  • 对 VRFY,gmail 回复“发送一些邮件,我会尽力而为”;-)
【解决方案2】:

此处的其他答案讨论了尝试执行此操作的各种问题。我想我会展示你如何尝试这个,以防你想自己学习。

您可以通过 telnet 连接到邮件服务器以询问电子邮件地址是否存在。下面是一个测试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 MX 首选项 = 20,邮件交换器 = STACKOVERFLOW.COM.S9A2.PSMTP.com stackoverflow.com MX 首选项 = 30,邮件交换器 = 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 Section 17538.45 禁止将此系统用于未经请求的电子邮件广告。 你好你好 250 Postini 回击打招呼 来自: 的邮件 250 好的 转至: 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");

【讨论】:

  • 脱帽致敬!我发现的一个问题是,端口 25 是否总是与低优先级 mx 记录一起使用??
  • @DhruvenkumarShah,对不起,我不知道。如果你发现了,请再次评论。
  • 嗨,我只是想用我自己的大学帐户来查找有关 MX 记录的所有信息,但它在 25 岁时不起作用.. 但是在线 verify-email.org 类网站确实有效..他们是怎么做的。如果我发现了,我会告诉你的
  • @DhruvenkumarShah 它提供的邮件交换服务器名称很少。请参阅邮件交换器的答案。因此,如果一个失败,列表中的另一个应该可以工作。
  • 对我真的很有帮助..谢谢先生..我在腻子中试过了,效果很好..谢谢..
【解决方案3】:

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

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

如果用户与其邮箱的交互成本并不高,许多网站实际上会通过发送一个必须发送回发送者的秘密号码来测试邮件是否到达某处(通过访问秘密 URL 或通过电子邮件发回此秘密号码) )。大多数邮件列表都是这样工作的。

【讨论】:

    【解决方案4】:

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

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

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

    【讨论】:

    • (个人经验:我不得不与我的电子邮件提供商来回争论是的,我知道我在做什么,并且是的,我需要关闭灰名单 - 因为来自第三方服务的这些检查失败)
    【解决方案5】:

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

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

    这样做有安全风险.....

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

    【讨论】:

    • 我也在考虑这个:)
    【解决方案6】:

    一些问题:

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

    【讨论】:

    • 关于第三点,只有当你想将它用作中继时才会发生这种情况。我不知道任何需要 SSL 的邮件交换器。如果有人这样做,他们将停止接收来自许多用户的电子邮件。
    • 对不起,我的错误。如果您想使用 gmail 的 SMTP 服务器发送电子邮件,则必须使用 SSL。
    【解决方案7】:

    我可以确认 Joseph 和 Drew 使用RCPT TO: &lt;address_to_check&gt; 的答案。我想在这些答案之上添加一些小附录。

    包罗万象的供应商

    一些邮件提供商实施包罗万象的策略,这意味着*@mydomain.com 将对RCPT TO: 命令返回肯定的结果。但这并不一定意味着邮箱“存在”,如“属于人类”。这里没有什么可以做的,请注意。

    IP 灰名单/黑名单

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

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

    注册表单上的 HTTP 请求

    这是非常特定于提供商的,但您有时可以使用精心设计的 HTTP 请求,并解析这些请求的响应以查看用户名是否已注册此提供商。

    这是我编写的开源库中的相关函数,用于使用 HTTP 请求检查*@yahoo.com 地址:check-if-email-exists。我知道我的代码是 Rust 并且这个线程被标记为 PHP,但同样的想法也适用。

    完整的收件箱

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

    披露

    我运行 [Reacher][1],一个实时电子邮件验证 API。我的代码是用 Rust 编写的,并且是 100% 开源的。如果您想要更强大的解决方案,请查看:

    Github:https://github.com/reacherhq/check-if-email-exists

    通过结合各种技术来跳过障碍,我设法验证了大约 80% 的电子邮件我的客户检查过。

    【讨论】:

    • 您的代码很好,但对于我测试的一些电子邮件,结果不如预期!
    • 如果你没有拼错RCPT(“re-ci-pien-t”的缩写),它会有所帮助。
    【解决方案8】:

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

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

    我个人会检查 DNS MX 记录,如果 MX 记录存在,则发送电子邮件验证。

    【讨论】:

      【解决方案9】:
      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
          }
      }
      

      【讨论】:

      • 80 端口没有意义
      • 我认为这只是检查域名是否存在而不是检查电子邮件本身。
      • 这可能更有用:getmxrr
      【解决方案10】:

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

      我一直在使用open sourced service 对一些项目的电子邮件进行更深入的验证(检查电子邮件地址域上的 mx 记录等),并取得了良好的效果。它还检查常见的拼写错误,这非常有用。演示here.

      【讨论】:

      • 您声称该服务是开源的。能否提供来源链接?
      • 对不起@amaurymartiny 我不能。如果我没记错的话,在撰写本文时 Mailgun 项目是开源的,但在此之后我无法找到任何提供源代码的存储库的链接。
      【解决方案11】:

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

      其实这是两个不同的东西。它可能存在,但可能不正确。

      有时您必须从表面上接受用户输入。否则有很多方法可以打败系统。

      【讨论】:

      • +1 您可以永远在不发送电子邮件并实际获得人工响应(例如单击链接)的情况下确保它是正确的。
      • 您可以在电子邮件正文中保留一个链接(用于图像等)并计算该链接的每次负载。无需等待点击
      【解决方案12】:

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

      【讨论】:

        【解决方案13】:

        我认为你不能,在很多情况下,即使发送电子邮件也会失败。例如。用户侧邮件服务器暂时宕机、邮箱存在但已满无法投递等

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

        【讨论】:

          【解决方案14】:
          <?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";
          
          ?>
          

          【讨论】:

          • 用户要求的是 .Net 解决方案而不是 php。
          猜你喜欢
          • 1970-01-01
          • 2011-12-29
          • 2011-01-22
          • 2016-04-06
          • 2017-09-10
          • 2016-08-20
          • 2012-09-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多