Base64 在邮件附件中的应用
← 返回博客
Base64 在邮件附件中的应用
· 5 分钟阅读
MIME 标准的历史背景
早期的互联网电子邮件协议(SMTP)是为传输纯 ASCII 文本设计的,每个字节只使用 7 位(值 0–127)。这意味着二进制文件(图片、文档、可执行程序)无法直接通过邮件传输。MIME(Multipurpose Internet Mail Extensions)标准于 1992 年(RFC 1341)提出,引入了 Base64 作为在邮件中安全传输二进制数据的机制。
时至今日,所有主流邮件客户端都遵循 MIME 标准,每当你发送一封包含图片或文件附件的邮件时,这些附件都在幕后被自动 Base64 编码,传输完成后再被解码还原。这一过程对用户完全透明。
MIME 邮件结构解析
一封包含附件的 MIME 邮件由多个"部分"(part)组成,每个部分有自己的头部和内容体。整个邮件是 multipart/mixed 类型,文本正文是一个 text/plain 或 text/html 部分,每个附件是独立的部分,通过 boundary 字符串分隔。
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----=_Part_1234"
------=_Part_1234
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
Hello, please find the attachment.
------=_Part_1234
Content-Type: application/pdf; name="report.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="report.pdf"
JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PC9UeXBlIC9DYXRhbG9nCi9QYWdlcyAy
...(Base64 数据,每76字符换行)...
------=_Part_1234--
Content-Transfer-Encoding 头部
Content-Transfer-Encoding 头部告知邮件客户端这个部分的数据如何编码。常见值包括:7bit(纯 ASCII 文本,每行不超过998字符)、8bit(可以包含非 ASCII 字节,但每行限制依然存在)、quoted-printable(适合大部分是 ASCII 的文本,偶有特殊字符)、base64(适合二进制数据)。
对于二进制文件,始终应使用 base64 编码。MIME Base64 要求每 76 个字符后插入 CRLF(\r\n)换行,这是与其他场景(如 JSON API)中使用 Base64 的重要区别。
用 Python 发送带附件的邮件
import smtplib
import base64
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
def send_email_with_attachment(sender, recipient, subject, body, file_path):
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = recipient
msg['Subject'] = subject
# 添加正文 / Add body
msg.attach(MIMEText(body, 'plain'))
# 添加附件 / Add attachment
with open(file_path, 'rb') as f:
part = MIMEBase('application', 'octet-stream')
part.set_payload(f.read())
# Base64 编码附件 / Base64 encode attachment
encoders.encode_base64(part)
part.add_header(
'Content-Disposition',
f'attachment; filename="{file_path}"'
)
msg.attach(part)
with smtplib.SMTP('smtp.example.com', 587) as server:
server.starttls()
server.login(sender, 'password')
server.sendmail(sender, recipient, msg.as_string())
内嵌图片 vs 附件
在 HTML 邮件中,图片可以以两种方式嵌入:作为附件引用(通过 CID)或直接作为 Base64 Data URI。使用 CID 时,图片作为 inline 附件附在邮件中,HTML 正文通过 cid:unique-id 引用它。这是 Outlook、Apple Mail 等桌面客户端偏好的方式。
直接使用 Base64 Data URI 的方式更简单,但许多主流邮件客户端(特别是 Gmail 和 Outlook Web)会出于安全考虑过滤掉 Data URI 图片。因此,在生产级 HTML 邮件中,应优先使用 CID 内嵌或外部 URL,而非 Data URI。
Base64 对邮件大小的影响
Base64 编码使附件体积增大约 33%,MIME 换行(每76字符一行)会再增加约 1.5% 的开销。因此,一个 1MB 的 PDF 附件,在邮件中实际占用约 1.37MB 的空间。这解释了为什么邮件服务商通常对邮件大小有严格限制(如 Gmail 的 25MB 上限)。
对于大型文件,建议改用云存储链接(如 Google Drive、OneDrive)而非直接附件,这样既避免了 Base64 体积膨胀,也解决了邮件大小限制的问题,同时还允许接收方随时查看最新版本的文件。
调试邮件附件问题
当附件无法正常显示或损坏时,常见原因包括:Base64 数据的换行格式不正确(应为 CRLF,不是仅 LF);Content-Type 头部中的 MIME 类型错误;Base64 数据末尾缺少必要的换行;boundary 字符串在邮件正文中出现(导致结构解析错误)。
调试时,可以使用邮件分析工具(如 MXToolbox 的邮件头分析器)检查邮件结构,或使用 Python 的 email 模块解析原始邮件内容,检查各部分的头部和 Base64 数据完整性。
立即尝试在线工具,无需安装,免费使用。
打开工具 →
立即免费使用相关工具
免费使用 →