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

发布于 2024-07-14 01:42:05 字数 241 浏览 14 评论 0原文

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

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

I have come across this PHP code to check email address using SMTP without sending an email.

Has anyone tried anything similar or does it work for you? Can you tell if an email customer / user enters is correct & exists?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

北陌 2024-07-21 01:42:05

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

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

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

    邮件来自:<> 
      RCPT 至:<用户@域> 
      

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

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

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

There are two methods you can sometimes use to determine if a recipient actually exists:

  1. You can connect to the server, and issue a VRFY command. Very few servers support this command, but it is intended for exactly this. If the server responds with a 2.0.0 DSN, the user exists.

    VRFY user
    
  2. You can issue a RCPT, and see if the mail is rejected.

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

If the user doesn't exist, you'll get a 5.1.1 DSN. However, just because the email is not rejected, does not mean the user exists. Some server will silently discard requests like this to prevent enumeration of their users. Other servers cannot verify the user and have to accept the message regardless.

There is also an antispam technique called greylisting, which will cause the server to reject the address initially, expecting a real SMTP server would attempt a re-delivery some time later. This will mess up attempts to validate the address.

Honestly, if you're attempting to validate an address the best approach is to use a simple regex to block obviously invalid addresses, and then send an actual email with a link back to your system that will validate the email was received. This also ensures that they user entered their actual email, not a slight typo that happens to belong to somebody else.

川水往事 2024-07-21 01:42:05

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

您可以通过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");

Other answers here discuss the various problems with trying to do this. I thought I'd show how you might try this in case you wanted to learn by doing it yourself.

You can connect to an mail server via telnet to ask whether an email address exists. Here's an example of testing an email address for 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

Lines prefixed with numeric codes are responses from the SMTP server. I added some blank lines to make it more readable.

Many mail servers will not return this information as a means to prevent against email address harvesting by spammers, so you cannot rely on this technique. However you may have some success at cleaning out some obviously bad email addresses by detecting invalid mail servers, or having recipient addresses rejected as above.

Note too that mail servers may blacklist you if you make too many requests of them.


In PHP I believe you can use fsockopen, fwrite and fread to perform the above steps programmatically:

$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");
像极了他 2024-07-21 01:42:05

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

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

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

The general answer is that you can not check if an email address exists event if you send an email to it: it could just go into a black hole.

That being said the method described there is quite effective. It is used in production code in ZoneCheck except that it uses RSET instead of QUIT.

Where user interaction with his mailbox is not overcostly many sites actually test that the mail arrive somewhere by sending a secret number that must be sent back to the emitter (either by going to a secret URL or sending back this secret number by email). Most mailing lists work like that.

北城孤痞 2024-07-21 01:42:05

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

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

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

This will fail (amongst other cases) when the target mailserver uses greylisting.

Greylisting: SMTP server refuses delivery the first time a previously unknown client connects, allows next time(s); this keeps some percentage of spambots out, while allowing legitimate use - as it is expected that a legitimate mail sender will retry, which is what normal mail transfer agents will do.

However, if your code only checks on the server once, a server with greylisting will deny delivery (as your client is connecting for the first time); unless you check again in a little while, you may be incorrectly rejecting valid e-mail addresses.

枫以 2024-07-21 01:42:05

我可以确认 Joseph 和 Drew 的答案,以使用 RCPT TO:。 我想在这些答案的基础上添加一些小附录。

包罗万象的提供商

某些邮件提供商实施包罗万象的策略,这意味着 *@mydomain.com 将向 RCPT TO: 命令返回正值。 但这并不一定意味着邮箱“存在”,如“属于人类”。 这里无能为力,只是要注意。

IP 灰名单/黑名单

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

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

注册表单上的 HTTP 请求

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

收件箱已满

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

I can confirm Joseph's and Drew's answers to use RCPT TO: <address_to_check>. I would like to add some little addenda on top of those answers.

Catch-all providers

Some mail providers implement a catch-all policy, meaning that *@mydomain.com will return positive to the RCPT TO: command. But this doesn't necessarily mean that the mailbox "exists", as in "belongs to a human". Nothing much can be done here, just be aware.

IP Greylisting/Blacklisting

Greylisting: 1st connection from unknown IP is blocked. Solution: retry at least 2 times.

Blacklisting: if you send too many requests from the same IP, this IP is blocked. Solution: use IP rotation.

HTTP requests on sign-up forms

This is very provider-specific, but you sometimes can use well-crafted HTTP requests, and parse the responses of these requests to see if a username already signed up or not with this provider. Headless browser automation on a password recovery page might also do the trick.

Full Inbox

This might be an edge case, but when the user has a full inbox, RCTP TO: will return a 5.1.1 DSN error message saying it's full. This means that the account actually exists!

