[深入07] 浏览器缓存机制(http缓存机制)

导航

[深入01] 执行上下文
[深入02] 原型链
[深入03] 继承
[深入04] 事件循环
[深入05] 柯里化 偏函数 函数记忆
[深入06] 隐式转换 和 运算符
[深入07] 浏览器缓存机制(http缓存机制)
[深入08] 前端安全
[深入09] 深浅拷贝
[深入10] Debounce Throttle
[深入11] 前端路由
[深入12] 前端模块化
[深入13] 观察者模式 发布订阅模式 双向数据绑定
[深入14] canvas
[深入15] webSocket
[深入16] webpack
[深入17] http 和 https
[深入18] CSS-interview
[深入19] 手写Promise
[深入20] 手写函数

[react] Hooks

[部署01] Nginx
[部署02] Docker 部署vue项目
[部署03] gitlab-CI

[源码-webpack01-前置知识] AST抽象语法树
[源码-webpack02-前置知识] Tapable
[源码-webpack03] 手写webpack - compiler简单编译流程
[源码] Redux React-Redux01
[源码] axios
[源码] vuex
[源码-vue01] data响应式 和 初始化渲染
[源码-vue02] computed 响应式 - 初始化,访问,更新过程

缓存的重要性

  • 一个优秀的缓存策略,可以缩短网页请求资源的距离,减少延迟,缓存文件可以重复利用所以还可以减少带宽,降低网路负荷

浏览器缓存

  • 浏览器启用缓存的优点:减少页面加载时间,减少服务器负载
  • <font color=red>浏览器是否使用缓存,缓存多久,是由服务器控制的</font>
    • 即服务器响应的 <font color=red>响应头</font> 中,某些字段指明了缓存的关键信息
  • 通用首部字段
    • 请求和响应都能用的字段
    • Cache-Control
  • 请求首部字段
    • If-None-Match
    • If-Modified-Since
  • 响应首部字段
    • ETag
  • 实体首部字段
    • Expires
    • Last-Modified
  • 浏览器缓存的分类
    • <font color=red>强缓存</font> 和 <font color=red>协商缓存</font>

强缓存

  • <font color=red>Expires</font>, <font color=red>Cache-Control</font>
  • 返回的状态码 200
  • <font color=red>network => size => 会显示 from-cache (from-disk-cache),(from-memory-cache)</font>
  • 强缓存的实现:通过( <font color=red>Expires</font> ) 或者 ( <font color=red>Cache-Control</font> ) 这两个 ( <font color=red>http response header</font> ) 来实现的,他们用都是用来表示资源在客服端存在的 <font color=red>有效期</font>

Expires

  • http1.0提出,响应头中的一个字段,绝对时间,用GMT格式的字符串表示
  • <font color=red>注意:expires是和浏览器本地的时间做对比,是一个绝对时间点,是一个GMT时间</font>
  • Expires是优化中最理想的情况,因为它根本不会产生请求,所以后端也就无需考虑查询快慢
  • Expires的原理
Expires的原理

1. 浏览器第一次向服务器请求资源,浏览器在请求资源的同时,在responder响应头中加上Expires字段
2. 浏览器在接收到这个资源后,将这个资源和所有response header一起缓存起来
   - 所以,缓存命中的请求返回的header并不是来自服务器,而是来自之前缓存的header
3. 浏览器再次请求这个资源时,先从缓存中寻找,找到这个资源后,拿出Expires跟当前的请求时间做比较
   - 如果当前请求时间,在Expires指定的时间之前,就能命中强缓存,否则不能
   - 注意:Expires是和浏览器本地时间作对比
4. 如果未命中缓存,则浏览器直接从服务器获取资源,并更新response header中的Expires
  • expires是较老的强缓存管理header,<font color=red>是服务器返回的一个绝对时间</font>,在服务器时间与客服端时间相差较大时,Expires缓存管理容易出问题(比如:随便修改客户端时间,就能影响命中结果),所以在http1.1中,提出了新的header => Cache-Control,一个相对时间,以秒为单位,用数值表示

Cache-Control

  • http1.1提出,响应头中的一个字段,相对时间,以秒为单位,用数值表示
  • <font color=red>注意:Cache-Control也是和浏览器本地时间做对比,以秒为单位的时间段</font>
  • Cache-Control可以指定:<font color=red>public</font> 和 <font color=red>private</font>
    • <font color=red>private</font>:表示该资源仅仅属于发出请求的最终用户,这将禁止中间服务器(如代理服务器)缓存此类资源,对于包含用户个人信息的文件,可以设置private
    • <font color=red>public</font>:允许所有服务器缓存该资源
    • no-cache:使用协商缓存
    • no-store:不使用缓存
    • max-age: 123123 // 一个时间段,单位是s
  • <font color=red>Cache-control: no-cache,private,max-age=123123</font>
  • Cache-Control的原理
Cache-Control的原理

1. 浏览器第一次向服务器请求资源,服务器在返回资源的同时,在responder的header中加上Cache-Control字段
2. 浏览器在接收到这个资源后,会将这个资源和所有的response header一起缓存起来
   - 所以,缓存命中的请求返回的header并不是来自服务器,而是来自之前缓存的header
3. 浏览器再次请求这个资源时,先从缓存中寻找,找到这个资源后,拿出Cache-Control和当前请求的时间做比较
   - 如果当前请求时间,在Cache-Control表示的时间段内,就能命中强缓存,否则不能
