跳到主要内容

4. Header Field Definition (头部字段定义)

Content-Disposition 响应 header field 用于传达有关如何处理响应负载的附加信息, 也可以用于附加其他元数据, 例如在本地保存响应负载时要使用的 filename.

4.1. Grammar (语法)

content-disposition = "Content-Disposition" ":"
disposition-type *( ";" disposition-parm )

disposition-type = "inline" | "attachment" | disp-ext-type
; case-insensitive
disp-ext-type = token

disposition-parm = filename-parm | disp-ext-parm

filename-parm = "filename" "=" value
| "filename*" "=" ext-value

disp-ext-parm = token "=" value
| ext-token "=" ext-value
ext-token = <the characters in token, followed by "*">

在 [RFC2616] 中定义:

token         = `<token, defined in [RFC2616], Section 2.2>`
quoted-string = `<quoted-string, defined in [RFC2616], Section 2.2>`
value = `<value, defined in [RFC2616], Section 3.6>`
; token | quoted-string

在 [RFC5987] 中定义:

ext-value   = `<ext-value, defined in [RFC5987], Section 3.2>`

如果 Content-Disposition header field 值包含同一参数名的多个实例, 则该值无效.

注意, 由于隐含线性空白的规则 ([RFC2616] 第 2.1 节), OPTIONAL 空白可以出现在单词 (token 或 quoted-string) 与分隔字符之间.

此外还需注意, ext-value 使用的格式允许指定自然语言 (例如 "en"); 这对 filename 的用途有限, 并且很可能被接收方忽略.

4.2. Disposition Type (处置类型)

如果 disposition-type 与 "attachment" 匹配 (不区分大小写), 则表示接收方应提示用户在本地保存响应, 而不是按正常方式处理它 (即根据其媒体类型处理).

另一方面, 如果它与 "inline" 匹配 (不区分大小写), 则表示采用默认处理方式. 因此, disposition-type "inline" 只有在附加额外参数时才有用, 例如 filename (见下文).

接收方 SHOULD 像处理 "attachment" 一样处理未知或未处理的 disposition-type (另见 [RFC2183] 第 2.8 节).

4.3. Disposition Parameter: 'Filename' (处置参数: 'Filename')

参数 "filename" 和 "filename*" 以不区分大小写的方式匹配, 它们提供用于构造 filename 的信息, 以便存储消息负载.

根据 disposition-type 的不同, 这些信息可能会立即使用 (在 "attachment" disposition-type 触发的 "save as..." 交互中), 也可能稍后使用 (例如, 当用户决定保存当前显示页面的内容时).

参数 "filename" 和 "filename*" 的唯一区别在于, "filename*" 使用 [RFC5987] 中定义的编码, 从而允许使用 ISO-8859-1 字符集 ([ISO-8859-1]) 中不存在的字符.

许多早于本规范的 user agent 实现不能理解 "filename*" 参数. 因此, 当单个 header field 值中同时出现 "filename" 和 "filename*" 时, 接收方 SHOULD 选择 "filename*" 并忽略 "filename". 这样, 发送方可以同时发送表达能力更强的 "filename*" 参数, 以及作为旧版接收方回退方案的 "filename" 参数, 从而避免为特定 user agent 编写特殊处理逻辑 (示例见第 5 节).

接收方必须只把指定的 filename 当作建议性信息, 因而在提取所需信息时必须非常谨慎. 尤其是:

  • 接收方 MUST NOT 能够写入除其明确有权写入的位置之外的任何位置. 为说明这个问题, 可以考虑能够覆盖知名系统位置 (例如 "/etc/passwd") 所造成的后果. 实现这一点的一种策略是永远不信任 filename 参数中的文件夹名称信息, 例如去除除最后一个路径段之外的所有内容, 只考虑实际 filename (其中 'path segments' 是由路径分隔字符 "\" 和 "/" 分隔的字段值组成部分).

  • 许多平台在文件系统中不使用 Internet Media Types ([RFC2046]) 保存类型信息, 而是依赖 filename 扩展名. 信任服务器提供的文件扩展名可能会在稍后打开已保存文件时引入权限提升风险 (考虑 ".exe"). 因此, 使用文件扩展名确定媒体类型的接收方 MUST 确保所使用的文件扩展名是安全的, 并且最好与接收到的负载的媒体类型匹配.

  • 接收方 SHOULD 去除或替换已知会在用户界面和 filename 中造成混淆的字符序列, 例如控制字符以及前导和尾随空白.

  • 接收方还需要注意在文件系统或 shell 命令中具有特殊含义的名称, 例如 "." 和 "..", "~", "|", 以及设备名称. 接收方 SHOULD 忽略或替换这类名称.

Note: 许多 user agent 在使用 quoted-string 形式时无法正确处理转义字符 "\". 此外, 一些 user agent 会错误地尝试对 "percent" 转义执行反转义 (见 Appendix C.2), 因而可能误解包含百分号字符后跟两个十六进制数字的 filename.

4.4. Disposition Parameter: Extensions (处置参数: 扩展)

为了支持未来扩展, 接收方 SHOULD 忽略无法识别的参数 (另见 [RFC2183] 第 2.8 节).

4.5. Extensibility (可扩展性)

注意, [RFC2183] 第 9 节为 disposition-type 和 disposition-parm 定义了 IANA 注册表. 该注册表由使用 Content-Disposition 的不同协议共享, 例如 MIME 和 HTTP. 因此, 并非所有已注册值在 HTTP 上下文中都有意义.