傲娇萝莉攻 2024-07-21 01:42:05

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

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

这样做存在安全风险.....

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

Not really.....Some server may not check the "rcpt to:"

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

Doing so is security risk.....

If the server do, you can write a bot to discovery every address on the server....

梦纸 2024-07-21 01:42:05

一些问题:

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

Some issues:

  1. I'm sure some SMTP servers will let you know immediately if an address you give them does not exist, but some won't as a privacy measure. They'll just accept whatever addresses you give them and silently ignore the ones that don't exist.
  2. As the article says, if you do this too often with some servers, they will blacklist you.
  3. For some SMTP servers (like gmail), you need to use SSL in order to do anything. This is only true when using gmail's SMTP server to send email.
他夏了夏天 2024-07-21 01:42:05

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

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

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

About all you can do is search DNS and ensure the domain that is in the email address has an MX record, other than that there is no reliable way of dealing with this.

Some servers may work with the rcpt-to method where you talk to the SMTP server, but it depends entirely on the configuration of the server. Another issue may be an overloaded server may return a 550 code saying user is unknown, but this is a temporary error, there is a permanent error (451 i think?) that can be returned. This depends entirely on the configuration of the server.

I personally would check for the DNS MX record, then send an email verification if the MX record exists.

蘑菇王子 2024-07-21 01:42:05

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

Assuming it's the user's address, some mail servers do allow the SMTP VRFY command to actually verify the email address against its mailboxes. Most of the major site won't give you much information; the gmail response is "if you try to mail it, we'll try to deliver it" or something clever like that.

じ违心 2024-07-21 01:42:05
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
    }
}
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
    }
}
稚气少女 2024-07-21 01:42:05

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

我一直在使用这个开源服务来更深入地验证电子邮件(检查 mx 记录)在电子邮件地址域等)的一些项目取得了良好的效果。 它还检查常见的拼写错误,这非常有用。 演示此处

Although this question is a bit old, this service tip might help users searching for a similar solution checking email addresses beyond syntax validation prior to sending.

I have been using this open sourced service for a more in depth validating of emails (checking for mx records on the e-mail address domain etc.) for a few projects with good results. It also checks for common typos witch is quite useful. Demo here.

つ可否回来 2024-07-21 01:42:05

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

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

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

"Can you tell if an email customer / user enters is correct & exists?"

Actually these are two separate things. It might exist but might not be correct.

Sometimes you have to take the user inputs at the face value. There are many ways to defeat the system otherwise.

ぇ气 2024-07-21 01:42:05

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

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

I think you cannot, there are so many scenarios where even sending an e-mail can fail. Eg. mail server on the user side is temporarily down, mailbox exists but is full so message cannot be delivered, etc.

That's probably why so many sites validate a registration after the user confirmed they have received the confirmation e-mail.

情深如许 2024-07-21 01:42:05

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

该服务检查电子邮件地址格式,然后确保域名有效并提取 MX 记录。
所以90%你可以确定它是否有效。 90%是因为一些邮件服务器没有参与这个过程。

You have many simple online tools like https://mail7.net

This service check the email address format, then make sure the domain name is valid and extracts the MX records.
So in 90% you can be sure if it valid. 90% because some mail servers are not involved in the process.

捶死心动 2024-07-21 01:42:05

MailVeri 在 https://github.com/mailveri/mailveri 提供免费 API 访问。

您无需注册帐户即可使用它。

我不确定其背后的技术堆栈。 但它非常适合我的需求。

只需编写简短的代码片段即可调用其 REST API。

curl -X POST https://free.mailveri.com --data-urlencode "[email protected]"
{"token": "4YCYfX3bdfhvCoKALhHyaezm6K4pYYq6", "wait": 5123}

等待5123ms处理,然后得到结果:

curl -X GET https://free.mailveri.com/[email protected]&token=4YCYfX3bdfhvCoKALhHyaezm6K4pYYq6
{"status": "BAD"}

MailVeri provides free API access at https://github.com/mailveri/mailveri.

You don't need to register an account to use it.

I'm not sure about the technical stack behind it. But it works very well for my needs.

Just write short code snippet to call their REST APIs.

curl -X POST https://free.mailveri.com --data-urlencode "[email protected]"
{"token": "4YCYfX3bdfhvCoKALhHyaezm6K4pYYq6", "wait": 5123}

Wait 5123ms for processing, then get result:

curl -X GET https://free.mailveri.com/[email protected]&token=4YCYfX3bdfhvCoKALhHyaezm6K4pYYq6
{"status": "BAD"}
南巷近海 2024-07-21 01:42:05
<?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";

?>
<?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";

?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文