前言

总所周知,缓存是解决Http1.1协议传输性能的问题中最主要的手段。

缓存既可以存在于浏览器上,也可以存在于服务器中。

而影响缓存的Http头部有很多,其中Cache-Control是比较重要的一个,也是取值比较复杂的一个。

下面先聊一聊缓存的工作原理,再说说Cache-Control的详细取值。

缓存的工作原理

HTTP缓存是一个以时间为维度的缓存。

浏览器在第一次请求中缓存了响应,而后续的请求可以从缓存提取第一次请求的响应。从而达到:减少时延而且还能降低带宽消耗,因为可能压根就没有发出请求,所以网络的吞吐量也下降了。

工作原理

浏览器发出第一次请求,服务器返回响应。如果得到响应中有信息告诉浏览器可以缓存此响应。那么浏览器就把这个响应缓存到浏览器缓存中。

如果后续再发出请求时,浏览器会先判断缓存是否过期。如果没有过期,浏览器压根就不会向服务器发出请求,而是直接从缓存中提取结果。

比如:访问掘金站点

 

Size中可以看出,disk cache是从硬盘中提取的缓存信息。

缓存过期了

如果缓存过期了,也并不一定向第一个请求那样服务器直接返回响应。

浏览器的缓存时间过过期了,就把该请求带上缓存的标签发送给服务器。这时如果服务器觉得这份缓存还能用,那就返回304响应码。浏览器将继续使用这份缓存。

比如:选择上面图中的其中一份缓存文件,copy请求urlcurl中展示

 

首先加-I获取原始请求,查看etaglast-modified头部。

因为浏览器缓存过期之后,请求就会带上这些头部一起发送给服务器,让服务器判断是否还能用。
针对etag头部,加一个if-none-match头部带上etag的值询问服务器。当然也可以针对last-modified头部,加一个if-modified-since头部询问。

 

返回的是304。304的好处就是不携带包体,也就是说content-length为0,这样就节省了大量的带宽。

共享缓存

浏览器缓存是私有缓存,只提供给一个用户使用的。

而共享缓存是放在服务器上的,可以提供多个用户使用。比如说某个比较热点的视频等热点资源就会放在代理代理服务器的缓存中,以减低源服务器的压力,提升网络效率。

怎么分辨这个资源是代理服务器的缓存还是源服务器发送的呢?

仍然使用掘金的例子

 

从图中看出这个请求的Response Headers中的age头部,单位是秒。

说明这个缓存是共享缓存返回的,age说明了它在共享缓存存在的时间,图中是327784,也就是在共享缓存中存在了327784秒。

共享缓存也有过期的时候,下面看看共享缓存的工作原理。

 

如图所示:
1、当client1发起请求时,Cache也就是代理服务器(共享缓存),转发这条请求给源服务器。源服务器返回响应,并在Cache-Control头部中设定可以缓存100秒。接着在Cache中就会开启一个定时器Age,将响应带上Age:0头部返回给client1

2、过了10秒后,client2发送相同的请求,Cache中的缓存还没有过期,就带上Age:10头部返回缓存中的响应给client2

3、过了100秒后,client3发送同样的请求,这时Cache中的缓存已经过期了,就像前面说到那样用条件请求头部If-None-Match带上缓存的指纹发给源服务器。当源服务认为此缓存还能用,就返回304状态码给CacheCache就重新计时,从缓存中找出响应带上Age:0头部返回给Client3

vary缓存

vary头部是可以做一些更为复杂的缓存匹配条件,只有vary头部指定的头部必须与请求中的头部相匹配才能使用缓存。

vary的定义:

  • "*": 意味着一定匹配失败
  • 1个或多个field-name:指定的头部必须与请求中的头部相匹配才能使用缓存
     

如图所示:
1、 当Client1携带Accept-Encoding:*头部的GET请求发送给serverserver返回的是gzip编码的响应,以及vary:Content-Encoding头部,表示着编码方式一样的时候才能使用缓存。

2、当Client2携带Accept-Encoding:br头部的GET请求发送给server,这时请求的是br编码。所以Cache不能使用缓存,因为不匹配vary的中的值,只能转发请求给源服务器server

