RFC 2183《MIME 的 Content-Disposition 头字段》中文导读
非官方中文导读声明:本页为 IETF RFC 2183《Communicating Presentation Information in Internet Messages: The Content-Disposition Header Field》 的非官方中文技术导读,按原文章节顺序梳理规范要点,并非逐字全文翻译;任何规范性判断均以英文原文为准。英文原文见 rfc-editor.org/rfc/rfc2183.txt。
1. 它解决“怎么呈现”而非“是什么”
MIME 的 Content-Type 头字段回答的是“这段数据是什么类型”(text/plain、image/png……)。但发送方常常还想额外告诉接收方“你应当怎么处置它”:是直接在正文里显示,还是作为附件让用户保存?
RFC 2183 的 Content-Disposition 头字段就承担这个职责。它更新了 RFC 1806,是 MIME 体系里“呈现信息(presentation information)”的标准承载。
2. 处置类型:inline 与 attachment
Content-Disposition 的取值首先是处置类型(disposition type),规范定义两类基本值与扩展值:
inline:建议接收方直接在邮件主体(或相应上下文)内显示该体。若未指定 Content-Disposition,默认按 inline 处理。attachment:建议接收方将其作为独立附件处理(通常提供“保存”而非直接内联显示)。- 扩展类型:以 X- 开头的私有类型;接收方若不认识,按
attachment处理。
Content-Type: image/png Content-Disposition: attachment; filename="diagram.png"
3. 参数集
处置类型后可带若干参数,提供补充的呈现/元数据信息:
| 参数 | 含义 |
|---|---|
| filename | 建议的存储文件名;接收方保存附件时使用。 |
| creation-date | 体的创建时间(RFC 822 日期格式)。 |
| modification-date | 体的最后修改时间。 |
| read-date | 体被读取/访问的时间。 |
| size | 体的原始字节大小(十进制 octet 数),若传输中有编码则指编码前大小。 |
这些参数都是建议性的:接收方实现可以出于安全或策略原因忽略它们(例如忽略 filename 而自行生成名字)。
4. filename 的安全陷阱
filename 参数看似简单,却是最容易出安全问题的地方。规范特别警告接收方实现:不得盲目信任 filename,因为它可能包含:
- 跨平台路径分隔符(
/、\),用于路径遍历攻击; - 指向父目录的
..序列; - 与系统保留名冲突的名字;
- 与已有文件同名的覆盖风险。
因此健壮的实现应当:剥离路径成分只保留基本文件名、对非法字符做净化、避免覆盖既有文件、并在展示给用户前明确标示“该文件名来自发件方、未经核实”。
5. 日期参数的限制
creation-date / modification-date / read-date 三个日期参数,其语义是“建议接收方在保存文件时参考这些时间”,但规范明确:接收方可以忽略它们,且它们的格式必须符合 RFC 822 日期语法。
文档还澄清,这些日期反映的是“体内容本身”的时间,不等同于邮件的 Date 头字段或传输时间,二者可能不同(例如一份 2020 年创建、今天转发的数据文件)。
6. 与 multipart 的配合
Content-Disposition 最常出现在 multipart 消息的各个子体内:例如 multipart/mixed 里,一个子体是正文(inline),另一个子体是附件(attachment)。接收方据此决定“哪些内联、哪些折叠成附件列表”。
对邮件客户端开发者,正确实现 Content-Disposition 是“附件体验”的基础:既要尊重发送方的意图(inline 尽量内联显示),也要在 attachment 时提供安全的保存流程,并防范 filename 注入。
参考:https://www.rfc-editor.org/rfc/rfc2183.txt
