入门指南

加了 immutable 之后,刷新也拿不到新文件:它不改寿命,只让缓存在新鲜期内别问

immutable 不延长 max-age,它只在响应还新鲜时要求客户端跳过条件请求,陈旧之后照常验证;它也不是 RFC 9111 的指令,不认识的缓存会直接忽略。讲清它与 max-age、no-cache、强刷新的边界,为什么只配换名的资源,以及它怎样把一次错误一起钉住。

immutable 只承诺新鲜期内不更新,它不改寿命,也挡不住强刷。

作者
AOPC 编辑部
发布
AOPC 编辑部
发布时间
更新
2026/11/2
核查
已复核
一扇上了锁的仓库门,门边贴着「一年内不换货」的封条,门缝里露出旧版本的箱子
经营者责任与 AI 执行层的关系

先看答案

适合谁
  • 自己发静态站、给资源加 hash 文件名、开了 CDN 的人
  • 改完样式部署成功,用户却说「还是旧的」的人
  • 把 immutable 当成「永久缓存」或「强制不更新」开关的人
你会获得
先确认这个 URL 真的不会变,再谈要不要加 immutable。
发布时间
实质更新
发布
AOPC 编辑部

60 秒结论

一分钟看懂这篇文章

immutable 只承诺新鲜期内不更新,它不改寿命,也挡不住强刷。

人负责

  • 判断哪些资源才配得上 immutable
  • 区分「没更新」与「缓存没问」

AI 负责

  • 读 Cache-Control 里的 max-age 与 immutable
  • 核对响应头是否被中间层改写
  1. 确认资源会换名
  2. 核对新鲜期长度
  3. 检查中间层转发
  4. 按层定位旧副本

直接答案

「样式改完了,部署也成功了。用户说还是旧的,让他刷新一下——还是旧的。」

如果那个 CSS 的响应头是 Cache-Control: max-age=31536000, immutable,这句话在这个文件「还新鲜」的这一年里都是正常的:普通刷新不会去问源站,客户端直接用手里的那份。要看到新文件,得强制刷新、绕过缓存重载,或者干脆换一个 URL。

问题在于,很多事故并不发生在「用户不肯强刷」,而发生在加 immutable 的人以为它做的是另一件事。

它做的事只有一件:在响应还新鲜的时候,告诉客户端「这段时间里不用回来问」。它不决定这份响应能存多久,也管不到陈旧之后的行为,更拦不住显式的强刷。

响应头 还新鲜的时候 变陈旧之后
max-age=600 直接用缓存;普通刷新可能发条件请求 发条件请求验证
max-age=600, immutable 直接用缓存,且客户端「不应」发条件请求(普通刷新也一样) 与没有 immutable 时一样,照常验证
no-cache 每次使用之前都要验证 —(它本来就不让直接用)
no-store 不存 —
max-age=600, immutable, no-cache 两个指令冲突,按最严格的那个处理 —

最后一行不是「既缓存又不缓存」的玄学:RFC 9111 对冲突给了一条明确的裁决规则,第五行只是按那条规则读出来的结果(见第二节)。

三句话记住:

  1. immutable 不改寿命:寿命仍然由 max-age/s-maxage/Expires 决定;
  2. 它只在新鲜期内生效,陈旧之后自动回到普通缓存行为;
  3. 它挡不住用户显式强刷,也挡不住你自己清缓存。

下面按这三点拆开,最后一节讲它最容易出事的地方:它把「我不会变」这句承诺,交给每一个客户端去执行。

一、它改的是「要不要问」,不是「能存多久」

RFC 8246 对这条扩展的第一句定义就是范围:

When present in an HTTP response, the immutable Cache-Control extension indicates that the origin server will not update the representation of that resource during the freshness lifetime of the response.

两个关键词:will not update(不会更新)与 during the freshness lifetime(在新鲜期内)。它说的是「这段时间里这份表示不会变」,不是「这份响应的寿命有多长」。

紧接着是它对客户端的要求,也是整篇最容易被忽略的一句:

Clients SHOULD NOT issue a conditional request during the response’s freshness lifetime (e.g., upon a reload) unless explicitly overridden by the user (e.g., a force reload).

注意它约束的动作是 conditional request(条件请求)——带 If-None-Match 或 If-Modified-Since 回来的那种请求,命中的话服务器回 304 Not Modified。immutable 省掉的是这一趟往返,不是「存储」这个动作,也不是「过期」这个动作。