4. 如果缓存未命中,则浏览器直接从服务器获取资源,并更新response header中的 Cache-Control

强缓存Expires和Cache-Control总结

  • Expires和Cache-Control可以开启一个,也可以同时开启
  • 当Expires和Cache-Control同时开启时,Cache-Control优先级高于Expires
  • Cache-Control可以指定private和public,表示是否允许中间服务器缓存该资源
  • expires是一个用GMT时间表示的时间点,Cach-Control是用秒表示的时间段,都是和浏览器本地时间做对比

协商缓存

  • <font color=red>Last-Modified(If-Modified-Since)</font>,<font color=red>ETag(If-None-Match)</font>
  • 返回状态码 304
  • 协商缓存的原理:<font color=red>当浏览器对某个资源的请求没有命中强缓存,就会发一个请求到服务器,验证协商缓存是否命中</font>,如果协商缓存命中,请求响应返回的http状态为304,并且会显示一个Not Modified的字符串表示资源未被修改
  • modified: 是修改的意思

Last-Modified 和 If-Modified-Since

  • Last-Modified和If-Modified-Since都是根据 <font color=red>服务器时间</font> 返回的header
  • 响应头:Last-Modified
  • 请求头:If-Modified-Since
  • 原理
Last-Modified If-None-Match

1. 浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在response的header加上Last-Modified的header
   - 这个header表示这个资源在服务器上的最后修改时间

2. 浏览器再次跟服务器请求这个资源时,在request的header上加上If-Modified-Since的header
   - 这个header的值就是上一次请求时返回的Last-Modified的值

3. 服务器再次收到资源请求时,根据浏览器传过来If-Modified-Since和资源在服务器上的最后修改时间判断资源是否有变化
   - 如果没有变化则返回304 Not Modified,但是不会返回资源内容;
   - 如果有变化,就正常返回资源内容。
   // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   // 当服务器返回304 Not Modified的响应时,response header中不会再添加Last-Modified的header
   // 因为既然资源没有变化,那么Last-Modified也就不会改变
 
4. 浏览器收到304的响应后,就会从缓存中加载资源

5. 如果协商缓存没有命中,浏览器直接从服务器加载资源时,Last-Modified Header在重新加载的时候会被更新
   - 下次请求时,If-Modified-Since会启用上次返回的Last-Modified值

ETag 和 If-None-Match

  • <font color=red>只要资源有变化ETag这个字符串就不一样,和修改时间没有关系,所以很好的补充了Last-Modified的问题</font>
  • 响应头:ETag
  • 请求头:If-None-Match
  • 原理
ETag 和 If-None-Match

1. 浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在response的header加上ETag的header
   - 这个header是服务器根据当前请求的资源生成的一个唯一标识,这个唯一标识是一个字符串
   - 只要资源有变化这个串就不同,跟最后修改时间没有关系,所以能很好的补充Last-Modified的问题

2. 浏览器再次跟服务器请求这个资源时,在request的header上加上If-None-Match的header,
   - 这个header的值就是上一次请求时返回的ETag的值

3. 服务器再次收到资源请求时,根据浏览器传过来If-None-Match然后再根据资源生成一个新的ETag
   - 如果没有变化则返回304 Not Modified,但是不会返回资源内容
   - 如果有变化,就正常返回资源内容。
   // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   // 与Last-Modified不一样的是,当服务器返回304 Not Modified的响应时
   // 由于ETag重新生成过,response header中还会把这个ETag返回,即使这个ETag跟之前的没有变化

4. 浏览器收到304的响应后,就会从缓存中加载资源。

Last-Modified(If-Modified-Since) 和 ETag(If-None-Match) 的区别

  • ETag的优势
    • ETag和Last-Modified非常相似,都是用来判断一个参数,从而决定是否启用缓存。
    • 但是ETag相对于Last-Modified也有其优势,可以更加准确的判断文件内容是否被修改,从而在实际操作中实用程度也更高。

强缓存和协商缓存的区别

  • 协商缓存跟强缓存不一样,强缓存不发请求到服务器,所以有时候资源更新了浏览器还不知道,但是协商缓存会发请求到服务器,所以资源是否更新,服务器肯定知道。
  • 大部分web服务器都默认开启协商缓存,而且是同时启用Last-Modified,If-Modified-Since和ETag、If-None-Match
  • Last-Modified,If-Modified-Since和ETag、If-None-Match一般都是同时启用,这是为了处理Last-Modified不可靠的情况
  • // 分布式系统里多台机器间文件的Last-Modified必须保持一致,以免负载均衡到不同机器导致比对失败
  • // 分布式系统尽量关闭掉ETag(每台机器生成的ETag都会不一样)

浏览器缓存判断的流程

  1. 第一次正常请求后,缓存了资源和所有header的前提下
  2. 在资源缓存后,在缓存过期失效之前,如果再次请求该资源,<font color=red>默认先检查强缓存</font>
    • 强缓存命中,则直接读取
    • 未命中强缓存,则发送请求到服务器,<font color=red>再检查是否命中协商缓存</font>
  3. 未命中强缓存,再发请求到服务器检查是否命中协商缓存
    • 协商缓存命中,则告诉浏览器还是可以从缓存读取
    • 未命中协商缓存,才从服务器返回最新的资源
image

https://juejin.im/post/6844903672556552205#heading-0

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容