使用SMTP服务器发送BCC电子邮件?

时间:2022-12-11 18:16:47

I've had this noted down on some of my code for a while:

我有一段时间记下了我的一些代码:

/**
 * Add a BCC.
 *
 * Note that according to the conventions of the SMTP protocol all
 * addresses, including BCC addresses, are included in every email as it
 * is sent over the Internet. The BCC addresses are stripped off blind
 * copy email only at the destination email server.
 *
 * @param string $email
 * @param string $name
 * @return object Email
 */

I don't remember where I got it from (possible source) but that shouldn't be relevant to this question. Basically, whenever I try to send an email with BCCs via SMTP the BCC addresses are not hidden - I've read the whole RFC for the SMTP protocol (a couple years ago) and I don't think I'm missing anything.

我不记得从哪里得到它(可能的来源),但这不应该与这个问题相关。基本上,每当我尝试通过SMTP发送带有BCC的电子邮件时,BCC地址都不会被隐藏 - 我已经阅读了整个RFC的SMTP协议(几年前),我不认为我错过任何东西。

The strange thing is, if I send an email with BCCs using the built-in mail() function everything works just right and I've no idea why - I would like to roll my own email sender but I fail to understand this.

奇怪的是,如果我使用内置的mail()函数发送带有BCC的电子邮件,一切正常,我不知道为什么 - 我想推送自己的电子邮件发件人,但我不明白这一点。

Can someone please shed some light into this dark subject?

有人可以对这个黑暗的主题有所了解吗?

2 个解决方案

#1


34  

The BCC addresses are not stripped off at the destination email server. That's not how it works.

BCC地址不会在目标电子邮件服务器上剥离。这不是它的工作原理。

How SMTP actually works

  • The sender will send a list of RCPT TO commands to the SMTP server, one for each receiver email addresses, and this command does not distinguish whether the receiver is a normal To, CC or BCC type receiver.
  • 发送方将向SMTP服务器发送RCPT TO命令列表,每个接收方电子邮件地址一个,此命令不区分接收方是普通的To,CC还是BCC类型接收方。

  • Soon enough after calling the command that tells the SMTP server who's the sender, who's the server, and everything else, only then the sender will call the DATA command, in which will contain the content of the email - which consist of the email headers and body - the one that are received by email clients. Among these email headers are the usual from address, to address, CC address.
  • 很快,在调用告诉SMTP服务器谁是发件人,谁是服务器以及其他所有的命令之后,发件人才会调用DATA命令,其中包含电子邮件的内容 - 包括电子邮件标题和正文 - 电子邮件客户端收到的正文。在这些电子邮件标题中,通常是从地址到地址,CC地址。

  • The BCC address is not shown to the receiver, simply because it's not printed out under the DATA command, not because the destination SMTP server stripped them away. The destination SMTP server will just refer to the RCPT TO for the list of email addresses that should receive the email content. It does not really care whether the receiver is in the To, CC or BCC list.
    Update (to clarify): BCC email addresses must be listed in the RCPT TO command list, but the BCC header should not be printed under the DATA command.
  • BCC地址不会显示给接收方,只是因为它没有在DATA命令下打印出来,不是因为目标SMTP服务器将它们剥离了。目标SMTP服务器将仅引用RCPT TO以获取应接收电子邮件内容的电子邮件地址列表。它并不关心接收器是否在To,CC或BCC列表中。更新(澄清):BCC电子邮件地址必须列在RCPT TO命令列表中,但不应在DATA命令下打印BCC标题。

Quoting a part of the RFC that I think is relevant to your case:

引用我认为与您的案例相关的RFC的一部分:

Please note that the mail data includes the memo header items such as Date, Subject, To, Cc, From [2].

请注意,邮件数据包括备注标题项,如日期,主题,收件人,抄送,来自[2]。

Rolling out your own email sender

A couple of years ago, I frankly think, is quite a long time back to assume that you still memorize end-to-end of RFC 821. :)

几年前,我坦率地认为,相当长的一段时间,我们假设您仍然记住RFC 821的端到端。:)

#2


14  

Very late, but the accepted answer is essentially wrong.

很晚,但接受的答案本质上是错误的。

First off, SMTP has nothing to do with BCC. SMTP, as a protocol, is concerned only with a return path (the MAIL request), a list of recipients (the RCPT request), and the data to be transferred (the DATA request). If you want to send an email to somebody via SMTP, then you have to supply their address in a RCPT request, period.

