RFC 2049:MIME 第 5 部分——符合性准则和示例
为什么存在
MIME 规范跨越四个技术 RFC(2045、2046、2047 和 2048)。实施者需要一个明确的答案:"我的软件必须处理什么才能符合 MIME?" RFC 2049 提供了这个答案,以及实施者可以用来验证其解析器的规范测试消息。
没有一份符合性文档,不同的实现将支持不同的 MIME 子集,导致互操作性失败。RFC 2049 设定了底线:每个 MIME 感知系统至少必须处理这些内容类型、编码和结构。
工作原理
RFC 2049 定义了两个符合性级别,每个级别都有具体要求。
发送代理要求
符合 MIME 的发送代理(MUA 或电子邮件库)必须:
-
在每条使用 MIME 功能的消息中始终包含
MIME-Version: 1.0。 -
在正文不是纯 US-ASCII 文本时包含
Content-Type标头。 - 使用有效的 Content-Transfer-Encoding,以确保消息正文可以通过 7 位 SMTP 网关传输(非 ASCII 内容使用 base64 或 quoted-printable)。
- 正确编码标头字段,在主题或发件人显示名称等标头中出现非 ASCII 字符时使用 RFC 2047 编码字。
- 生成有效的多部分边界,不出现在任何包含的正文部分中。
接收代理要求
符合 MIME 的接收代理必须:
-
识别
MIME-Version: 1.0,并将消息视为 MIME 编码。 - 解析 Content-Type 和 Content-Transfer-Encoding 标头,包括所有参数。
- 解码 base64 和 quoted-printable 内容传输编码。
-
处理所有多部分类型 — 至少
multipart/mixed、multipart/alternative、multipart/digest和multipart/parallel。未知的多部分子类型必须视为multipart/mixed。 -
处理
message/rfc822— 显示封装的消息或至少提供保存选项。 -
妥善处理无法识别的内容类型 — 提供将正文部分保存为文件,而不是崩溃或无声丢弃。无法识别的类型应视为
application/octet-stream。 - 解码标头字段中的 RFC 2047 编码字。
-
处理文本类型上的
charset参数,至少支持 US-ASCII 和 ISO-8859-1,理想情况下支持 UTF-8。
健壮性原则
RFC 2049 为 MIME 强化了 Postel 定律:发送时严格,接收时宽松。符合要求的接收器应尽力显示即使略微格式错误的 MIME 消息,而不是完全拒绝它们。
关键技术细节
规范示例
RFC 2049 包含了 MIME 消息的详细示例。以下是包含纯文本和 HTML 的格式正确的 multipart/alternative 消息的模式:
MIME-Version: 1.0 From: sender@example.com To: recipient@example.com Subject: MIME conformance test Content-Type: multipart/alternative; boundary="boundary42" --boundary42 Content-Type: text/plain; charset=us-ascii This is the plain text version. --boundary42 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable <html><body><p>This is the <strong>HTML</strong> version.</p></body></html> --boundary42--
处理未知类型
一个关键的符合性要求:当接收代理遇到它不理解的 Content-Type 时,它必须将其视为 application/octet-stream 并提供保存选项。此规则确保向前兼容性 — 可以定义新的媒体类型而不会破坏现有客户端。
; 客户端遇到的未知类型 Content-Type: application/vnd.custom-format Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="data.custom" ; 符合要求的客户端将其视为 application/octet-stream ; 并向用户提供"另存为"对话框
未知多部分子类型
同样,未知的多部分子类型必须视为 multipart/mixed。这意味着客户端按顺序显示每个部分。例如,multipart/report(在 RFC 3462 中定义)在将其视为混合类型的较早客户端中仍会正确显示。
最小字符集支持
符合要求的实现必须至少支持:
-
US-ASCII— 基准 -
ISO-8859-1— 西欧字符(Latin-1)
实际上,任何现代实现都必须支持 UTF-8。在 2024 年及以后不这样做,即使 1996 年的规范未强制要求,从精神上讲也是符合性失败。
MIME/非 MIME 边界
没有 MIME-Version: 1.0 标头的消息被视为前 MIME 纯 ASCII 文本,无论它们是否碰巧包含 Content-Type 标头。MIME-Version 标头是看门人:没有它,MIME 处理就不会激活。
常见错误
-
在遇到未知 Content-Type 时崩溃。规范明确规定:将未知类型视为
application/octet-stream。抛出未知类型异常的库不符合要求,并且会在注册新媒体类型时破坏。 -
将未知多部分子类型视为错误。它们必须视为
multipart/mixed。一个常见的错误是拒绝或跳过multipart/report、multipart/signed或其他扩展类型。 -
忽略 text/* 类型上的字符集。没有字符集声明的文本内容默认为
US-ASCII。将其显示为 UTF-8 可能适用于 ASCII 内容,但会为旧版 ISO-8859-1 消息产生乱码。 - 从转发的消息中剥离 MIME-Version。转发或重新发送时,必须保留 MIME-Version 标头。没有它,接收客户端可能根本不会处理 MIME 结构。
-
部分 base64/QP 解码。两个解码器都必须处理边界情况:base64 填充、QP 软行换行符(
=\r\n)和尾随空格。不完整的解码器为合法消息产生损坏的输出。 - 不为无法呈现的部分提供保存选项。符合要求的客户端必须让用户保存任何正文部分,即使它无法显示。无声丢弃部分违反规范并丢失数据。
可递送性影响
- 符合要求的 MIME 结构是可递送性的基准。不符合要求的消息 — 缺少 MIME-Version、损坏的多部分边界、不正确的编码 — 是垃圾邮件工具的特征。垃圾邮件过滤器使用 MIME 符合性作为质量信号。
- 同时包含 text/plain 和 text/html。RFC 2049 的示例演示了包含两种格式的 multipart/alternative。这不仅是最佳实践;许多垃圾邮件过滤器会惩罚仅 HTML 的消息。text/plain 部分必须具有有意义的内容,而不仅仅是"在浏览器中查看此电子邮件"。
-
有效的 Content-Transfer-Encoding 可防止损坏。声明
quoted-printable但包含原始 8 位数据的消息将被 7 位 SMTP 网关混淆。这会导致收件人呈现失败,即使消息到达收件箱。 -
正确的字符集声明可防止乱码。为 UTF-8 内容声明
charset=us-ascii会使重音字符无法读取。收件人可能会将消息报告为垃圾邮件,而不是尝试对其进行解码。 - 格式正确的 MIME 可改善跨客户端的呈现。符合 MIME 的消息在 Gmail、Outlook、Apple Mail、Thunderbird 和移动客户端中正确呈现。不符合要求的消息可能在一个客户端中呈现,但在另一个客户端中断开,导致投诉和退订。