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...