【问题标题】:How to replace/overwrite default header of EmailMultiAlternatives如何替换/覆盖 EmailMultiAlternatives 的默认标头
【发布时间】:2019-10-01 17:36:03
【问题描述】:

环境:Ubuntu 18.10、Python 2.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 上正确显示的内联图像。我将此消息的标头与我的代码生成的消息的标头进行了比较。

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

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

如果我可以将该标题设置为正确的值,那么问题将得到解决。

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

我尝试像这样添加标题,但它不起作用:

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>

如果我无法修改该标题,您是否建议任何替代方案?

【问题讨论】:

    标签: python django email-attachments amazon-ses email-headers


    【解决方案1】:

    如果你查看源代码,你会发现EmailMultiAlternativesEmailMessage 的子类,EmailMessage 本身有一个类属性:

    mixed_subtype = 'mixed'
    

    所以如果你创建自己的子类来覆盖它,你应该得到你需要的:

    class EmailMultiAlternativesRelated(EmailMultiAlternatives):
        mixed_subtype = 'related'
    

    就是这样,现在你只需使用这个新类,它将使用“multipart/related”。

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

    【讨论】:

    • 不可能,我不敢相信事情就这么简单。 :-) 这正是我所需要的! (这里是 Django 初学者。)实际上我没有创建一个新的子类,但我设置了 msg.mixed_subtype = 'related' 并且它完成了工作。但绝对你的回答让我走上了正确的轨道。谢谢一百万!
    • 如果您在代码中发送更多电子邮件,创建子类可以更轻松地重用。但是,是的,直接在实例上设置变量也可以。
    猜你喜欢
    • 1970-01-01
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    • 2015-06-14
    • 1970-01-01
    相关资源
    最近更新 更多