如何对 MIME 消息中 Content-Disposition 标头的文件名参数值进行编码?

Posted

技术标签:

【中文标题】如何对 MIME 消息中 Content-Disposition 标头的文件名参数值进行编码?【英文标题】:How to encode the filename parameter value of the Content-Disposition header in MIME message? 【发布时间】:2019-01-14 02:22:32 【问题描述】:

通过检查一些电子邮件的来源,我发现许多电子邮件使用“编码字”(RFC 2047)格式对文件名参数值进行编码。但是,根据 RFC 2047,此编码方法不应用于标头参数值。而参数值,比如Content-Disposition头中的filename参数,应该使用RFC 2231建议的编码方式。

因此,我的问题是为什么这么多电子邮件不符合 RFC 标准。使用 RFC 2047 格式对标头参数值进行编码是否正确?所有的邮件代理都能正确解析这些邮件吗?

【问题讨论】:

【参考方案1】:

可悲的事实是,许多流行的电子邮件客户端都违反了相关的 RFC。

确实,正如您所猜测的那样,MIME 正文部分中的文件名应该使用 RFC2231,但在野外的许多实现都使用 RFC2047 或许多其他非正式的、临时的,或者最坏的情况是无法确定的文件名编码。

至于“为什么”,我真的不认为这是可以回答的。从根本上说,我认为我们最好的办法就是在某种程度上猜测这是一个错误。

常见且易于识别的错误编码似乎在流行客户端之间相当透明地工作;但根据定义,不遵守规范将无法保证接收者可以正确猜测其意图。

作为参考,这是一个模型消息,应该希望通过验证 (-:

From: me <tripleee@example.org>
To: =?utf-8?B?G=C3=B6del?= <goedel@example.net>
Subject: File name and recipient are identical,
  but encoded differently
Mime-Version: 1.0
Content-type: application/octet-stream;
  name*=UTF-8''G%C3%B6del
Content-disposition: attachment;
  filename*=UTF-8''G%C3%B6del
Content-transfer-encoding: base64

R8O2ZGVsCg==

作为记录,Content-Type: 标头的 name 参数被 Content-Disposition: 标头的 filename 参数取代,但许多实现仍然保守地指定两者,以防某些客户端仍然无法理解 @ 987654326@

【讨论】:

好伤心...实际上,我用 Python 电子邮件模块构建了一些电子邮件,它符合 RFC 2231,并将这些电子邮件发送给多个收件人。一些收件人告诉我,我电子邮件中的 Excel 附件变成了“.dat”文件,他们无法打开附件文件。我怀疑这是因为 Python 电子邮件对文件名参数值使用 RFC 2231 样式编码方法,并且某些客户端无法正确解析 RFC 2231 编码。我不确定。我在网上没有找到任何解决此问题的方法。 如果没有这些电子邮件的样本和有关他们使用的客户端的信息,这很难分析或验证。我推测问题出在其他地方。

以上是关于如何对 MIME 消息中 Content-Disposition 标头的文件名参数值进行编码?的主要内容,如果未能解决你的问题,请参考以下文章

在 MIME 多部分消息中显式指定边界?

如何在 C# 中将非 mime 消息转换为 mime 邮件消息

MIME消息结构解析与分析

如何在 SMTP 的多部分 MIME 消息中使用 8 位编码?

Python:如何在注意图形结构的同时迭代 MIME 消息树?

如何编写多部分 MIME 混合消息以在 Outlook 中正确显示