考虑以下示例,通过Python 3中的smtplib和电子邮件库发送电子邮件:
import smtplib
from email.message import EmailMessage
# Make the email:
msg = EmailMessage()
msg.set_content("""
Hi,
From foo
from bar
From baz
""")
msg['Subject'] = 'Example'
msg['From'] = "me@example.com"
msg['To'] = "you@example.com"
# Send the message via our own SMTP server.
s = smtplib.SMTP('localhost')
s.send_message(msg)
s.quit()
这将生成一封看起来像这样的电子邮件:
Message-ID: <...>
Date: Thu, 17 Mar 2022 12:01:47 -0700 (PDT)
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
MIME-Version: 1.0
Subject: Example
From: me@example.com
To: you@examole.com
Hi,
>From foo
from bar
From baz
请注意,如果From
位于一行的开头,那么它是如何在电子邮件正文中变为>From
的。如果电子邮件文本中使用了From,我不想把>
放在那里。我怀疑这是为了防止from
被注入到主体中,如果它没有在头部中定义,但在我的情况下它是定义的。
有趣的是,这并不在EmailMessage
本身中:
>>> print(msg)
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
MIME-Version: 1.0
Subject: Example
From: me@example.com
To: you@example.com
Hi,
From foo
from bar
From baz
正文中的nFrom
似乎在方法SMTP(...).send_message
中变成了n>From
,这不是由消息本身中的电子邮件策略引起的。
因此,问题是如何在发送电子邮件时停止将文本主体中的nFrom
替换为n>From
。
我找到了答案,并决定在其他人遇到相同问题时将其记录下来。简而言之,答案是你无能为力
基本上这就是smtplib中发生的情况。SMTP.send_message:
def send_message(self, msg, from_addr=None, to_addrs=None,
mail_options=(), rcpt_options=()):
...
else:
g = email.generator.BytesGenerator(bytesmsg)
g.flatten(msg_copy, linesep='rn')
注意生成器是如何通过将bytesmsg
作为参数来创建的。
然后启动生成器:
def __init__(self, outfp, mangle_from_=None, maxheaderlen=None, *,
policy=None):
...
if mangle_from_ is None:
mangle_from_ = True if policy is None else policy.mangle_from_
self._fp = outfp
self._mangle_from_ = mangle_from_
self.maxheaderlen = maxheaderlen
self.policy = policy
仅传递outfp
(bytesmsg
(。策略为None,因此在smtplib的send_message
方法中,mangle_from_
始终为True
。
在几个方法调用之后,将调用一个执行以下操作的方法:
...
if self._mangle_from_:
payload = fcre.sub('>From ', payload)
self._write_lines(payload)
...
这将在电子邮件的文本内容中的nFrom
前面添加>
。
因此,似乎无法摆脱将正文中的From
替换为>From
。您可以自己对方法进行子类化,复制代码并修复策略,但这并不干净。