乐趣区

关于http:RFC文档阅读HTTP-Cache

Cache 类型

private cache

意味着该缓存不会与其余用户共享

share cache

  1. Proxy cache
    就是两头代理服务器的缓存,然而因为 https 的风行,这些代理服务器基本上只能转发申请
  2. Managed cached
    就是源服务器配置的缓存:nginx,cdn,service worker

什么样申请响应时能够被缓存的

  1. 响应的状态码是 1xx, 2xx,3xx, 4xx,5xx 范畴内
  2. 没有呈现 no-store 指令
  3. 响应含有 Expire 字段或者以下的指令:public,private,max-age,s-maxage,immutable 等

缓存响应的 key

个别应用申请办法 + 申请的 URI 作为缓存的 key,然而能够应用 vary 字段,增加响应头作为 key 的一部分
例如:Vary: Accept-Language

Freshness

只有响应的 age 不超过它的 freshness lifetime 就认为是是“陈腐的”,否则就会认为曾经过期

freshness lifetime 是指响应从服务器产生到它的过期工夫这段时间范畴

explicit expiration time 是指响应头蕴含 Expires 字段或者 max-age 指令

age 是指该响应从服务产生后所过来的工夫

浏览器也能够应用 max-age 或者 min-fresh 申请指令来倡议服务器返对应的响应(例如浏览器强制刷新的时候就会带上 max-age=0)

Freshness Lifetime(Freshness 生命周期计算)

  1. 如果 cache 是共享的,而且响应头也蕴含 s -maxage,则应用这个值
  2. 如果响应头蕴含 max-age,则应用这个值
  3. 如果响应头蕴含 Expires,则应用这个字段减去 Date 字段(如果 Date 字段不存在,则应用接管响应的工夫)
  4. 否则如果在响应头没有明确的过期工夫,则会利用一种启发式的 Freshness Lifetime 去计算

如果响应头呈现多个 Expires 或者多个Cache-Control: max-age,则能够应用第一个字段的值或者认为这个响应曾经 stale(行为未定义,要依据浏览器理论行为参考),如果缓存指令呈现抵触,例如(max-age 和 no-cache 同时呈现)则只会利用最严格的那个指令;如果 max-age 是有效的值,则也会认为该响应是 stale 的

Calculating Heuristic Freshness(启发式计算 Freshness)

次要起因因为服务器可能不会提供明确的过期工夫(没有 Expires 和 max-age),所以这个时候缓存本人要给文件计算一个过期工夫,例如应用其余字段 Last-Modified 工夫辅助计算,然而这里不会给出一个固定的算法,要浏览器本人定义。
然而还是给出一个参考:(Last-Modified – Date)* 10%(能够认为如果隔了这么一段时间才批改,大略下次批改也会在这段时间之内,所以生命周期也在这个工夫范畴内)

Age 计算

age_value 响应头 Age 字段,如果没有则认为是 0
date_value 响应头 Date 字段
now 以后工夫
request_time 申请工夫
response_time 响应工夫

计算形式次要有两种

  1. apparent_age,response_time 减去 date_value,如果浏览器工夫是跟服务器工夫同步的应该是比拟精确(然而不太可能)
    apparent_age = max(0, response_time – date_value);
  2. corrected_age_value (只有反对 http1.1 以上的都应用这个计算形式)
    response_delay = response_time – request_time;
    corrected_age_value = age_value + response_delay;

而后 corrected_age_value 还能够被用作 corrected_initial_age,
然而还有一种状况就是返回头没有 Age 字段的时候(age_value 则视为 0 参加 corrected_age_value 计算),corrected_initial_age 能够上面激进的形式计算,别离统计 apparent_age 和 corrected_age_value,再求最大值:
corrected_initial_age = max(apparent_age, corrected_age_value);

resident_time = now – response_time;
current_age = corrected_initial_age + resident_time;

Serving Stale Responses

如果响应头蕴含 no-cache,must-revalidate,s- maxage 和 proxy-revalidate,是禁止缓存返回过期的响应的
除非浏览器无奈与服务器建设链接,或者申请时带有 max-stale 指令才容许返回过期的响应

Validation(验证资源)

如果响应被缓存了(也就是必须被缓存过的响应才会进入验证阶段,这由与响应能不能被缓存相干),而且缓存曾经过期,或者无奈被选则(具体起因前面补充),须要应用 conditional request mechanism(条件申请验证机制)去发送一个申请让服务端返回新的响应

Sending a Validation Request 发送验证申请

缓存会合成一个申请,复制 mehod,uri 还有 vary 字段所标记的其余头部字段,还有增加 If-Modified-Since,If-Unmodified-Since,If-Match,If-None-Match 这些 precondition header;这里 f -Match,If-None-Match 比 If-Modified-Since,If-Unmodified-Since 优先级更高(毕竟验证更加精确)

Handling a Validation Response

  1. 304 状态码,不返回响应内容
  2. 或者残缺的响应
  3. 也有可能是 5xx

Cache-Control

cache-control 的指令能够别离在申请 / 响应中失效,也就是 cache-control 能够呈现在申请头中 / 响应头中,而他们在申请和响应中所反对的指令也不肯定雷同,就算指令雷同也不肯定含意都一样

