Skip to main content

5. Field Definitions (字段定义)

本节定义与缓存相关的 HTTP 字段的语法和语义.

5.1 Age

"Age" 响应头部字段传达发送方对自响应在源服务器生成或成功验证以来经过的时间的估计. Age 值按第 4.2.3 节中的规定计算.

Age = delta-seconds

Age 字段值是非负整数, 表示以秒为单位的时间 (参见第 1.2.2 节).

虽然它被定义为单例头部字段, 但遇到具有基于列表的 Age 字段值的消息的缓存应该 (SHOULD) 使用字段值的第一个成员, 丢弃后续成员.

如果字段值 (在丢弃其他成员后, 如上所述) 无效 (例如, 它包含非负整数以外的内容), 缓存应该 (SHOULD) 忽略该字段.

Age 头部字段的存在意味着响应不是由源服务器为此请求生成或验证的. 然而, 缺少 Age 头部字段并不意味着联系了源服务器.

5.2 Cache-Control

"Cache-Control" 头部字段用于列出请求/响应链上缓存的指令. 缓存指令是单向的, 即请求中存在指令并不意味着响应中存在或复制相同的指令.

有关如何处理在其他地方定义的 Cache-Control 指令的信息, 请参见第 5.2.3 节.

代理 (无论是否实现缓存) 必须 (MUST) 在转发的消息中传递缓存指令, 无论这些指令对该应用程序的意义如何, 因为指令可能适用于请求/响应链上的所有接收方. 无法将指令定向到特定缓存.

缓存指令由令牌标识 (以不区分大小写的方式进行比较), 并具有可选参数, 该参数可以使用令牌和引用字符串语法. 对于下面定义参数的指令, 接收方应该接受两种形式, 即使生成时需要特定形式.

Cache-Control   = #cache-directive

cache-directive = token [ "=" ( token / quoted-string ) ]

对于下面定义的缓存指令, 除非另有说明, 否则不定义 (也不允许) 参数.

5.2.1 Request Directives (请求指令)

本节定义缓存请求指令. 它们是建议性的; 缓存可以 (MAY) 实现它们, 但不是必需的.

5.2.1.1 max-age

参数语法:

delta-seconds (参见第 1.2.2 节)

max-age 请求指令表示客户端更喜欢年龄小于或等于指定秒数的响应. 除非还存在 max-stale 请求指令, 否则客户端不希望接收过期响应.

此指令使用参数语法的令牌形式: 例如, 'max-age=5' 而不是 'max-age="5"'. 发送方禁止 (MUST NOT) 生成引用字符串形式.

5.2.1.2 max-stale

参数语法:

delta-seconds (参见第 1.2.2 节)

max-stale 请求指令表示客户端将接受已超过其新鲜度生命周期的响应. 如果存在值, 则客户端愿意接受超过其新鲜度生命周期不超过指定秒数的响应. 如果没有为 max-stale 分配值, 则客户端将接受任何年龄的过期响应.

此指令使用参数语法的令牌形式: 例如, 'max-stale=10' 而不是 'max-stale="10"'. 发送方禁止 (MUST NOT) 生成引用字符串形式.

5.2.1.3 min-fresh

参数语法:

delta-seconds (参见第 1.2.2 节)

min-fresh 请求指令表示客户端更喜欢其新鲜度生命周期不小于其当前年龄加上指定秒数的响应. 也就是说, 客户端希望响应至少在指定秒数内仍然新鲜.

此指令使用参数语法的令牌形式: 例如, 'min-fresh=20' 而不是 'min-fresh="20"'. 发送方禁止 (MUST NOT) 生成引用字符串形式.

5.2.1.4 no-cache

no-cache 请求指令表示客户端更喜欢在没有在源服务器上成功验证的情况下不使用存储的响应来满足请求.

5.2.1.5 no-store

no-store 请求指令表示缓存禁止 (MUST NOT) 存储此请求或对它的任何响应的任何部分. 此指令适用于私有缓存和共享缓存. 在此上下文中 "MUST NOT store" 意味着缓存禁止 (MUST NOT) 有意将信息存储在非易失性存储中, 并且必须 (MUST) 尽最大努力在转发后尽快从易失性存储中删除信息.

