如何 replace/overwrite 默认 header 的 EmailMultiAlternatives

How to replace/overwrite default header of EmailMultiAlternatives

环境:Ubuntu18.10,Python2.7.15,Django 1.11.16

我正在尝试发送包含内联图像的电子邮件。我有以下代码:

msg = EmailMultiAlternatives(some_subject, some_body, 'from@some-domain.com', ['to@some@domain'])

img_data = open('path/to/image.png', 'rb').read()
img = MIMEImage(img_data)
msg.attach(img)

msg.send()

(我只包含了我认为相关的代码,但我可以根据需要添加更多代码。)

以上正常工作,图像在我测试过的大多数电子邮件客户端(大约 7 个,包括移动、桌面或网络邮件)上正常显示,但有两个例外:Mozilla Thunderbird 60 和一些 macOS本机电子邮件客户端。

在 Thunderbird 上,图像不是内嵌显示的,而是显示在消息的最后。在 macOS 客户端上,图像以内嵌方式显示,但另外它也显示在消息的最后。

我从另一个电子邮件客户端撰写并发送了一封测试邮件,其中包含一张在 Thunderbird 和 macOS 上都能正确显示的内联图像。我将此消息的 header 与我的代码生成的消息的 header 进行了比较。

我注意到错误消息将 'Content-Type' 设置为 'multipart/mixed',而正确显示的消息将相同的 header 设置为 'multipart/related'

我将错误消息保存在一个 eml 文件中,并手动更改了该文件的值 header,然后将消息加载到 Thunderbird 中。消息已正确显示并且图像位于正确的位置。

如果我能把那个header设置成合适的值,问题就解决了。

所以,我的问题是:是否有可能告诉 EmailMultiAlternatives 设置 'Content-Type' : 'multipart/related' 而不是默认值 'multipart/mixed'

我试过像这样添加 header 但它不起作用:

msg = EmailMultiAlternatives(some_subject, some_body, 'from@some-domain.com', ['to@some@domain'], headers={'Content-Type' : 'multipart/related'})

我收到以下错误(我使用 Amazon SES):

400 Bad Request
<ErrorResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
  <Error>
    <Type>Sender</Type>
    <Code>InvalidParameterValue</Code>
    <Message>Duplicate header 'Content-Type'.</Message>
  </Error>
  <RequestId>xxxxxxxxxx</RequestId>
</ErrorResponse>

如果我不能修改那个header,你有什么替代建议吗?

如果你查看源代码,你会看到 EmailMultiAlternativesEmailMessage 的子 class,它本身具有 class 属性:

mixed_subtype = 'mixed'

因此,如果您创建自己的子class 来覆盖它,您应该得到您需要的东西:

class EmailMultiAlternativesRelated(EmailMultiAlternatives):
    mixed_subtype = 'related'

就是这样,现在你只要使用这个新的class,它就会使用"multipart/related"。

_create_attachments() 方法将此子类型传递给 python 的 SafeMIMEMultipart,后者为每个附件创建实际的 headers。)