浏览器缓存 是浏览器将用户请求过的静态资源(html、css、js),存储到电脑本地磁盘中,当浏览器再次访问时,就能够直接从本地加载了,不须要再去服务端请求了。css
但也不是说缓存没有缺点,若是处理不当,可能会致使服务端代码更新了,可是用户却仍是老页面。因此前端们要针对项目中各个资源的实际状况,作出合理的缓存策略。html
缓存的优势:前端
这里先介绍一下浏览器缓存资源的一个大概的流程。nginx
咱们能够认为,浏览器里有一个专门存放缓存规则的一个数据库,也能够说是一个映射表,把缓存资源信息,同电脑磁盘中的实际文件的地址,对应起来。(大概意思,别较真)chrome
而这个缓存规则的表,在浏览器中是能够看到的: chrome://cache/数据库
不过我升级了浏览器以后,就很差使了,可是找到了 chrome://net-internals/#httpCache ,不知道是否是就是原来的,知道的同窗也能够反馈一下后端
浏览器第一次请求资源时浏览器
上面所说的 缓存规则,就是声明所请求的这个资源,要采起哪一种缓存策略?缓存多长时间?等等。。。而这个规则,是在http的header中的返回来的。缓存
注意: 是response header ,而不是 request header !!!服务器
而实际上, request header 中也会携带规则信息,下面会讲,要区分 request 和 response
强缓存和协商缓存。
简单粗暴,若是资源没过时,就取缓存,若是过时了,则请求服务器。
如何判断资源是否过时呢,也就是说强缓存的规则怎么看?
主要是看 response headers 中的 Cache-Control 的值,图中的max-age = 31xxxxxxx,就是说在这些秒内,都直接使用缓存,超过了就继续请求服务器
而和 Cache-Control 并列的,还有一个 Expires ,已经基本淘汰了,因此不用管
Cache-Control 的几个取值含义:
private: 仅浏览器能够缓存
public: 浏览器和代理服务器均可以缓存(对于private和public,前端能够认为同样,不用深究)
max-age=xxx 过时时间(重要)
no-cache 不进行强缓存(重要)
no-store 不强缓存,也不协商缓存,基本不用,缓存越多才越好呢
注意:规则能够同时多个
因此,对于强缓存,咱们主要研究 Cache-Control 中的 max-age 和 no-cache
因此,判断该资源是否命中强缓存,就看 response 中 Cache-Control 的值,若是有max-age=xxx秒,则命中强缓存。若是Cache-Control的值是no-cache,说明没命中强缓存,走协商缓存。
强缓存流程:
因此强缓存步骤已经很清晰了:
触发条件:
也就是说,无论怎样,均可能最后要进行协商缓存(no-store除外)
这个图,虽然强缓存命中,可是也有 ETag 和 Last-Modified ,这两个就是协商缓存的相关规则。虽然以前的强缓存流程和他俩没关。。。
ETag:每一个文件有一个,改动文件了就变了,能够看似md5
Last-Modified:文件的修改时间
也就是说,每次http返回来 response header 中的 ETag和 Last-Modified,在下次请求时在 request header 就把这两个带上(可是名字变了ETag-->If-None-Match,Last-Modified-->If-Modified-Since ),服务端把你带过来的标识,资源目前的标识,进行对比,而后判断资源是否更改了。
这个过程是循环往复的,即缓存表在每次请求成功后都会更新规则。
1. 第n次请求成功时:
2. 缓存表中更新该资源的 ETag 值
3. 第n+1次请求:
从缓存表中取该资源最新的ETag,而后加在 request header 中, 注意变名字了,由 ETag -- > If-None-Match
图:
因此协商缓存步骤总结:
注意:协商缓存不管若是,都要向服务端发请求的,只不过,资源未更改时,返回的只是header信息,因此size很小;而资源有更改时,还要返回body数据,因此size会大。
0. 怎么配置资源的缓存规则
能够有后端服务器配置,也能够在nginx中配置,稍后会更新一张nginx的配置
1. 为何要有Etag
你可能会以为使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为何还须要Etag呢?HTTP1.1中Etag的出现(也就是说,ETag是新增的,为了解决以前只有If-Modified的缺点)主要是为了解决几个Last-Modified比较难解决的问题:
一些文件也许会周期性的更改,可是他的内容并不改变(仅仅改变的修改时间),这个时候咱们并不但愿客户端认为这个文件被修改了,而从新GET;
某些文件修改很是频繁,好比在秒如下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改没法判断(或者说UNIX记录MTIME只能精确到秒);
某些服务器不能精确的获得文件的最后修改时间。
2. 强缓存与协商缓存的区别能够用下表来表示:
3. 用户行为对缓存的影响
即:F5 会 跳过强缓存规则,直接走协商缓存;;;Ctrl+F5 ,跳过全部缓存规则,和第一次请求同样,从新获取资源
借两个图