为什么值得省?RFC 8246 在引言里给了场景:

A user agent that understands HTML and fetches its dependent sub-resources might issue hundreds of conditional requests to refresh all portions of a common page [REQPERPAGE].

一次普通刷新可能带出几百个条件请求。对用 hash 命名的静态资源来说,这些请求几乎必然全部返回 304——内容本来就没变,问一遍只是确认。immutable 就是把这个「几乎必然」变成「不必问」。

然后它把边界画死:

The immutable extension only applies during the freshness lifetime of the stored response. Stale responses SHOULD be revalidated as they normally would be in the absence of the immutable extension.

as they normally would be in the absence of the immutable extension——陈旧之后,有没有 immutable 完全一样。它不是「加了就永远不问」,而是「新鲜期内别问」。

所以判断一个响应会不会出问题,顺序永远是:先看它新鲜多久,再看它有没有加 immutable。反过来看,就会把「一年」的锅扣在 immutable 头上。

二、寿命还是由 max-age 算

RFC 9111 定义了两件事,immutable 一件都不碰。

第一件是「新鲜」:

A “fresh” response is one whose age has not yet exceeded its freshness lifetime. Conversely, a “stale” response is one where it has.

第二件是寿命怎么来。max-age 的定义是:

The max-age response directive indicates that the response is to be considered stale after its age is greater than the specified number of seconds.

而 RFC 9111 计算寿命时按顺序取第一个命中的来源:共享缓存上的 s-maxage → max-age → Expires 减去 Date → 都没有就走启发式。这份清单里没有 immutable(本文件检索 RFC 9111 全文,immutable 一次都没出现,见第三节)。

RFC 8246 自己给的例子也只有这一个数:

Cache-Control: max-age=31536000, immutable

31536000 是一年,这个「一年」完全是 max-age 给的;immutable 只是在说「这一年里别回来问」。把 max-age 改成 600,immutable 的作用窗口就跟着缩成十分钟——它没有自己的时钟。

由此可以读出两个常被写反的结论(编辑推论,依据是上面两句原文):

  • max-age=0, immutable 等于没写 immutable:寿命为零的响应一生成就是陈旧的,而 immutable 只在新鲜期内生效。
  • no-cache, immutable 是自相矛盾:no-cache 要求每次使用前都要验证,而冲突时「取最严格的那个」——RFC 9111 的原话是 If directives conflict (e.g., both max-age and no-cache are present), the most restrictive directive should be honored. 严格的那一方是 no-cache。

还有一个更要命的时间差:改小 max-age 不会追溯缩短已经存下来的副本。副本的寿命是它当时收到的头算出来的,之后你把它改成 max-age=60,已经拿着「一年」的那些客户端并不知道——它们要等到自己那份变陈旧、回来验证一次,才可能拿到新的头(RFC 9111 允许缓存用后续响应的头字段更新已存响应,但那个「后续响应」正是 immutable 让它不必发生的)。这是编辑推论,机制依据在 RFC 9111 的「更新已存头字段」与新鲜度计算两节;它解释了为什么「改完配置、刷新一下就好了」在自己机器上成立、在别人机器上不成立。

三、它不是 RFC 9111 的指令

这一点必须先说清,因为它决定了「加了就一定生效吗」的答案。

immutable 定义在 RFC 8246,不在 RFC 9111 里。RFC 8246 的 IANA 小节写的是:

The immutable extension has been registered in the “Hypertext Transfer Protocol (HTTP) Cache Directive Registry” per the guidelines described in Section 7.1 of [RFC7234].

而 RFC 9111 把这份注册表当作命名空间来维护:

The “Hypertext Transfer Protocol (HTTP) Cache Directive Registry” defines the namespace for the cache directives. It has been created and is now maintained at https://www.iana.org/assignments/http-cache-directives.

在 IANA 的实际页面上,immutable 这一行的 Reference 就是 RFC 8246;同一张表里 max-age 指向的是 RFC 9111 的两节。也就是说:它是注册过的扩展指令,不是 9111 本文定义的指令。

扩展指令的待遇,RFC 9111 写得很直白:

A cache MUST ignore unrecognized cache directives.

不认识的指令,必须忽略。所以一个不认识 immutable 的缓存,行为上等于你根本没写这三个字:它照 max-age 正常缓存,也照常在你刷新时发条件请求。这不是实现有 bug,而是扩展机制的设计前提——新指令不能把旧实现带崩。