首先,SMTP与BCC无关。 SMTP作为协议,仅涉及返回路径(MAIL请求),收件人列表(RCPT请求)和要传输的数据(DATA请求)。如果您想通过SMTP向某人发送电子邮件,则必须在RCPT请求期间提供其地址。

The contents of an email - the DATA, effectively - are specified completely separately, in RFC2822. There's a lot of latitude in how BCC should be handled. The spec gives 3 ways of handling BCC, and in only one of them is the BCC stripped out while preparing the email. If I use Thunderbird as an email client, for example, and point it to an SMTP server, and then look at the message on the line, then I find that the Thunderbird BCC has gone (from the SMTP DATA), and the SMTP connection instead contains a standard RCPT request for the bcc'ed address. So, Thunderbird converts BCC to RCPT, but that's not the only way to do it.

电子邮件的内容 - 有效的 - 在RFC2822中完全单独指定。如何处理BCC有很大的*度。该规范提供了3种处理BCC的方法,其中只有一种方法是在准备电子邮件时剥离了BCC。例如,如果我将Thunderbird用作电子邮件客户端,并将其指向SMTP服务器,然后查看该行上的消息,那么我发现Thunderbird BCC已经消失(来自SMTP DATA),以及SMTP连接而是包含bcc'ed地址的标准RCPT请求。因此,Thunderbird将BCC转换为RCPT,但这不是唯一的方法。

Another place to handle BCC is at the MTA - in other words, whatever SMTP server your mail client is pointed to. Sendmail, for example, searches all of the To, Cc, and Bcc lines in the SMTP DATA, and then constructs an address list from those lines, and then removes the Bcc line. You can persuade Sendmail to keep the Bcc if you want to. If sendmail isn't the destination MTA, then it will connect to another MTA over SMTP, and send the recipient addresses via RCPT. In other words, if sendmail is the destination MTA, and it gets a Bcc, it will strip it out, contrary to Amry's statement.

另一个处理BCC的地方是MTA - 换句话说,就是你的邮件客户端指向的任何SMTP服务器。例如,Sendmail搜索SMTP DATA中的所有To,Cc和Bcc行,然后从这些行构造地址列表,然后删除Bcc行。如果你愿意,你可以说服Sendmail保留密件抄送。如果sendmail不是目标MTA,则它将通过SMTP连接到另一个MTA,并通过RCPT发送收件人地址。换句话说,如果sendmail是目标MTA,并且它获得了密件抄送,它将剥离它,这与Amry的声明相反。

There's also some confusion in the comments. You can specify RCPT addresses to any domain, not just a list of addresses in the same domain. The MTA has to look up the MX records for the destination domains to work out where to send everything. The google.com and yahoo.com statements are wrong.

评论中也存在一些混淆。您可以为任何域指定RCPT地址,而不仅仅是同一域中的地址列表。 MTA必须查找目标域的MX记录,以确定发送所有内容的位置。 google.com和yahoo.com的陈述是错误的。

#1


34  

The BCC addresses are not stripped off at the destination email server. That's not how it works.

BCC地址不会在目标电子邮件服务器上剥离。这不是它的工作原理。

How SMTP actually works

  • The sender will send a list of RCPT TO commands to the SMTP server, one for each receiver email addresses, and this command does not distinguish whether the receiver is a normal To, CC or BCC type receiver.
  • 发送方将向SMTP服务器发送RCPT TO命令列表,每个接收方电子邮件地址一个,此命令不区分接收方是普通的To,CC还是BCC类型接收方。

  • Soon enough after calling the command that tells the SMTP server who's the sender, who's the server, and everything else, only then the sender will call the DATA command, in which will contain the content of the email - which consist of the email headers and body - the one that are received by email clients. Among these email headers are the usual from address, to address, CC address.
  • 很快,在调用告诉SMTP服务器谁是发件人,谁是服务器以及其他所有的命令之后,发件人才会调用DATA命令,其中包含电子邮件的内容 - 包括电子邮件标题和正文 - 电子邮件客户端收到的正文。在这些电子邮件标题中,通常是从地址到地址,CC地址。

  • The BCC address is not shown to the receiver, simply because it's not printed out under the DATA command, not because the destination SMTP server stripped them away. The destination SMTP server will just refer to the RCPT TO for the list of email addresses that should receive the email content. It does not really care whether the receiver is in the To, CC or BCC list.
    Update (to clarify): BCC email addresses must be listed in the RCPT TO command list, but the BCC header should not be printed under the DATA command.
  • BCC地址不会显示给接收方,只是因为它没有在DATA命令下打印出来,不是因为目标SMTP服务器将它们剥离了。目标SMTP服务器将仅引用RCPT TO以获取应接收电子邮件内容的电子邮件地址列表。它并不关心接收器是否在To,CC或BCC列表中。更新(澄清):BCC电子邮件地址必须列在RCPT TO命令列表中,但不应在DATA命令下打印BCC标题。

