不同的电子邮件客户端选择以multipart/mixed
不同的方式呈现消息。
大多数客户选择内联渲染每个部分(在“多部分”消息中)——按照它们添加到电子邮件中的顺序。但是,如果某个图像在某个text/html
部件中被引用,大多数客户端稍后不会在“内联所有部件”过程中再次显示该图像。
OSX 和 iOS 上的 Apple Mail 是不同的,因为它们将按照包含的顺序显示消息中的每个部分multipart/mixed
,而不管 HTML 和图像之间的任何内部引用。这会导致您的图像在 HTML 中显示一次,然后在自动内联的消息末尾再次显示。
解决方案是将您的 HTML 和图像资产组合成一个related
部分。IE:
from django.core.mail import EmailMultiAlternatives
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# HTML + image container
related = MIMEMultipart("related")
# Add the HTML
html = MIMEText('an image: <img src="cid:some_image"/>', "html")
related.attach(html)
# Add an image
with open("icon.png", "rb") as handle:
image = MIMEImage(handle.read())
image.add_header("Content-ID", "<some_image>")
image.add_header("Content-Disposition", "inline")
related.attach(image)
# top level container, defines plain text version
email = EmailMultiAlternatives(subject="demo", body="plain text body",
from_email="foo@example.com",
to=["bar@example.com"])
# add the HTML version
email.attach(related)
# Indicate that only one of the two types (text vs html) should be rendered
email.mixed_subtype = "alternative"
email.send()