You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3中Gmail SMTP邮件References头设置与IMAP读取异常问题

解决Python SMTP发送邮件时References头乱码问题

问题场景

使用Python 3.8的smtplib和email.message.EmailMessage发送Gmail邮件时,设置References头后,邮件发送无报错,Gmail原始邮件显示正常,但用imaplib的email.message_from_bytes读取时,References头出现大量QP编码的乱码(如=?utf-8?q?=22=3CBN8PR17...),而Message-ID和In-Reply-To显示正常。

原始设置代码:

reference_ids = [
    '<BN8PR17MB27372595A957D7912CEE184FBF6F9@BN8PR17MB2737.namprd17.prod.outlook.com>',
    '<CAM9Ku=FZ5RGMvw3VzNrZz+DA78zyq2Am8fz9JNLmjUQ9ZEXpDQ@mail.gmail.com>',
    '<BN8PR17MB27371C71A65834531DF028BBBF6F9@BN8PR17MB2737.namprd17.prod.outlook.com>',
    '<CAM9Ku=E1wmpj=AMRhsh-Sk1RHqmK_x-J5ey8szVehefYQvn13w@mail.gmail.com>']
in_reply_to = reference_ids[0]

smtp = smtplib.SMTP_SSL(es.smtp_server)
smtp.login(es.username, es.password)
msg = email.message.EmailMessage()
if (reference_ids is not None):
    msg.add_header('In-Reply-To', in_reply_to)
    msg.add_header('References', (' ').join(reference_ids))
msg['Subject'] = request.vars.subject
msg['From'] = es.email
msg['To'] = request.vars.to
msg['CC'] = request.vars.cc
msg['BCC'] = request.vars.bcc
msg.set_content(request.vars.message)
smtp.send_message(msg)
smtp.quit()

读取到的异常References头内容:

References: =?utf-8?q?=22=3CBN8PR17MB27372595A957D7912CEE184FBF6F9=40BN8PR17?=
 =?utf-8?q?MB2737=2Enamprd17=2Eprod=2Eoutlook=2Ecom=3E?=
 <CAM9Ku=FZ5RGMvw3VzNrZz+DA78zyq2Am8fz9JNLmjUQ9ZEXpDQ@mail.gmail.com>
 =?utf-8?q?=3CBN8PR17MB27371C71A65834531DF028BBBF6F9=40BN8PR17MB2737=2Enampr?=
 =?utf-8?q?d17=2Eprod=2Eoutlook=2Ecom=3E_=3CBN8PR17MB27377F609B669D0E72638D6?=
 =?utf-8?q?9BF6F9=40BN8PR17MB2737=2Enamprd17=2Eprod=2Eoutlook=2Ecom=3E?=
 <CAM9Ku=E1wmpj=AMRhsh-Sk1RHqmK_x-J5ey8szVehefYQvn13w@mail.gmail.com>

问题原因

EmailMessage.add_header()方法默认会将内容视为非结构化文本,对其中的特殊字符或过长内容进行QP(Quoted-Printable)编码,但References和In-Reply-To属于结构化邮件头,由标准格式的Message-ID组成,不需要编码。使用add_header会错误触发编码逻辑,导致后续读取时出现乱码。

解决方案

直接通过字典赋值方式设置这些结构化头,而非调用add_header方法,EmailMessage会自动按照邮件标准处理结构化头的格式,避免不必要的编码:

修改后的核心代码:

if reference_ids:
    msg['In-Reply-To'] = in_reply_to
    msg['References'] = ' '.join(reference_ids)

读取时的注意事项

读取邮件时,使用email.policy.default策略替代默认的兼容策略,确保正确解码结构化头:

import imaplib
import email

# 连接IMAP服务器并获取邮件字节流(省略连接逻辑)
...
msg = email.message_from_bytes(email_bytes, policy=email.policy.default)
# 获取正确的References内容
references = msg.get('References', '')

这种方式会自动处理编码后的头内容,直接返回原始的Message-ID列表字符串,不会显示乱码。

内容的提问来源于stack exchange,提问作者lucas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 14:05:47