php 使用 SMTP 服务器发送密件抄送电子邮件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2750211/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sending BCC emails using a SMTP server?
提问by Alix Axel
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 发送带有密件抄送的电子邮件时,密件抄送地址都不会隐藏 - 我已经阅读了 SMTP 协议的整个 RFC(几年前),我认为我没有遗漏任何内容。
The strange thing is, if I send an email with BCCs using the built-in mail()functioneverything 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()功能发送带有密件抄送的电子邮件,一切正常,但我不知道为什么 - 我想推出自己的电子邮件发件人,但我不明白这一点。
Can someone please shed some light into this dark subject?
有人可以对这个黑暗的主题有所了解吗?
回答by Amry
The BCC addresses are not stripped off at the destination email server. That's not how it works.
密件抄送地址不会在目标电子邮件服务器上剥离。这不是它的工作原理。
How SMTP actually works
SMTP 的实际工作原理
- The sender will send a list of
RCPT TOcommands 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. - 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
DATAcommand, 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. - The BCC address is not shown to the receiver, simply because it's not printed out under the
DATAcommand, not because the destination SMTP server stripped them away. The destination SMTP server will just refer to theRCPT TOfor 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 theRCPT TOcommand list, but the BCC header should notbe printed under theDATAcommand.
- 发送方会向
RCPT TOSMTP 服务器发送一个命令列表,每个接收方的电子邮件地址一个,该命令不区分接收方是普通的 To、CC 或 BCC 类型的接收方。 - 在调用告诉 SMTP 服务器谁是发件人、谁是服务器以及其他所有内容的命令后不久,发件人才会调用该
DATA命令,其中将包含电子邮件的内容 - 由电子邮件标题和正文组成- 电子邮件客户端收到的那个。在这些电子邮件标题中,通常有发件人地址、收件人地址、抄送地址。 - BCC 地址不会显示给接收者,仅仅是因为它没有在
DATA命令下打印出来,而不是因为目标 SMTP 服务器将它们剥离了。目标 SMTP 服务器将仅参考RCPT TO应接收电子邮件内容的电子邮件地址列表。它并不真正关心接收者是否在 To、CC 或 BCC 列表中。
更新(澄清):BCC的电子邮件地址必须在上市RCPT TO命令列表,但BCC头应该不会下进行打印DATA命令。
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已经很久了。:)
回答by EML
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 MAILrequest), a list of recipients (the RCPTrequest), and the data to be transferred (the DATArequest). If you want to send an email to somebody via SMTP, then you have to supply their address in a RCPTrequest, 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 BCCshould be handled. The spec gives 3 ways of handling BCC, and in only one of them is the BCCstripped 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 BCChas gone (from the SMTP DATA), and the SMTP connection instead contains a standard RCPTrequest for the bcc'ed address. So, Thunderbird converts BCCto RCPT, but that's not the only way to do it.
电子邮件的内容 -DATA有效地 - 在RFC2822 中完全单独指定。BCC应该如何处理有很大的自由度。规范给出了 3 种处理方式,BCC其中只有一种是BCC在准备电子邮件时删除的。例如,如果我使用 Thunderbird 作为电子邮件客户端,并将其指向 SMTP 服务器,然后查看线路上的消息,那么我发现 ThunderbirdBCC已经消失(来自 SMTP DATA),而 SMTP 连接反而包含RCPT对bcc'ed 地址的标准请求。因此,Thunderbird 转换BCC为RCPT,但这不是唯一的方法。
Another place to handle BCCis 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 Bcclines in the SMTP DATA, and then constructs an address list from those lines, and then removesthe Bccline. You can persuade Sendmail to keep the Bccif 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 isthe destination MTA, and it gets a Bcc, it will strip it out, contrary to Amry's statement.
另一个需要处理的地方BCC是 MTA - 换句话说,您的邮件客户端指向的任何 SMTP 服务器。Sendmail的,例如,搜索所有的To,Cc和Bcc在SMTP线DATA,然后从构建这些行的地址列表,然后删除该Bcc行。Bcc如果您愿意,您可以说服 Sendmail 保留它。如果 sendmail 不是目标 MTA,则它将通过 SMTP 连接到另一个 MTA,并通过RCPT. 换句话说,如果 sendmail是目标 MTA,并且它得到一个Bcc,它将把它去掉,这与 Amry 的说法相反。
There's also some confusion in the comments. You can specify RCPTaddresses 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 的声明是错误的。