RFC 9111 对「行为型扩展」的设计约束也是这个意思:

Both the new directive and the old directive are supplied, such that applications that do not understand the new directive will default to the behavior specified by the old directive, and those that understand the new directive will recognize it as modifying the requirements associated with the old directive.

「认识它的按新语义,不认识它的按旧语义」——所以 immutable 永远要和一个旧的寿命指令(max-age 或 Expires)一起出现,它自己不带寿命。

接收方 看到 max-age=600, immutable 会怎么做
认识 immutable 新鲜期内直接用,普通刷新也不发条件请求
不认识 immutable 忽略这三个字,按 max-age=600 正常缓存与验证
两边都不认 走启发式寿命,行为与 immutable 无关

还要注意 RFC 8246 用的词是 SHOULD NOT,不是 MUST NOT:客户端不应该在新鲜期内发条件请求,但发了也不算违规。这意味着两件事不能写死——「所有浏览器都遵守」和「所有 CDN 都支持」。本文不对任何具体实现的遵守程度下结论,因为没有一手来源。

四、参数、重复与方向

RFC 8246 用一整段把语法边界写完了:

The immutable extension takes no arguments. If any arguments are present, they have no meaning and MUST be ignored. Multiple instances of the immutable extension are equivalent to one instance. The presence of an immutable Cache-Control extension in a request has no effect.

逐句落到写法上:

写法 原文怎么说 实际效果
Cache-Control: max-age=600, immutable 标准形态 新鲜期内不发条件请求
... immutable=1 参数无意义,MUST be ignored 被忽略的是参数;指令本体仍然生效(编辑判断)
... immutable, immutable 多次等价于一次 与写一次相同
请求头 Cache-Control: immutable has no effect 客户端要求「别更新」是无效的,方向只有一个

另外,Cache-Control 的指令名按 token 比较、大小写不敏感(RFC 9111 的通用规则),所以 IMMUTABLE 与 immutable 在语义上是一回事——但没有理由去测这个边界,写标准的小写形态就好。

这张表里真正容易踩的是第三行和第四行:它只能由源站在响应里声明。你在请求里写、在 HTML 的 <meta http-equiv> 里写、在构建脚本的注释里写,都不构成响应头。

五、中间缓存:代理也该跳过,但它回 304 还是 200 由它自己定

静态站前面通常不止一层缓存:浏览器 → CDN 边缘 → 源站。RFC 8246 专门用一节讲中间层:

An immutable response has the same semantic meaning when received by proxy clients as it does when received by user-agent-based clients.

Therefore, proxies SHOULD skip conditionally revalidating fresh responses containing the immutable extension unless there is a signal from the client that a validation is necessary (e.g., a no-cache Cache-Control request directive defined in Section 5.2.1.4 of [RFC7234]).

这里有个细节值得注意:代理跳过的是「向源站做条件验证」,但它对浏览器怎么回,是另一件事——

A proxy that uses the immutable extension to bypass a conditional revalidation can choose whether to reply with a 304 or 200 response to its requesting client based on the request headers the proxy received.

也就是说,浏览器看到 304 还是 200,不能用来判断 CDN 认不认 immutable(编辑判断)。真正能判断的是「它有没有回源」——而这需要看源站日志或 CDN 的统计,curl 看不到。

还有一条常被忽略的义务,在 RFC 9111 里:

A proxy, whether or not it implements a cache, MUST pass cache directives through in forwarded messages, regardless of their significance to that application, since the directives might apply to all recipients along the request/response chain.

代理必须原样转发缓存指令,不管它自己用不用。这条对排查很有用:如果 CDN 返回给你的 Cache-Control 里 immutable 消失了,那不是「它不认识所以删掉」(不认识应该忽略、而不是删除),而是中间某处改写了头。这是一个可以直接观测的异常信号。

六、它只配「换名」的资源

RFC 8246 的引言先描述了它要解决的场景——版本化 URL:

This design pattern allows a very large freshness lifetime to be used for the sub-resource without guessing when it will be updated in the future.

Unfortunately, the user agent does not know when this versioned URL design pattern is used. As a result, user-driven refreshes still translate into wasted conditional requests for each sub-resource as each will return 304 responses.

这两句把 immutable 的前提说透了:它假设你已经用「换 URL」来表达「换内容」。例子是 main.css 改成 main.3f2a1c.css,引用它的 HTML 同时更新。资源内容一变,URL 就变;URL 不变,就说明内容真的没变。