Response Directives

当返回附带以下指令,cache 必须恪守这些指令来解决

max-age
指出新鲜度工夫范畴,当响应的 age 超过这个范畴就认为是过期的

然而响应的 age 并不是依据当初的工夫减去接管响应的工夫来计算的

must-revalidate
指出一旦响应缓存曾经过期了,必须在从新 validate 后能力应用,禁止任何状况下应用过期的响应缓存
因为在无奈 connnect 服务器状况下,有可能应用过期的响应缓存来进行回复申请,所以 must-revalidate 会禁止这种状况,间接返回一个 504 错误码

个别状况下须要跟 max-age 配合应用

must-understand
指出如果 cache 了解依据状态码来缓存响应,才应该缓存响应

个别 must-understand 会搭配 no-store 应用

Cache-Control: must-understand, no-store

如果 cache 不反对 must-understand,那就应用 no-store 指令
if cache support must-understand,it stores the response with an understanding of cache requirements based on its status code

no-cache
指出响应缓存必须是通过 Validation 和接管到(successful response)胜利的响应能力被应用
这意味着每次应用缓存前都须要发送验证申请到服务器验证

这里留神 no-cache 并不是代表“don’t cache”,no-cache 意味着还是能缓存响应然而应用缓存之前必须通过 revalidate。
真正的“don’t cache”是 no-store 指令

no-store
指出无论 private cache 还是 share cache 都不应该缓存响应

no-transform
因为一些两头服务器会把内容转换成各种格局,例如图片能够转换成不同格局来缩小传输大小,所以这里会禁止这种行为

private
意味着响应只能存在 private cache
只有返回资源有波及到用户的个人信息,都应该应用这个指令,缩小个人信息透露

proxy-revalidate
同 must-validate,然而仅仅对 share cache 失效

public
指出这里响应应该缓存在 share cache 外面

s-maxage
相似 max-age 然而只对 share cache 失效

immutable
指出响应在生命周期内是不会更新内容的

个别状况下,当强制刷新浏览器就(哪怕缓存没有过期)会发送申请去服务器进行 validate
当缓存还没过期的时候(还在生命周期内),即便强制刷新也不会发送申请去 validate(因为没必要)

这适宜带版本永不更新的资源

stale-while-revalidate
指出缓存过期后的一段时间内依然能够应用过期的缓存,而这段时间内资源会在后盾进行 revalidate,这样的益处就是缩小间接的 revalidate 进步用户体验,因为都在后盾进行 revalidate 了

Cache-Control: max-age=604800, stale-while-revalidate=86400

在 604800 秒后缓存过期,然而在接着的 86400 秒工夫内依然能够应用过期缓存,而且还会在这段时间外在后盾进行 revalidate

stale-if-error
指出过期的缓存,如果在进行 revalidate 时,服务器返回 (500, 502, 503, or 504) 依然能够应用一段时间,过后在这一段时间之后还是会进入失常的过期流程

Request Directives

当申请头附带以下指令,是阐明这是申请对 cache 的一种冀望,然而不肯定必须满足

max-age
容许 cache 返回生命周期在肯定工夫范畴的缓存

很多浏览器会应用 max-age= 0 来进行强制刷新

max-stale
容许 cache 返回过期工夫在肯定范畴内的缓存

min-fresh
指出 cache 返回的缓存,它的生命周期至多还有肯定工夫,要是少于这个工夫则禁止应用这个缓存,然而大部分浏览器都不反对这个指令

no-cache
申请 cache 在应用缓存时先进行 revalidate

no-store
让 cache 不要缓存响应,哪怕响应是能够被缓存的

no-transform
同 Response 的指令

only-if-cached
指出心愿获取曾经缓存的响应,所以如果 cache 曾经缓存了资源,间接返回即可

问题思考

max-age= 0 和 no-cache 区别

max-age=0,仅仅让缓存生效了,失常状况下还是要进行 revalidate,然而在无奈 connnect 服务器的状况下浏览器还是能够返回过期的缓存,而 no-cache 是禁止了这种行为
所以 no-cache 更加等效于 must-revalidate, max-age=0

怎么移除浏览器缓存

一旦缓存生成了,那是没有完满的方法移除,因为在缓存失效期间都不会有申请都间接到服务器(除非设置了 no-cache,must-revalidate)

一种办法是应用 POST 申请去申请同一个 url,让缓存生效,但这种形式实现比拟麻烦

另外一种形式就是应用 Clear-Site-Data 响应头字段
例如:Clear-Site-Data: cache
能够革除 cache,cookies,storage,executionContexts
然而并不是所有浏览器都反对(safari 就不反对)

怎么对待 http 缓存

一旦应用了 http 缓存,当然能够进步网页加载性能和进步整体体验,然而也意味着开发者对页面没方法实现相对的管制(例如页面代码更新没有方法让所有用户拜访时都能立刻体验失去,除非应用 no-cache 等指令强制每次申请都去 revalidate)

Referer

https://developer.mozilla.org…
https://www.rfc-editor.org/rf…
https://www.rfc-editor.org/rf…

退出移动版