3、当Client3携带Accept-Encoding:br头部的GET请求发送给server,这时Cachebr编码的缓存,能匹配vary头部的值,所以能使用缓存返回。

Cache-Control

Cache-Control头部取值范围非常复杂。

Cache-Control的定义是:

  • 必选的token
  • 可选的“=”,加上带引号的值或者1个或多个十进制的数字也就是指定的秒数

Cache-Control既可以在请求中使用,也可以在响应是使用。而且相同的值在请求和响应中的含义是不一样的。

Cache-Control值有三种用法:

  • 1、直接使用token
  • 2、token值+ '=' + 十进制数字
  • 3、token值+ '=' + 相应的头部 / 直接使用token

在请求中的应用

在请求中Cache-Control的取值、用法及其含义:@后面表示第几种用法

  • max-age@2: 告诉服务器,客户端不会接收Age超出max-age秒的缓存
  • max-stale@2: 告诉服务器,即使缓存不再新鲜,但过期秒数没有超过max-stale时,客户端仍打算使用。若max-stale后没有值,则表示无论过期多久,客户端都可使用。
  • min-fresh@2: 告诉服务器,Age至少经过min-fresh秒后缓存才可使用
  • no-cache@1: 告诉服务器,不能直接使用已有缓存作为响应返回,除非带着缓存条件到上游服务器得到304状态码才可使用现有缓存。
  • no-store@1: 告诉各代理服务器,不要对该请求的响应缓存
  • no-transform@1: 告诉代理服务器不要修改消息包体的内容
  • only-if-cached@1: 告诉服务器仅能返回缓存的响应,否则若没有缓存则返回504错误码

在响应中的应用

在响应中Cache-Control的取值及其含义:

  • max-age@2: 告诉客户端缓存Age超出max-age秒后则缓存过期
  • s-maxage@2:与max-age类似,但仅针对共享缓存,且优先级高于max-ageexpires
  • must-revaildate@1: 告诉客户端一旦缓存过期,必须向服务器验证后才可使用
  • proxy-revalidate@1: 与must-revaildate类似,但它仅对代理服务器的共享缓存有效
  • no-cache@3: 1、告诉客户端不能直接使用缓存的响应,使用前必须在源服务器验证得到304返回码。2、如果no-cache后指定头部,则若客户端的后续请求及响应中不含有这些头部则可直接使用缓存
  • no-store@1: 告诉所有下游服务器但不能对响应进行缓存
  • no-transform: 告诉代理服务器不能修改消息包体的内容
  • public@1: 表示无论私有缓存或者共享缓存,皆可将该响应缓存
  • private@3: 1、表示该响应不能被代理服务器作用共享缓存使用。2、若priate后指定头部,则告诉代理服务器不能缓存指定的头部,可以缓存其他头部

作者: zhangwinwin
链接:URI与URL傻傻分不清楚?
来源:github

