to的msg
参数sendmail
不是消息体,而是整个消息。因此,它必须是有效的 RFC(2)822 消息。
正如文档末尾的注释所说:
通常,您会希望使用电子邮件包的功能来构造电子邮件,然后您可以将其转换为字符串并通过 sendmail() 发送;请参阅电子邮件:示例。
但是,上面的示例显示了如何自己生成简单的消息:
# Add the From: and To: headers at the start!
msg = ("From: %s\r\nTo: %s\r\n\r\n"
% (fromaddr, ", ".join(toaddrs)))
如果您想知道什么构成有效的电子邮件,请参阅RFC 2822(可能还有RFC 822,它被 2822 取代,但有一些有用的不同解释和示例)。但简短的版本是这样的:它是一系列标题行,每行都以 结尾\r\n
,然后是一个空行(意思是\r\n\r\n
),然后是消息正文。
所以,从技术上讲,你的代码甚至不应该工作,因为它只是有一个\n
而不是\r\n
前缀。
更重要的是,您发送的消息根本没有标题。甚至你可能认为你包括的From:
and也不包括在内。To:
正如文档sendmail
所说:
from_addr 和 to_addrs 参数用于构造传输代理使用的消息信封。SMTP 不会以任何方式修改邮件标头。
这可能会或可能不会被各种服务器视为无效(或垃圾邮件)。
同时,末尾额外的换行符是因为所有行都必须以a结尾\r\n
,而SMTP是面向行的协议。如果消息不以换行符结尾,则根本没有办法表明消息已完成。
如果您想了解详细信息,请参阅RFC2821,其中解释了 SMTP 协议。具体来说,请看 2.3.1 邮件对象、2.3.7 行和 4.1.1.4 数据(DATA)。但简短的版本是发送消息需要一个 DATA 命令,该命令必须以 结尾\r\n.\r\n
,并且“这个终止序列的第一个也是结束数据(消息文本)最后一行的那个”。这意味着无法发送不以换行符结尾的消息。
如果你真的想要,可以通过将你的正文封装在 MIME 消息中来解决这个问题;MIME 消息本身当然会以换行符结尾,但这不会影响您封装的正文。有几种方法可以做到这一点 - 但您需要收件人能够处理您发送的任何内容,我猜这些方法都不适用于电子邮件-SMS 网关(更不用说 SMS 接收端点了) )。