此指令不是确保隐私的可靠或充分机制. 特别是, 恶意或受损的缓存可能无法识别或遵守此指令, 并且通信网络可能容易受到窃听.

请注意, 如果包含此指令的请求从缓存中得到满足, 则 no-store 请求指令不适用于已存储的响应.

5.2.1.6 no-transform

no-transform 请求指令表示客户端要求中间件避免转换内容, 如 [HTTP] 第 7.7 节所定义.

5.2.1.7 only-if-cached

only-if-cached 请求指令表示客户端只希望获得存储的响应. 遵守此请求指令的缓存应该 (SHOULD) 在接收到它时, 使用与请求的其他约束一致的存储响应或 504 (Gateway Timeout) 状态码进行响应.

5.2.2 Response Directives (响应指令)

本节定义缓存响应指令. 缓存必须 (MUST) 遵守本节中定义的 Cache-Control 指令.

5.2.2.1 max-age

参数语法:

delta-seconds (参见第 1.2.2 节)

max-age 响应指令表示在响应的年龄大于指定秒数后, 应将响应视为过期.

此指令使用参数语法的令牌形式: 例如, 'max-age=5' 而不是 'max-age="5"'. 发送方禁止 (MUST NOT) 生成引用字符串形式.

5.2.2.2 must-revalidate

must-revalidate 响应指令表示一旦响应过期, 缓存禁止 (MUST NOT) 重用该响应来满足另一个请求, 直到它已由源服务器成功验证, 如第 4.3 节所定义.

must-revalidate 指令对于支持某些协议特性的可靠操作是必要的. 在所有情况下, 缓存禁止 (MUST NOT) 忽略 must-revalidate 指令; 特别是, 如果缓存断开连接, 缓存必须 (MUST) 生成错误响应而不是重用过期响应. 生成的状态码应该 (SHOULD) 是 504 (Gateway Timeout), 除非另一个错误状态码更适用.

服务器应该仅在验证请求失败可能导致不正确操作 (例如无声失败的金融交易) 时使用 must-revalidate 指令.

must-revalidate 指令还允许共享缓存重用对包含 Authorization 头部字段 (参见 [HTTP] 第 11.6.2 节) 的请求的响应, 但须遵守上述有关重新验证的要求 (第 3.5 节).

5.2.2.3 must-understand

must-understand 响应指令将响应的缓存限制为理解并符合该响应状态码要求的缓存.

包含 must-understand 指令的响应应该 (SHOULD) 还包含 no-store 指令. 当实现 must-understand 指令的缓存接收到包含它的响应时, 如果缓存理解并实现状态码的缓存要求, 则缓存应该 (SHOULD) 忽略 no-store 指令.

5.2.2.4 no-cache

参数语法:

#field-name

无限定形式 (不带参数) 的 no-cache 响应指令表示响应禁止 (MUST NOT) 用于满足任何其他请求, 除非将其转发以进行验证并接收到成功的响应; 参见第 4.3 节.

这允许源服务器防止缓存使用响应来满足请求而不联系它, 即使是已配置为发送过期响应的缓存也是如此.

带有参数的限定形式的 no-cache 响应指令 (列出一个或多个字段名称) 表示如果列出的头部字段从后续响应中排除或后续响应已与源服务器成功重新验证 (更新或删除这些字段), 则缓存可以 (MAY) 使用响应来满足后续请求, 但须遵守对缓存的任何其他限制. 这允许源服务器防止重用响应中的某些头部字段, 同时仍然允许缓存响应的其余部分.

给定的字段名称不限于本规范定义的头部字段集. 字段名称不区分大小写.

此指令使用参数语法的引用字符串形式. 发送方不应该 (SHOULD NOT) 生成令牌形式 (即使对于单条目列表似乎不需要引用).

注意: 指令的限定形式通常由缓存处理, 就好像收到了无限定的 no-cache 指令; 也就是说, 限定形式的特殊处理并未得到广泛实现.

5.2.2.5 no-store

no-store 响应指令表示缓存禁止 (MUST NOT) 存储立即请求或响应的任何部分, 并且禁止 (MUST NOT) 使用响应来满足任何其他请求.

此指令适用于私有缓存和共享缓存. 在此上下文中 "MUST NOT store" 意味着缓存禁止 (MUST NOT) 有意将信息存储在非易失性存储中, 并且必须 (MUST) 尽最大努力在转发后尽快从易失性存储中删除信息.

