使用smtplib发送含HTML图片的邮件,Gmail无法显示问题求助
问题描述
使用Python结合smtplib通过Outlook SMTP发送邮件时,HTML内容中用cid引用的内嵌图片,Outlook收件人可正常显示,但所有Gmail收件人无法查看这些图片。
问题代码
import smtplib from email.mime.image import MIMEImage import os from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText s = smtplib.SMTP('smtp-mail.outlook.com',587) s.starttls() s.login('xxxx@hotmail.com', "xxxx") me = 'xxxx PRENUMERATION <xxxxx@hotmail.com>' # 创建消息对象 msg = MIMEMultipart() # 设置消息参数 msg['From'] = me msg['To'] = "xxxx@gmail.com" msg['Subject'] = 'Testing' html = """ <tr> <td class="x_template-container-cell" align="center" style="padding: 0;"> <table width="100%" align="center" cellpadding="0" cellspacing="0" border="0" style="height: auto; background-color: #ffffff;"> <tbody> <tr> <td class="x_menu-box-start" align="left" valign="center" style="padding-left: 20px; padding-right: 30px; padding-bottom: 15px; padding-top: 15px;"> <a href="https://xxxx.nu/" target="_blank" rel="noopener noreferrer" data-auth="NotApplicable" style="text-decoration: none; color: #000001;" data-linkindex="1" > <img data-imagetype="External" src="cid:foodlogfive" width="50" height="50" border="0" alt="HeaderLogo" style="display: block; padding: 0; border: 0; outline: none; text-decoration: none;" /> </a> </td> </tr> </tbody> </table> </td> </tr> """ # 组合消息正文 msg.attach(MIMEText(html, 'html')) fp = open('foodlogfive.png', 'rb') foodlogfive = MIMEImage(fp.read()) fp.close() foodlogfive.add_header('Content-ID', 'foodlogfive') foodlogfive.add_header('Content-Disposition', 'attachment', filename=os.path.basename('foodlogfive.png')) foodlogfive.add_header("Content-Transfer-Encoding", "base64") msg.attach(foodlogfive) # 通过SMTP服务器发送消息 s.send_message(msg)
解决方案
问题根源在于图片的MIME头设置:
- 你当前将图片标记为
attachment(附件),Gmail会优先将其作为附件处理,不会自动在HTML中以内嵌形式渲染;而Outlook对该标记的兼容性更强,因此能正常显示。 - 部分邮件客户端要求
Content-ID必须包含尖括号(<>),否则无法正确识别引用。
修改步骤:
- 将
Content-Disposition改为inline,明确告知客户端这是内嵌资源而非附件 - 给
Content-ID添加尖括号,提升跨客户端兼容性 - 移除手动设置的
Content-Transfer-Encoding(MIMEImage会自动处理该编码)
修改后的图片处理代码片段:
fp = open('foodlogfive.png', 'rb') foodlogfive = MIMEImage(fp.read()) fp.close() # 给Content-ID添加尖括号 foodlogfive.add_header('Content-ID', '<foodlogfive>') # 设置为inline类型 foodlogfive.add_header('Content-Disposition', 'inline', filename=os.path.basename('foodlogfive.png')) # 移除冗余的编码设置 msg.attach(foodlogfive)
注意:HTML中的src="cid:foodlogfive"无需修改,引用cid时不需要尖括号。
如果需要同时让图片作为可下载附件,可添加两份相同的图片资源:一份设为inline用于HTML显示,另一份设为attachment作为附件。
补充说明
- Gmail对内嵌图片的安全策略更严格,必须明确标记为
inline才能在邮件内容中自动显示 - 遵循MIME标准格式(如带尖括号的Content-ID)能大幅提升不同邮件客户端的兼容性
内容的提问来源于stack exchange,提问作者user17226215
相关产品推荐
相关产品推荐

