强缓存
如果资源没过期,就取缓存,如果过期了,则请求服务器,一般用于JS、CSS、图片等资源
如何判断强缓存过期?
第一次访问页面,浏览器会根据服务器返回的 response Header 来判断是否对资源进行缓存,如果响应头中有 cache-control 或 expires 字段,代表该资源是强缓存
Cache-Control
是 HTTP1.1 中控制网页缓存的字段,主要取值为:
- public:资源客户端和服务器都可以缓存
- privite:资源只有客户端可以缓存
- no-cache:客户端缓存资源,但是是否缓存需要经过协商缓存来验证
- no-store:不使用缓存
- max-age:缓存保质期,是相对时间
Expires
是HTTP1.0控制网页缓存的字段,值为一个时间戳,服务器返回该资源缓存的到期时间
但 Expires 有个缺点,就是它判断是否过期是用本地时间来判断的,本地时间是可以自己修改的
到了HTTP/1.1,Expire 已经被 Cache-Control 替代,Cache-Control 使用了max-age相对时间,解决了Expires 的缺陷
注意:当 Cache-Control 与 expires 两者都存在时,Cache-Control 优先级更高
memory cache 与 disk cache 的区别?
两者都属于强缓存,主要区别在于存储位置和读取速度上
- memory cache 表示缓存来自内存, disk cache 表示缓存来自硬盘
- memory cache 要比 disk cache 快的多!从磁盘访问可能需要5-20毫秒,而内存访问只需要100纳秒甚至更快
- memory cache 特点:当前tab页关闭后,数据将不存在(资源被释放掉了),再次打开相同的页面时,原来的 memory cache 会变成 disk cache
- disk cache 特点:关闭tab页甚至关闭浏览器后,数据依然存在,下次打开仍然会是 from disk cache
一般情况下,浏览器会将js和图片等文件解析执行后直接存入内存中,这样当刷新页面时,只需直接从内存中读取(from memory cache);而css文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存(from disk cache)
协商缓存
浏览器携带缓存标识向服务器发送请求,服务器根据缓存标识来决定该资源是否过期,一般用于html资源,验证版本是否更新
触发条件:(强缓存没有命中,也就是说强缓存的优先级高于协商缓存)
- Cache-Control 的值为 no-cache (协商缓存)
- 或者 Cache-Control: max-age=0
协商缓存的标识
Last-Modified : 文件在服务器最后被修改的时间,从服务器 Respnse Headers 上获取
Last-Modified 的验证流程:
- 第一次访问页面时,服务器的响应头会返回 Last-Modified 字段
- 客户端再次发起该请求时,请求头 If-Modified-Since 字段会携带上次请求返回的 Last-Modified 值
- 服务器根据 if-modified-since 的值,与该资源在服务器最后被修改时间做对比,若服务器上的时间大于 Last-Modified 的值,则重新返回资源,返回200,表示资源已更新;反之则返回304,代表资源未更新,可继续使用缓存
- 请求的 Request Headers 上携带 if-modified-since 字段:
Etag
ETag:当前资源文件的一个唯一标识(由服务器生成),若文件内容发生变化该值就会改变
ETag 的验证流程:
- 第一次访问页面时,服务器的响应头会返回 etag 字段
- 客户端再次发起该请求时,请求头 If-None-Match 字段会携带上次请求返回的 etag 值
- 服务器根据 If-None-Match 的值,与该资源在服务器的Etag值做对比,若值发生变化,状态码为200,表示资源已更新;反之则返回304,代表资源无更新,可继续使用缓存
请求的 Request Headers 上携带 if-none-match 字段:
为什么要有 Etag ?
Etag 的出现主要是为了解决一些 Last-Modified 难处理的问题:
- 一些文件也许会周期性的更改,但是内容并不改变(仅仅改变的修改时间),这时候并不希望客户端认为这个文件被修改了而重新去请求;
- 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说 1s 内修改了 N 次),If-Modified-Since 能检查到的粒度是秒级的,使用 Etag 就能够保证这种需求下客户端在 1 秒内能刷新 N 次 cache
注意:Etag 优先级高于 Last-Modified,若 Etag 与 Last-Modified 两者同时存在,服务器优先校验 Etag
协商缓存的两种状态
服务器根据请求头携带的缓存标识,判断该资源是否变化,资源未变化返回304,反之返回200
1)资源未变化,返回304
2)资源已更新,返回200
协商缓存的流程
1)第一次请求
客户端发送请求,服务器处理请求,返回文件内容和一堆Header,包括Etag 和 Last-Modified,状态码200
2)第二次请求
1、客户端发起请求,此时请求头上会带上 if-none-match值为Etag 和 if-modified-since值为last-modified
2、服务器优先判断 Etag,若资源未变化状态码为304,客户端继续使用本地缓存,若资源发生变化,状态码为200 并返回最新的资源