此指令不是确保隐私的可靠或充分机制. 特别是, 恶意或受损的缓存可能无法识别或遵守此指令, 并且通信网络可能容易受到窃听.

请注意, must-understand 缓存指令在某些情况下会覆盖 no-store; 参见第 5.2.2.3 节.

5.2.2.6 no-transform

no-transform 响应指令表示中间件 (无论是否实现缓存) 禁止 (MUST NOT) 转换内容, 如 [HTTP] 第 7.7 节所定义.

5.2.2.7 private

参数语法:

#field-name

无限定的 private 响应指令表示共享缓存禁止 (MUST NOT) 存储响应 (即, 响应针对单个用户). 它还表示私有缓存可以 (MAY) 存储响应, 但须遵守第 3 节中定义的约束, 即使响应在其他情况下不会被私有缓存启发式缓存.

如果存在限定的 private 响应指令 (带有列出一个或多个字段名称的参数), 则仅列出的头部字段限于单个用户: 如果原始响应中存在列出的头部字段, 共享缓存禁止 (MUST NOT) 存储它们, 但可以 (MAY) 在没有这些头部字段的情况下存储响应消息的其余部分, 但须遵守第 3 节中定义的约束.

给定的字段名称不限于本规范定义的头部字段集. 字段名称不区分大小写.

此指令使用参数语法的引用字符串形式. 发送方不应该 (SHOULD NOT) 生成令牌形式 (即使对于单条目列表似乎不需要引用).

注意: "private" 一词的这种用法仅控制响应可以存储的位置; 它不能确保消息内容的隐私. 此外, 指令的限定形式通常由缓存处理, 就好像收到了无限定的 private 指令; 也就是说, 限定形式的特殊处理并未得到广泛实现.

5.2.2.8 proxy-revalidate

proxy-revalidate 响应指令表示一旦响应过期, 共享缓存禁止 (MUST NOT) 重用该响应来满足另一个请求, 直到它已由源服务器成功验证, 如第 4.3 节所定义. 这类似于 must-revalidate (第 5.2.2.2 节), 只是 proxy-revalidate 不适用于私有缓存.

请注意, proxy-revalidate 本身并不意味着响应是可缓存的. 例如, 它可能与 public 指令 (第 5.2.2.9 节) 结合使用, 允许缓存响应, 同时仅要求共享缓存在过期时重新验证.

5.2.2.9 public

public 响应指令表示即使响应在其他情况下被禁止, 缓存也可以 (MAY) 存储响应, 但须遵守第 3 节中定义的约束. 换句话说, public 明确将响应标记为可缓存. 例如, public 允许共享缓存重用对包含 Authorization 头部字段 (第 3.5 节) 的请求的响应.

请注意, 根据第 3 节, 对于已经可缓存的响应, 无需添加 public 指令.

如果具有 public 指令的响应没有明确的新鲜度信息, 则它是启发式可缓存的 (第 4.2.2 节).

5.2.2.10 s-maxage

参数语法:

delta-seconds (参见第 1.2.2 节)

s-maxage 响应指令表示, 对于共享缓存, 此指令指定的最大年龄会覆盖 max-age 指令或 Expires 头部字段指定的最大年龄.

s-maxage 指令为共享缓存包含 proxy-revalidate 响应指令 (第 5.2.2.8 节) 的语义. 共享缓存禁止 (MUST NOT) 重用具有 s-maxage 的过期响应来满足另一个请求, 直到它已由源服务器成功验证, 如第 4.3 节所定义. 此指令还允许共享缓存重用对包含 Authorization 头部字段的请求的响应, 但须遵守上述有关最大年龄和重新验证的要求 (第 3.5 节).

此指令使用参数语法的令牌形式: 例如, 's-maxage=10' 而不是 's-maxage="10"'. 发送方禁止 (MUST NOT) 生成引用字符串形式.

5.2.3 Extension Directives (扩展指令)

可以通过使用一个或多个扩展缓存指令来扩展 Cache-Control 头部字段. 缓存必须 (MUST) 忽略无法识别的缓存指令.

可以添加信息性扩展 (不需要更改缓存行为的扩展), 而不更改其他指令的语义.

