浏览器的缓存规则是在 http 协议头和 html 页面的 meta 标签中定义的。主要分为两部分:强缓存和协商缓存。
强缓存是指缓存的副本在有效期内,浏览器直接获取这个副本并渲染。
强缓存主要涉及的 http 协议报头有:Expires,cache-control。css
强缓存的过程:浏览器发起 http 请求,浏览器缓存中查找该请求的结果以及缓存标识,缓存副本在有效期内,该请求返回状态码 200,从 disk cache 或 memory cache (size 中显示 from disk cache 或 from memory cache)中返回。若是缓存副本并不在有效期内,浏览器将发起 http 请求到服务端,服务端返回请求结果和缓存规则,并将请求结果和缓存标识存在浏览器缓存中。html
Expires:是HTTP/1的产物,是一个绝对的时间,若是浏览器时间尚未超过这个expires时间,表明缓存还有效。直接从缓存中读取资源。
cache-control:是HTTP/1.1提出的。web
指令 | 做用 |
public | 代表响应能够被任何对象(包括:发送请求的客户端,代理服务器,等算法 等)缓存。浏览器 |
private | 代表响应只能被单个用户缓存,不能做为共享缓存(即代理服务器不能缓存 缓存它),能够缓存响应内容。服务器 |
no-cache | 在释放缓存副本以前,强制高速缓存将请求提交给原始服务器进行验证。 |
only-if-cached | 代表客户端只接受已缓存的响应,而且不要向原始服务器检查是否有更cookie 新的拷贝网络 |
max-age=<seconds> | 设置缓存存储的最大周期,超过这个时间缓存被认为过时(单位秒)。负载均衡 与Expires相反,时间是相对于请求的时间。 |
s-maxage=<seconds> | 覆盖max-age 或者 Expires 头,可是仅适用于共享缓存(好比各个代理), 而且私有缓存中它被忽略。 |
max-stale[=<seconds>] | 代表客户端愿意接收一个已通过期的资源。 可选的设置一个时间(单位秒), 表示响应不能超过的过期时间。 |
min-fresh=<seconds> | 表示客户端但愿在指定的时间内获取最新的响应。 |
若是 cache-control 和 expires 同时存在的话,cache-control 优先级高于 Expires。Expires 设置的过时时间受客户端本地时间影响。
协商缓存是在强缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。
协商缓存的过程:浏览器发起 http 请求,浏览器缓存返回缓存标识(请求的缓存结果失效),浏览器携带该资源的缓存标识,向服务器发起 http 请求,若是服务器返回 304 和 not modified,浏览器向浏览器缓存获取该请求的缓存结果,浏览器环迅返回该请求结果。若是服务器返回 200 和请求结果(该资源更新了,从新返回请求结果),浏览器将该请求结果和缓存标识存入浏览器缓存中。
协商缓存主要涉及的 http 协议报头有:Last-Modified 和 ETag。
Last-Modified:浏览器在第一次访问资源时,服务器返回响应头Last-Modified,值是这个资源在服务器上的最后修改时间,浏览器接收后缓存文件和header;再次请求资源,浏览器检测有 Last-Modified 就会添加请求头 If-Modified-Since,值是Last-Modified 的值。服务器接收请求会根据 If-Modified-Since 中的值与服务器中这个资源的最后修改时间对比,若是没有变化返回 304 和空的响应体,直接从缓存读取。若是 If-Modified-Since 时间小于服务器中这个资源的最后修改时间,说明文件有更新,因而返回新的资源文件和 200。
Etag 和 If-None-Match:Etag返回的是资源文件的惟一标识,只要文件有变化吗Etag就会从新生成。浏览器在下次加载资源时带上 If-None-Match,值是ETag。服务器比较跟资源文件的ETag是否一致。若是一致,则直接返回 304 。
若是 ETag 和 Last-Modified 同时存在,ETag 优于 Last-Modified.Last-Modified
的时间单位是秒,秒级别的修改,不能保证精度。若是是负载均衡的服务器各个服务器生成的 Last-Modified 也有可能不一致。在性能上,ETag 要逊于 Last-Modified,ETag
须要服务器经过算法计算一个hash值。
协商缓存是没法减小请求数的开销的,可是能够减小返回的正文大小。通常来讲,对于勤改动的html文件,使用协商缓存是一种不错的选择。
F5 刷新,Expires/cache-control 无效了,Last-Modified/ETag 仍是有效的。
Ctrl + F5 强制刷新,Expires/cache-control,Last-Modified 都无效。
不被缓存的请求:
基于缓存策略:
参考博客:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers