缓存的分类
- 强缓存
用户发送的请求,直接从客户端缓存中获取,不发送请求到服务器,不与服务器发生交互行为。 - 协商缓存
用户发送的请求,发送到服务器后,由服务器判定是否从缓存中获取资源。
通常为本地的缓存不存在,或已过期后向浏览器发送请求后确认不使用缓存,进行协商缓存 - 两者共同点
客户端获得的数据最后都是从客户端缓存中获得。 - 两者的区别
从名字就可以看出,强缓存不与服务器交互,而协商缓存则需要与服务器交互。
###
- 新鲜度(过期机制)
也就是缓存副本有效期。一个缓存副本必须满足以下条件,浏览器会认为它是有效的,足够新的:- 含有完整的过期时间控制头信息(HTTP协议报头),并且仍在有效期内;
- 浏览器已经使用过这个缓存副本,并且在一个会话中已经检查过新鲜度;
满足以上两个情况的一种,浏览器会直接从缓存中获取副本并渲染。
- 校验值 (验证机制)
服务器返回资源的时候有时在控制头信息带上这个资源的实体标签 Etag(Entity Tag),它可以用来作为浏览器再次请求过程的校验标识。如过发现校验标识不匹配,说明资源已经被修改或过期,浏览器需求重新获取资源内容。
Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304(not modified,缓存已过期重新申请)还是200(from cache,缓存没过期 / ok,缓存已过期且新缓存已修改)。- 注意
- Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存,但是需要注意的是分布式系统里多台机器间文件的last-modified必须保持一致,以免负载均衡到不同机器导致比对失败,Yahoo建议分布式系统尽量关闭掉Etag(每台机器生成的etag都会不一样,因为除了 last-modified、inode 也很难保持一致)。
- Last-Modified/If-Modified-Since要配合Cache-Control使用,Etag/If-None-Match也要配合Cache-Control使用。
- 注意
浏览器缓存的控制
使用HTML Meta 标签
1<meta http-equiv="Pragma" content="no-cache">- 限制
- 仅有IE才能识别这段meta标签含义,其它主流浏览器仅识别“Cache-Control: no-store”的meta标签。
- 在IE中识别到该meta标签含义,并不一定会在请求字段加上Pragma,但的确会让当前页面每次都发新请求(仅限页面,页面上的资源则不受影响)。
- 限制
- 使用缓存有关的HTTP消息报头
- Cache-Control
Http1.1 中的标准,可以看成是 expires 的补充。使用的是相对时间的概念。
简单介绍下Cache-Control的属性设置。- max-age
设置缓存的最大的有效时间,单位为秒(s)。max-age[相对时间]会覆盖掉Expires[具体时期] - s-maxage
只用于共享缓存,比如CDN缓存(s -> share)。与max-age 的区别是:max-age用于普通缓存,
而s-maxage用于代理缓存。如果存在s-maxage,则会覆盖max-age 和 Expires. - public
响应会被缓存,并且在多用户间共享。默认是public。 - private
响应只作为私有的缓存,不能在用户间共享。如果要求HTTP认证,响应会自动设置为private。 - no-cache
指定不缓存响应,表明资源不进行缓存。但是设置了no-cache之后并 不代表浏览器不缓存,而是 在缓存前要向服务器 确认资源是否被更改。因此有的时候只设置no-cache防止缓存还是不够保险,还可以加上private指令,将过期时间设为过去的时间。 - no-store
绝对 禁止缓存。 - must-revalidate
如果页面过期,则去服务器进行获取。
- max-age
- Cache-Control 和 Pragma(逐渐淘汰)
- Cache-Control: max-age=秒 和 Expires(逐渐淘汰,如果c和s时间不一致则有偏差)
用户行为对缓存的影响
- Cache-Control