行为扩展旨在通过充当现有缓存指令基础的修饰符来工作. 提供新指令和旧指令, 以便不理解新指令的应用程序将默认为旧指令指定的行为, 而理解新指令的应用程序将识别它为修改与旧指令相关的要求. 通过这种方式, 可以在不破坏已部署缓存的情况下对现有缓存指令进行扩展.

例如, 考虑一个名为 "community" 的假设新响应指令, 它充当 private 指令的修饰符: 除了私有缓存之外, 仅允许由命名社区成员共享的缓存来缓存响应. 希望允许 UCI 社区在其共享缓存中使用原本私有的响应的源服务器可以通过包含以下内容来实现:

Cache-Control: private, community="UCI"

识别这种 community 缓存指令的缓存可以根据该扩展扩大其行为. 不识别 community 缓存指令的缓存将忽略它并遵守 private 指令.

新的扩展指令应该考虑定义:

  • 指令被多次指定意味着什么,

  • 当指令不带参数时, 存在参数意味着什么,

  • 当指令需要参数时, 缺少参数意味着什么, 以及

  • 指令是特定于请求的、特定于响应的, 还是能够在两者中使用.

5.2.4 Cache Directive Registry (缓存指令注册表)

"超文本传输协议 (HTTP) 缓存指令注册表 (Hypertext Transfer Protocol (HTTP) Cache Directive Registry)" 定义了缓存指令的命名空间. 它已创建并现在维护在 https://www.iana.org/assignments/http-cache-directives.

注册必须 (MUST) 包括以下字段:

  • 缓存指令名称

  • 指向规范文本的指针

要添加到此命名空间的值需要 IETF Review (参见 [RFC8126] 第 4.8 节).

5.3 Expires

"Expires" 响应头部字段给出日期/时间, 在此之后响应被视为过期. 有关新鲜度模型的进一步讨论, 请参见第 4.2 节.

Expires 头部字段的存在并不意味着原始资源将在该时间或之前或之后更改或停止存在.

Expires 字段值是 HTTP-date 时间戳, 如 [HTTP] 第 5.6.7 节所定义. 有关特定于缓存的解析要求, 另请参见第 4.2 节.

Expires = HTTP-date

例如:

Expires: Thu, 01 Dec 1994 16:00:00 GMT

缓存接收方必须 (MUST) 将无效的日期格式, 特别是值 "0", 解释为表示过去的时间 (即, "已经过期").

如果响应包含带有 max-age 指令 (第 5.2.2.1 节) 的 Cache-Control 头部字段, 接收方必须 (MUST) 忽略 Expires 头部字段. 同样, 如果响应包含 s-maxage 指令 (第 5.2.2.10 节), 共享缓存接收方必须 (MUST) 忽略 Expires 头部字段. 在这两种情况下, Expires 中的值仅供尚未实现 Cache-Control 头部字段的接收方使用.

没有时钟 (参见 [HTTP] 第 5.6.7 节) 的源服务器禁止 (MUST NOT) 生成 Expires 头部字段, 除非其值表示过去的固定时间 (始终过期) 或其值已由具有时钟的系统与资源关联.

历史上, HTTP 要求 Expires 字段值不超过未来一年. 虽然不再禁止更长的新鲜度生命周期, 但已证明极大的值会导致问题 (例如, 由于使用 32 位整数作为时间值而导致的时钟溢出), 并且许多缓存将更早地驱逐响应.

5.4 Pragma

"Pragma" 请求头部字段是为 HTTP/1.0 缓存定义的, 以便客户端可以指定 "no-cache" 请求 (因为 Cache-Control 直到 HTTP/1.1 才定义).

然而, 现在对 Cache-Control 的支持已经很普遍. 因此, 本规范弃用 Pragma.

注意: 由于从未指定响应中 "Pragma: no-cache" 的含义, 因此它不能为响应中的 "Cache-Control: no-cache" 提供可靠的替代.

5.5 Warning

"Warning" 头部字段用于携带有关消息状态或转换的附加信息, 这些信息可能未反映在状态码中. 本规范废弃了它, 因为它没有被广泛生成或呈现给用户. 它携带的信息可以通过检查其他头部字段 (例如 Age) 来收集.