URI与URL傻傻分不清楚?的更多相关文章

  1. URL URI傻傻分不清楚,dart告诉你该怎么用

    目录 简介 dart中的URI encode和decode 解析URI 总结 简介 如果我们要访问一个网站,需要知道这个网站的地址,网站的地址一般被称为URL,他的全称是Uniform Resourc ...

  2. JS魔法堂:属性、特性,傻傻分不清楚

    一.前言 或许你和我一样都曾经被下面的代码所困扰 var el = document.getElementById('dummy'); el.hello = "test"; con ...

  3. 傻傻分不清之 Cookie、Session、Token、JWT

    傻傻分不清之 Cookie.Session.Token.JWT 什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证明“你是你自己”(比如:你每天上下班打卡,都需要通过指纹打 ...

  4. JDBC、ORM、JPA、Spring Data JPA,傻傻分不清楚?一文带你厘清个中曲直,给你个选择SpringDataJPA的理由!

    序言 Spring Data JPA作为Spring Data中对于关系型数据库支持的一种框架技术,属于ORM的一种,通过得当的使用,可以大大简化开发过程中对于数据操作的复杂度. 本文档隶属于< ...

  5. MVP MVC MVVM 傻傻分不清

    最近MVC (Model-View-Controller) 和MVVM (Model-View-ViewModel) 在微软圈成为显学,ASP.NET MVC 和WPF 的Prism (MVVM Fr ...

  6. Java:接口和抽象类,傻傻分不清楚?

    01. 来看网络上对接口的一番解释: 接口(英文:Interface),在 Java 编程语言中是一个抽象类型,是抽象方法的集合.一个类通过继承接口的方式,从而来继承接口的抽象方法. 兄弟们,你们怎么 ...

  7. [转帖]十分钟快速理解DPI和PPI,不再傻傻分不清!

    十分钟快速理解DPI和PPI,不再傻傻分不清! https://baijiahao.baidu.com/s?id=1605834796518990333&wfr=spider&for= ...

  8. OCA,OCP,OCM傻傻分不清?

    可能大家知道OCA.OCP.OCM的关系是一个比一个难考,一个比一个含金量高,但是你知道具体的考试科目.考试方式.就业形势区别吗?不知道的话这篇通俗易懂的文章会让你一目了然. 区别一:含金量 ■OCA ...

  9. 学点经济学:M0、M1、M2、M3,傻傻分不清?(转载)

    来源:http://t.10jqka.com.cn/pid_97006727.shtml 学点经济学:M0.M1.M2.M3,傻傻分不清? 25,508人浏览 2018-08-03 11:06 常听人 ...

随机推荐

  1. 开发规范(一) 如何记录日志 By 阿里

  2. 开发规范(三)数据库 By 阿里

    建表规约 索引规约 SQL语句 ORM映射

  3. [Machine Learning] 逻辑回归 (Logistic Regression) -分类问题-逻辑回归-正则化

    在之前的问题讨论中,研究的都是连续值,即y的输出是一个连续的值.但是在分类问题中,要预测的值是离散的值,就是预测的结果是否属于某一个类.例如:判断一封电子邮件是否是垃圾邮件:判断一次金融交易是否是欺诈 ...

  4. win10 设置文件夹别名、修改文件夹图标、修改文件夹别名、英文目录和中文目录、设置文件夹中文名称、快捷访问显示设置中文

    最近在设置文件夹的时候发现个有趣的事情: 系统路径 C:\Users\Administrator  内的文件夹不仅有图标还显示中文名称,但是打开路径的时候显示的却是英文,这就激发了我的探索欲,究竟是为 ...

  5. salesforce零基础学习(九十九)Salesforce Data Skew(数据倾斜)

    本篇参考: https://developer.salesforce.com/blogs/engineering/2013/04/managing-lookup-skew-to-avoid-recor ...

  6. ASP.NET Core 上传文件到共享文件夹

    参考资料:ASP.NET 上传文件到共享文件夹 创建共享文件夹参考资料:https://www.cnblogs.com/dansediao/p/5712657.html 一.配置上传文件相关参数并读取 ...

  7. 内存性能测试 Memtester+mbw

    Memtester简单介绍 Memtester主要是捕获内存错误和一直处于很高或者很低的坏位, 其测试的主要项目有随机值,异或比较,减法,乘法,除法,与或运算等等. 通过给定测试内存的大小和次数, 可 ...

  8. iostat的输出

    第一行显示的时子系统启动以来的平均值,接下来的报告显示了增量的平均值,每个设备一行 Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   ...

  9. 【System】I/O密集型和CPU密集型工作负载之间有什么区别

    CPU密集型(CPU-bound) CPU密集型也叫计算密集型,指的是系统的硬盘.内存性能相对CPU要好很多,此时,系统运作大部分的状况是CPU Loading 100%,CPU要读/写I/O(硬盘/ ...

  10. python sqlite3增加表字段

    给sqlite3表格增加新字段,要注意大小写,要不然不成功. 一开始这样写,不成功! 后面规范写,按大小写严格规范写! 成功了!现在查看新增加的字段commit: 仔细看,这下全部小写,括表名称.co ...