这也是它和「长 max-age」的区别。RFC 9111 说源站给未来过期时间,是相信内容不会变:

Generally, origin servers will assign future explicit expiration times to responses in the belief that the representation is not likely to change in a semantically significant way before the expiration time is reached.

in the belief that——相信。而 RFC 8246 的 immutable 把它升级成 will not update——不会更新。相信错了,代价是「旧内容多留一会儿」;承诺错了,代价是「旧内容在这一整段时间里连问都不问」。所以能不能写 immutable,取决于你能不能真的做出这个承诺,而不是取决于你想不想少几次 304。

按这个标准分一下(编辑判断):

资源 适合吗 原因
app.3f2a1c.css、logo.9d2b.svg、字体、图片 适合 内容变就换名,URL 与内容一一对应
/、/pricing/、文章页 不适合 URL 稳定,内容随时会改
app.css(没有指纹的固定名) 不适合 名字不变就没法表达「内容变了」
接口响应、带用户信息的 JSON 不适合 同一 URL 对不同人、不同时刻都可能是不同内容

HTML 尤其不能这么写。给首页一个「一年 + immutable」,等于告诉所有客户端:这一年里这个首页不会变。之后你改标题、改价格、发新文章,都不会有人回来问——除非他强刷。判断依据是第一节那句 will not update the representation,不是任何一家 CDN 的默认值。

七、强刷、no-cache 与「让用户清缓存」

immutable 的豁免写得很清楚:unless explicitly overridden by the user (e.g., a force reload)。RFC 8246 的安全小节又补了一遍机制层面的差异:

User agents often provide two different refresh mechanisms: reload and some form of force-reload. The latter is used to rectify interrupted loads and other corruption. These reloads, typically indicated through no-cache request attributes, SHOULD ignore the immutable extension as well.

两种刷新:普通刷新(reload)与强制刷新(force-reload)。前者被 immutable 抑制,后者应当忽略 immutable。请求里带 no-cache 也算后者的信号。

但 no-cache 这个请求指令本身是建议性的:

The no-cache request directive indicates that the client prefers a stored response not be used to satisfy the request without successful validation on the origin server.

prefers——偏好。RFC 9111 在新鲜度一节也写了:

Clients can send the max-age or min-fresh request directives (Section 5.2.1) to suggest limits on the freshness calculations for the corresponding response. However, caches are not required to honor them.

are not required to honor them——缓存没有义务照做。所以「让用户按 Ctrl+F5」是一根能用的拐杖,但它不是发布流程:

  • 你无法确认对方按了,也无法确认对方用的是哪种刷新;
  • 它只影响那一个浏览器,影响不到 CDN 边缘上那份;
  • 新访客没有旧副本,他拿到的是「现在源站给的那份」——如果源站给的是旧文件,强刷也没用。

「让用户清缓存」同理:能救一个人,救不了下一个人。真正的修法在第九节。

八、它把错误一起钉住

RFC 8246 的安全小节没有绕弯子:

The immutable mechanism acts as form of soft pinning and, as with all pinning mechanisms, creates a vector for amplification of cache corruption incidents. These incidents include cache-poisoning attacks.

soft pinning(软钉死)与 amplification(放大)。max-age 写错,最坏结果是「旧内容多留一会儿」;immutable 写错,是「这段时间里连问都不问」,于是一次错误会被完整复制给每一个新访客,窗口长度等于整个新鲜期(编辑推论)。这也是为什么它比 max-age 更需要一个「能保证」的前提。

RFC 8246 给了三条缓解措施,都是「客户端应当忽略」:

缓解 原文 落地含义
只在可信传输上生效 Clients SHOULD ignore the immutable extension from resources that are not part of an authenticated context such as HTTPS. 明文 HTTP 上的响应,有些客户端会直接不认这三个字
强制刷新忽略它 These reloads, typically indicated through no-cache request attributes, SHOULD ignore the immutable extension as well. 覆盖「加载中断、内容损坏」这类需要重来的场景
长度不可靠时忽略它 Clients SHOULD ignore the immutable extension for resources that do not provide a strong indication that the stored response size is the correct response size such as responses delimited by connection close. 用连接关闭定界、拿不到可靠长度的响应,可能不被信任

第三条最容易被忽略:它说的不是「内容会变」,而是「我无法确认我拿到的是完整的一份」。如果你把 immutable 加在一个长度不可靠的响应上,等于让客户端在整个新鲜期里都不去复核那份可能不完整的内容。