Quoting a part of the RFC that I think is relevant to your case:

引用我认为与您的案例相关的RFC的一部分:

Please note that the mail data includes the memo header items such as Date, Subject, To, Cc, From [2].

请注意,邮件数据包括备注标题项,如日期,主题,收件人,抄送,来自[2]。

Rolling out your own email sender

A couple of years ago, I frankly think, is quite a long time back to assume that you still memorize end-to-end of RFC 821. :)

几年前,我坦率地认为,相当长的一段时间,我们假设您仍然记住RFC 821的端到端。:)

#2


14  

Very late, but the accepted answer is essentially wrong.

很晚,但接受的答案本质上是错误的。

First off, SMTP has nothing to do with BCC. SMTP, as a protocol, is concerned only with a return path (the MAIL request), a list of recipients (the RCPT request), and the data to be transferred (the DATA request). If you want to send an email to somebody via SMTP, then you have to supply their address in a RCPT request, period.

首先,SMTP与BCC无关。 SMTP作为协议,仅涉及返回路径(MAIL请求),收件人列表(RCPT请求)和要传输的数据(DATA请求)。如果您想通过SMTP向某人发送电子邮件,则必须在RCPT请求期间提供其地址。

The contents of an email - the DATA, effectively - are specified completely separately, in RFC2822. There's a lot of latitude in how BCC should be handled. The spec gives 3 ways of handling BCC, and in only one of them is the BCC stripped out while preparing the email. If I use Thunderbird as an email client, for example, and point it to an SMTP server, and then look at the message on the line, then I find that the Thunderbird BCC has gone (from the SMTP DATA), and the SMTP connection instead contains a standard RCPT request for the bcc'ed address. So, Thunderbird converts BCC to RCPT, but that's not the only way to do it.

电子邮件的内容 - 有效的 - 在RFC2822中完全单独指定。如何处理BCC有很大的*度。该规范提供了3种处理BCC的方法,其中只有一种方法是在准备电子邮件时剥离了BCC。例如,如果我将Thunderbird用作电子邮件客户端,并将其指向SMTP服务器,然后查看该行上的消息,那么我发现Thunderbird BCC已经消失(来自SMTP DATA),以及SMTP连接而是包含bcc'ed地址的标准RCPT请求。因此,Thunderbird将BCC转换为RCPT,但这不是唯一的方法。

Another place to handle BCC is at the MTA - in other words, whatever SMTP server your mail client is pointed to. Sendmail, for example, searches all of the To, Cc, and Bcc lines in the SMTP DATA, and then constructs an address list from those lines, and then removes the Bcc line. You can persuade Sendmail to keep the Bcc if you want to. If sendmail isn't the destination MTA, then it will connect to another MTA over SMTP, and send the recipient addresses via RCPT. In other words, if sendmail is the destination MTA, and it gets a Bcc, it will strip it out, contrary to Amry's statement.

另一个处理BCC的地方是MTA - 换句话说,就是你的邮件客户端指向的任何SMTP服务器。例如,Sendmail搜索SMTP DATA中的所有To,Cc和Bcc行,然后从这些行构造地址列表,然后删除Bcc行。如果你愿意,你可以说服Sendmail保留密件抄送。如果sendmail不是目标MTA,则它将通过SMTP连接到另一个MTA,并通过RCPT发送收件人地址。换句话说,如果sendmail是目标MTA,并且它获得了密件抄送,它将剥离它,这与Amry的声明相反。

There's also some confusion in the comments. You can specify RCPT addresses to any domain, not just a list of addresses in the same domain. The MTA has to look up the MX records for the destination domains to work out where to send everything. The google.com and yahoo.com statements are wrong.

评论中也存在一些混淆。您可以为任何域指定RCPT地址,而不仅仅是同一域中的地址列表。 MTA必须查找目标域的MX记录,以确定发送所有内容的位置。 google.com和yahoo.com的陈述是错误的。