本文要点
拿到Age之后,第二步是找同一个响应里的Cache-Control: max-age
Age这个数字落在不同位置,说明的事情不一样
光看公式容易记混,建议用一张自己填的对照表练几遍

本文目录
先分清Age回答的是哪一段时间
如果你在响应头里看到Age,先明确它记录的是什么:Age表示这个响应在共享缓存里已经存了多久,单位是秒。
按MDN的HTTP缓存说明,当响应存储在共享缓存中时,可以向客户端告知该响应的存活时间。文档给的例子是:一个max-age为604800秒的响应,被共享缓存存了一天之后,再返回给后续客户端时,响应里会多出一行Age: 86400。86400秒正好是一天。
所以Age不是响应从生成到现在一共过了多久,也不是源服务器处理请求花了多久。它只回答一个问题:这份响应在到达你之前,已经在中间那层共享缓存里躺了多少秒。
这一点决定了它的用途。Age是给客户端做减法用的,不是给你判断服务器快慢用的。本文只讲怎么读这个秒数、怎么用它算剩余新鲜时间,不涉及其他缓存策略。
一个自建情境(示例,不是对某个真实网站的记录):你在练习目录里维护一个自建页面,用本地或公开地址打开它,在开发者工具的Network面板里点开某条响应,看响应头里有没有Age这一行。下面所有数字都是练习用的自建数据。
max-age减去Age,得到的是剩余新鲜秒数
拿到Age之后,第二步是找同一个响应里的Cache-Control: max-age。
按MDN文档的说明,收到带Age的响应后,客户端会发现它在剩余的518400秒内是有效的,这是响应的max-age和Age之间的差异。文档给的这组数字是:max-age=604800,Age=86400,两者相减得518400。
所以公式只有一条:
剩余新鲜时间 = max-age − Age
把文档那组数字代进去核对一遍:604800 − 86400 = 518400。这个518400就是客户端还能直接复用这份缓存、不必回源验证的秒数。
这里要分清两个词。max-age是这份响应从生成那一刻算起的总新鲜期;Age是它已经被共享缓存消耗掉的部分;两者相减,才是留给你这次请求的余额。
一个自建示例(练习数据,不是真实响应):假设你在练习目录里自己写一份响应头文本,写成下面两行,然后手工做一次减法核对。
Cache-Control: max-age=604800
Age: 86400把604800和86400相减,得到518400。这一步只是算术核对,不代表任何真实网站的缓存状态。
三种Age取值分别对应什么状态
Age这个数字落在不同位置,说明的事情不一样。下面按三种情况分开说,每种只回答一个问题。
第一种,Age为0或没有Age这一行。说明这份响应基本是刚由源服务器产生、还没在共享缓存里停留,或者这次请求没有经过会写入Age的共享缓存。此时剩余新鲜时间约等于max-age本身。
第二种,Age大于0但小于max-age。这是最常见的情况,说明响应在共享缓存里存了一段时间,但还没到期。剩余新鲜时间就是max-age减Age,结果为正数。文档那组604800和86400的例子就属于这一种。
第三种,Age大于或等于max-age。相减结果为零或负数,说明按max-age算,这份响应已经不再新鲜。文档把这种情况归入过期状态:过期的响应不会立即被丢弃,但不能再不经验证直接复用。
需要说清一个边界:Age只反映共享缓存这一层已经消耗的时间。它不告诉你浏览器私有缓存里有没有另一份副本,也不告诉你源服务器上的内容有没有更新。本文只按Age和max-age这两个字段做判断,不涉及其他缓存层。
用一张自建对照表练减法
光看公式容易记混,建议用一张自己填的对照表练几遍。下面这张表是编辑设计的练习表,数字全部是自建的,不是对任何真实响应的记录。
max-age Age max-age - Age 状态判断
604800 0 604800 刚生成,几乎全新鲜
604800 86400 518400 已消耗一天,仍新鲜
604800 604800 0 刚好到期
604800 700000 -95200 已过期
3600 1800 1800 剩半小时填表时按三步走:
1. 从响应头里抄下max-age的秒数,填进第一列。
2. 抄下Age的秒数,填进第二列。没有Age就填0。
3. 做减法,把结果填进第三列,再按上一节的三档判断状态。
这张表的作用是让你把“读两个数字、做一次减法”变成固定动作。练熟之后,看到任何一组max-age和Age,都能当场算出剩余秒数。
一个提醒:表里的数字只用于练习算术,不要拿它去推断某个真实网站的实际缓存时长。
算出来是负数或零时该怎么理解
减法结果为负,容易让人以为算错了。其实不是,它说明Age已经超过了max-age。
按MDN文档对新鲜和过期的划分:如果响应的存活时间小于max-age,响应为新鲜的;如果超过max-age,响应为过期的。存活时间在这里指响应生成以来经过的时间,而Age正是共享缓存已经消耗的那一段。
所以当Age大于max-age时,这份响应在共享缓存这一层已经过期。文档同时说明,过期的响应不会立即被丢弃,HTTP有一种验证机制,可以通过询问源服务器把旧响应转换为新响应。
对读Age的人来说,这意味着两件事:
第一,负数和零都表示“按max-age算已经不再新鲜”,不需要纠结负多少。
第二,过期不等于这份缓存没用了。它只是不能再不经验证直接复用,后续可能走条件请求去问源服务器。
本文只讲到这一步,不展开验证请求的具体字段,也不讲其他缓存指令。
读Age时容易搞错的三处
第一处:把Age当成响应总年龄。Age只记录共享缓存已经存储的秒数,它不包含响应在源服务器上生成之前的时间,也不包含浏览器私有缓存里的时间。用Age去推算“这个页面多久没更新”,方向就错了。
第二处:拿Date和Age互相换算。Date是响应生成的时刻,Age是已经过去的秒数,两者格式不同,一个是HTTP日期,一个是整数秒。文档给的例子里,Date写的是Tue, 22 Feb 2022 22:22:22 GMT,Age写的是86400,不能直接相减。
第三处:忘了先确认max-age存在。减法要用到max-age,如果响应里没有Cache-Control: max-age,就没有这个被减数。文档提到,缺少max-age时可能走启发式缓存,但本文不涉及启发式推算,遇到没有max-age的响应,本文的减法不适用。
核对顺序建议固定成:先看有没有max-age,再看有没有Age,最后做减法。三步缺一步,结论就不成立。
这套读法的适用边界
本文的减法只适用于一种情形:响应里同时给出了Cache-Control: max-age和Age,且你想知道客户端还能直接复用这份共享缓存多少秒。
不适用于以下情形:
响应里没有max-age。此时没有可减的被减数,本文的公式用不上。
你想判断的是浏览器私有缓存。Age描述的是共享缓存这一层,私有缓存的时间消耗不在这个字段里。
你想知道源服务器上的内容有没有更新。Age和max-age只说明缓存的新鲜度,不说明内容是否已变。
你想推算过期之后会发生什么。本文只讲到“过期”这个判断,不展开后续的验证流程。
一个操作提醒:如果你要在练习目录里自己写响应头文本做减法练习,先复制一份到单独目录,例如exercise/,不要改动正在使用的任何配置文件。本文所有示例数字都是自建的练习数据,不是对真实响应的记录,也不代表任何网站的实际缓存状态。
观看知识要点视频 18 秒
18秒无旁白要点导览,文字来自已审核正文;完整步骤、条件及参考资料见下方。
参考资料
以下原始资料提供本文依据;请结合日期、适用条件和产品说明查阅。
请结合原始资料的适用条件阅读。
返回浏览器工具 →