← 返回博客

Base64 在邮件附件中的应用

2026-04-09 · 5 分钟阅读

← 返回博客

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/plaintext/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 数据完整性。

立即尝试在线工具,无需安装,免费使用。

打开工具 →

立即免费使用相关工具

免费使用 →