浏览器包含哪些存储机制?
cookie、webStorage以及IndexedDB
cookie的存在更多的是为了让服务端区别用户,webStorage和IndexedDB则更多用在保存具体的数据和在客户端存储大量结构化数据(文件/blobs)上面。
缓存 请求资源的副本
好处
- 缓解服务器压力(不用每次去请求资源);
- 提升性能(打开本地资源速度当然比请求回来再打开要快得多);
- 减少带宽消耗(我相信你可以理解);
浏览器缓存,代理服务器缓存
缓存在宏观上可以分成两类:私有缓存和共享缓存。共享缓存就是那些能被各级代理缓存的缓存。私有缓存就是用户专享的,各级代理不能缓存的缓存
缓存过程分析
cache.png由上图我们可以知道:
浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识
浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中
以上两点结论就是浏览器缓存机制的关键,他确保了每个请求的缓存存入与读取,只要我们再理解浏览器缓存的使用规则,那么所有的问题就迎刃而解了,本文也将围绕着这点进行详细分析。为了方便大家理解,这里我们根据是否需要向服务器重新发起HTTP请求将缓存过程分为两个部分,分别是强制缓存和协商缓存。
HTTP协议里定义了很多关于缓存的请求和响应字段
浏览器对于缓存的处理是根据第一次请求资源时返回的响应头来确定的。
Age:23146
Cache-Control:max-age=2592000 // HTTP 1.1 缓存过期相对时间,优先级高
Date:Tue, 28 Nov 2017 12:26:41 GMT
ETag:W/"5a1cf09a-63c6" // 对文件的标记
Expires:Thu, 28 Dec 2017 05:27:45 GMT // HTTP 1.0 缓存过期绝对时间
Last-Modified:Tue, 28 Nov 2017 05:14:02 GMT // 文件最后一次修改时间
Vary:Accept-Encoding
强缓存阶段
强制缓存就是向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程,强制缓存的情况主要有三种
- 不存在缓存标识:直接请求
- 存在缓存标识,但结果失效:协商缓存
- 存在缓存标识,且结果未失效:直接返回结果
// 与上述的Last-Modified,ETag对应,If优先级低
If-Moified-Since: Tue, 28 Nov 2017 05:14:02 GMT
If-None-Match: W/"5a1cf09a-63c6"
协商缓存阶段
过期后进入协商缓存阶段
请求携带这两个字段,服务器以此判断资源是否修改
修改:返回200 和新的内容
未修改:返回304 加载本地缓存(Chrome,firefox不会)
启发式缓存阶段
Age:23146
Cache-Control: public
Date:Tue, 28 Nov 2017 12:26:41 GMT
Last-Modified:Tue, 28 Nov 2017 05:14:02 GMT
Vary:Accept-Encoding
确定缓存过期时间的字段一个都没有!
根据响应头中2个时间字段 Date 和 Last-Modified 之间的时间差值,取其值的10%作为缓存时间周期。
flowChart.pngExpires有一个很大的弊端,就是它返回的是服务器的时间,但判断的时候用的却是客户端的时间
If-Unmodified-Since
这个字段字面意思和If-Modified-Since
相反,但处理方式并不是相反的。如果文件在两次访问期间没有被修改则返回200和资源,如果文件修改了则返回状态码412(预处理错误)。
用途:
- 与含有
If-Range
消息头的范围请求搭配使用,实现断点续传的功能,即如果资源没修改继续下载,如果资源修改了,续传的意义就没有了。 - POST、PUT请求中,优化并发控制,即当多用户编辑用一份文档的时候,如果服务器的资源已经被修改,那么在对其作出编辑会被拒绝提交
Last-Modified
有几个缺点:没法准确的判断资源是否真的修改了,比如某个文件在1秒内频繁更改了多次,根据Last-Modified的时间(单位是秒)是判断不出来的,再比如,某个资源只是修改了,但实际内容并没有发生变化,Last-Modified也无法判断出来,因此在HTTP/1.1中还推出了ETag
这个字段
https://juejin.im/entry/5ad86c16f265da505a77dca4
https://juejin.im/post/5a6c87c46fb9a01ca560b4d7
网友评论