Python smtplib.sendmail Mime Multipart 正文未在 iPhone 上显示

Posted

技术标签:

【中文标题】Python smtplib.sendmail Mime Multipart 正文未在 iPhone 上显示【英文标题】:Python smtplib.sendmail Mime Multipart body doesn't shown on iPhone 【发布时间】:2014-06-17 08:07:23 【问题描述】:

这是我的代码:

FROM = ''
TO = ''
SMTPSERVER = ''
MYEMAILPASSWORD = ""

import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.mime.base import MIMEBase
from email import encoders


def physicallySend(listOfAttachments):
    msg = MIMEMultipart('alternative')
    msg['Subject'] = "Testing"
    msg['From'] = FROM
    msg['To'] = TO

    textPart = MIMEText("Hello. I should be able to see this body.", 'plain')
    msg.attach(textPart)
    for attachmentFilename in listOfAttachments:
        fp = open(attachmentFilename, 'rb')
        file1 = MIMEBase('application','csv')
        file1.set_payload(fp.read())
        fp.close()
        encoders.encode_base64(file1)
        file1.add_header('Content-Disposition','attachment;filename=%s' % attachmentFilename)
        msg.attach(file1)

    server = smtplib.SMTP(SMTPSERVER)
    server.ehlo()
    server.starttls()
    server.login(FROM, MYEMAILPASSWORD)
    server.sendmail(FROM, to, msg.as_string())
    server.quit()
    return True


physicallySend(["testfile.csv"])

虽然我可以在 Gmail 和 Outlook 上很好地看到正文,但在我的 iPhone (6.1.3) 上我只能看到附件,而不是正文。

【问题讨论】:

我遇到了完全相同的问题,除了我附加的是图像而不是 csv 文件。我注意到,如果我只是不包含图像/为其添加标题,则正文显示得很好。让我知道您是否能够解决此问题。谢谢! 【参考方案1】:

我在这条评论中找到了我的解决方案:How do I send attachments using SMTP?

我的第一行应该是

msg = MIMEMultipart('mixed')

而不是“替代”。

【讨论】:

【参考方案2】:

对于寻求问题完整解决方案的人,将在所有电子邮件客户端(包括 iOS 默认电子邮件应用程序)上按预期工作

何时使用multipart/mixed

来自 RFC

multipart 的主要子类型“mixed”适用于身体各部分独立并按顺序显示的情况。任何实现无法识别的多部分子类型都应被视为“混合”子类型。

所以当消息的所有部分(text/htmltext/plainimage/png 等)都同样重要并且都应该显示给用户时,应该使用 multipart/mixed 类型

这意味着,如果您将 text/html 附加到消息中,并且将 text/plain 作为 html 的后备,则它们将一个接一个地显示给用户,这没有任何意义

何时使用multipart/alternative

来自 RFC

特别是,每个部分都是相同信息的“替代”版本。用户代理应该认识到各个部分的内容是可以互换的。用户代理应该根据用户的环境和偏好选择“最佳”类型,或者为用户提供可用的替代方案。一般来说,选择最佳类型意味着只显示可以显示的 LAST 部分。例如,这可以用于以花哨的文本格式发送邮件,以便可以轻松地显示在任何地方

这意味着您附加到multipart/alternative 消息的任何内容都可以被视为相同的值,但形式不同。

为什么这很重要?

如果在文本部分之后,您将图像(image/pngimage/jpeg)附加到multipart/alternative 消息,它可以被视为与消息本身同等重要,因此用户将看到的唯一内容是图片 - 没有 text/htmltext/plain 部分。 这对于现在的大多数客户来说并非如此 - 他们足够聪明,可以理解您的意思,但 仍然这样做的是 iOS 默认邮件应用程序 -您不想让这些用户感到困惑。

那么正确的做法是什么?

在解释之后这将变得更有意义

# keeps the textual and attachment parts separately
root_msg = MIMEMultipart('mixed')  

root_msg['Subject'] = email.subject
root_msg['From'] = self._format_from_header()
root_msg['To'] = self._format_addrs(recipients=email.recipients)

alter_msg = MIMEMultipart('alternative')

plain_text = MIMEText('some text', 'plain', 'UTF-8')
html = MIMEText('<strong>some text</strong>', 'html')  

alter_msg.attach(plain_text)
alter_msg.attach(html)

# now the alternative message (textual)
# is just a part of the root mixed message
root_msg.attach(alter_msg)

img_path = '...'
filename = os.path.basename(img_path)
with open(img_path, 'rb') as f:
    attachment = MIMEImage(f.read(), filename=filename)          
    attachment.add_header('Content-Disposition', 'attachment', filename=filename)
    # now the images (attachments) will be shown alongside 
    # either plain or html message and not instead of them
    root_msg.attach(attachment)

【讨论】:

以上是关于Python smtplib.sendmail Mime Multipart 正文未在 iPhone 上显示的主要内容,如果未能解决你的问题,请参考以下文章

python累计求和,编写一个程序,从键盘输入两个整数m和n,求m和n之间(包括m和n)

python while 循环 if elif else 判断

Python的-m参数

-m选项在python中代表什么?

python 随笔

python实现简单的并行矩阵乘法