邮件主题为什么会乱码:聊聊 RFC 2047 的 Subject 编码

举报
yd_256822737 发表于 2026/10/22 15:50:05 2026/10/22
【摘要】 邮件正文正常、主题却乱码,多半是 Subject 没按 RFC 2047 编码。本文介绍编码字格式、B/Q 两种编码的区别,以及用 Python 标准库正确生成与解析邮件主题的方法和常见坑。

最近在做一个自动发信的小工具时遇到一个问题:邮件正文显示正常,唯独主题里的中文在部分客户端里变成了一串以 =?UTF-8?B? 开头的乱码。其实这不是显示端的故障,而是邮件头编码方式没有处理对。

邮件头为什么不能直接写中文

邮件协议(RFC 5322)规定,邮件头字段只能使用 ASCII 字符。主题(Subject)里要放中文,就必须先编码。RFC 2047 定义了“编码字”(Encoded-Word)格式:

=?字符集?编码方式?编码后文本?=

编码方式有两种:

  • B 编码:Base64,适合较长的非 ASCII 文本;
  • Q 编码:类似 Quoted-Printable,适合以 ASCII 为主、夹杂少量非 ASCII 字符的文本。

例如“测试邮件”用 UTF-8 加 B 编码表示为:

=?UTF-8?B?5rWL6K+V6YKu5Lu2?=

接收端按相反顺序解码,就能还原出原文。

用 Python 正确生成主题

不要手工拼接编码字,直接用标准库:

from email.header import Header
from email.mime.text import MIMEText

msg = MIMEText("正文内容", "plain", "utf-8")
msg["Subject"] = Header("测试邮件", "utf-8")
msg["From"] = "sender@example.com"
msg["To"] = "rcpt@example.com"

Header 类会根据内容自动选择 B 编码,并按长度上限折行,避免长主题被截断或被服务器拒收。

解析收到的主题时用 decode_header:

from email.header import decode_header

parts = decode_header(msg["Subject"])
subject = "".join(
    p.decode(charset or "ascii") if isinstance(p, bytes) else p
    for p, charset in parts
)

几个常见坑

  1. 编码字之间、编码字与普通文本之间的空格在解码时会被忽略,拼接多段主题时要留意。
  2. 编码后的单行长度不能超过 75 个字符,长主题要折行,续行以空格开头。
  3. 主题里不要直接放换行符,否则有邮件头注入风险,发送前应过滤回车和换行。

小结

主题乱码大多是“该编码时没编码”或“解码时没按字符集还原”造成的。用标准库处理编码字,并注意长度与换行,就能避开绝大多数兼容问题。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。