三条都是 SHOULD ignore——客户端可以不认,不是必须不认。所以「我在 HTTPS 上,所以一定生效」也不成立;反过来「我在 HTTP 上,所以一定不生效」同样不成立。这里能确定的只有规范给的倾向,具体实现行为没有一手来源,本文不猜。

九、出事了,按这个顺序查

「用户看到旧文件」有四个不同的原因,混在一起查就会来回打转:

  1. 响应头里根本没有 immutable(或没有你以为了那么长的 max-age);
  2. 有 immutable,但 URL 也没换——内容和名字对不上,承诺从一开始就是错的;
  3. 有 immutable、URL 也换了,但 HTML 引用的还是旧 URL——旧 HTML 被缓存住了,问题在上一层;
  4. 各层都对了,只是那一份副本还没陈旧——这是设计内的行为,不是故障。

排查顺序与对应的证据:

步骤 看什么 判读
1 直连源站与经过 CDN 各取一次响应头 两处 Cache-Control 不一致 → 中间层改写
2 响应头里的 max-age 到底是多久 比你以为的长 → 先修寿命,再谈 immutable
3 HTML 里引用的资源名带不带指纹 不带 → immutable 的前提不成立
4 响应有没有 Age 头 有 Age 说明这份不是本次由源站生成或验证的
5 旧 URL 还在不在被请求 在 → 旧 HTML 或旧引用还没退场

第 4 步的依据是 RFC 9111 对 Age 的定义:

The presence of an Age header field implies that the response was not generated or validated by the origin server for this request.

修法有优先级(编辑判断,按「确定性」排,不按「方便」排):

  1. 换 URL:改文件名或加版本参数,让「新内容」有一个新地址。这是唯一能让所有客户端立刻拿到新东西的做法,也是 immutable 唯一自洽的用法。
  2. 改响应头:只对之后收到的副本生效。已经存下的那份要等它陈旧、回来验证一次才可能更新——而 immutable 恰恰让这次验证不发生。
  3. 清 CDN 缓存:只清它经过的那些缓存。RFC 9111 的失效机制是给不安全方法准备的:A cache MUST invalidate the target URI (Section 7.1 of [HTTP]) when it receives a non-error status code in response to an unsafe request method (including methods whose safety is unknown). 静态站部署走的是上传新文件,不是对同一个 URI 发一个 PUT,所以不会自动触发这条失效(编辑判断)。
  4. 让用户清缓存:救一个人,救不了下一个。

十、十分钟核对

先说清这组命令的边界:curl 每次都是全新请求,没有本地缓存,所以它只能核对服务器发了什么头,看不到浏览器会怎么处理。客户端行为要另外用真实浏览器验证。

第一组:HTML 与资源的头各是什么

for u in https://example.com/ https://example.com/assets/app.3f2a1c.css; do
  echo "== $u"
  curl -sS -o /dev/null -D - "$u" \
    | grep -iE '^(HTTP/|cache-control:|age:|etag:|expires:)'
done

第二组:HTML 引用的到底是不是带指纹的名字

curl -sS https://example.com/ | grep -oE '/assets/[A-Za-z0-9._-]+\.(css|js)' | sort -u

第三组:校验器还在不在(陈旧之后要靠它验证)

etag=$(curl -sS -o /dev/null -D - https://example.com/assets/app.3f2a1c.css \
  | grep -i '^etag:' | tr -d '\r' | cut -d' ' -f2-)
curl -sS -o /dev/null -D - -H "If-None-Match: $etag" \
  https://example.com/assets/app.3f2a1c.css | head -1

第四组:经过 CDN 时,头有没有被改写

curl -sS -o /dev/null -D - https://example.com/assets/app.3f2a1c.css \
  | grep -iE '^(HTTP/|cache-control:|age:)'

判读:

看到什么 说明 下一步
资源头有 immutable,但 max-age 很短 immutable 的作用窗口也很短 先确认这个长度是不是你要的
HTML 也带 immutable 且 max-age 很长 首页被钉住了 改成 no-cache,别给稳定 URL 加 immutable
资源名不带指纹,却写了 immutable 承诺与实现不一致 先换名,或者去掉 immutable
直连有 immutable、经过 CDN 没有 中间层改写了响应头 查 CDN 的响应头改写规则
有 Age,max-age 还没到 这是命中缓存,不是故障 需要立刻更新就换 URL
第三组返回 304 校验器在工作 陈旧之后能正常验证,这是底线

十一、上线前十二项清单

  1. 这个 URL 的内容会变吗?会变,就不要写 immutable。
  2. 文件名里有内容指纹(hash 或版本号)吗?
  3. max-age 具体是多少秒?immutable 不会改这个数。
  4. 这份响应只通过 HTTPS 提供吗?
  5. HTML 用的是 no-cache,而不是长 max-age 加 immutable?
  6. immutable 写在响应头里,而不是请求头或 <meta> 里?
  7. 有没有和 no-cache、max-age=0 同时出现(互相抵消)?
  8. 经过 CDN/反向代理后,Cache-Control 里还有 immutable 吗?
  9. ETag 或 Last-Modified 还在吗?陈旧之后要靠它们验证。
  10. 旧资源被替换时,旧 URL 还会被请求多久?有没有过渡方案?
  11. 回滚的时候,旧的指纹文件名还在不在?回滚是不是也要换名?
  12. 上线后普通刷新与强制刷新各试一次,确认两者的差异符合预期。

六种误读,与本周能做的五件事

误读 原文怎么说
「immutable 让缓存永久有效」 原文限定 during the freshness lifetime;寿命仍由 max-age 等决定
「immutable 会延长 max-age」 寿命计算按 s-maxage → max-age → Expires → 启发式取第一个,immutable 不在其中
「加了 immutable 就不用换文件名」 它的前提就是版本化 URL:allows a very large freshness lifetime ... without guessing when it will be updated
「immutable 能拦住强刷」 原文是 unless explicitly overridden by the user (e.g., a force reload),且 no-cache 类重载也应忽略它
「immutable 是 RFC 9111 的指令」 RFC 9111 全文 0 命中,它注册在 IANA,规范来源是 RFC 8246
「加了就一定生效」 不认识它的缓存按 RFC 9111 MUST ignore unrecognized cache directives 处理,等于没写

本文不写:各家浏览器与 CDN 对 immutable 的支持比例、默认是否开启、版本差异,缓存命中率数字,以及任何产品的配置项名称与生效时间。这些都没有一手来源,写出来就是猜。

本周能做的五件事:

  1. 把站点所有带 immutable 的响应列出来,逐个回答清单第 1、2 条。
  2. 找一条长 max-age 的 HTML 响应,把它改成 no-cache,观察一次发布后的表现。
  3. 给静态资源加内容指纹,让「换内容」等于「换 URL」。
  4. 直连源站与经过 CDN 各取一次头,确认 Cache-Control 没有被改写。
  5. 把「回滚时旧指纹文件还在不在」写进发布检查单——回滚也是一次换名。

边界说明

  • 本文只引用 RFC 8246、RFC 9111 与 IANA 注册表的原文;每处英文引用都可在对应页面检索到,标注为「编辑判断」「编辑推论」的段落是从原文推出来的工程结论,不是规范原文。
  • 不讨论具体浏览器、CDN、反向代理对 immutable 的实现差异与支持比例;这些需要各家官方文档,本文没有取证。
  • 不讨论 immutable 对 SEO、可访问性或安全策略的影响;没有一手来源支持具体结论。
  • 文中 example.com 与 app.3f2a1c.css 均为占位示例,不代表任何真实站点的配置。

来源

  • RFC 8246: HTTP Immutable Responses — https://www.rfc-editor.org/rfc/rfc8246.txt核查于 2026/11/2(2026-11-02 访问;§1 引言与版本化 URL 场景、§2 定义与三条语法边界、§2.1 中间层、§2.2 示例、§3 软钉死与三条缓解、§4 IANA 注册)
  • RFC 9111: HTTP Caching — https://www.rfc-editor.org/rfc/rfc9111.txt核查于 2026/11/2(2026-11-02 访问;§3.2 更新已存头字段、§4.2 新鲜与陈旧、§4.2.1 寿命计算与冲突裁决、§4.4 失效机制、§5.1 Age、§5.2 指令通用规则与转发义务、§5.2.1.4 请求 no-cache、§5.2.2.1 max-age、§5.2.3 扩展指令、§5.2.4 注册表)
  • IANA: Hypertext Transfer Protocol (HTTP) Cache Directive Registry — https://www.iana.org/assignments/http-cache-directives核查于 2026/11/2(2026-11-02 访问;immutable 的 Reference 为 RFC 8246)

唯一主行动

把下一步变成可执行动作

进入发布、维护与回滚工作流