前言

总所周知,缓存是解决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. 关于django的坑(一)

    关于django orm 的坑: 关于设置数据库表自动更新 django的orm关于更新数据库的方法有update和save两种方法.想要表中自动更新需要一下几个条件: 使用 DateTimeFiel ...

  2. JAVA数据结构(十一)—— 堆及堆排序

    堆 堆基本介绍 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,最坏,最好,平均时间复杂度都是O(nlogn),不稳定的排序 堆是具有以下性质的完全二叉树:每个节点的值都大于或等 ...

  3. 分布式ID生成策略之ZK

    import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFra ...

  4. C/C++ 弱符号

    为什么会出现弱符号 在两个目标文件(a.o与b.o)链接的过程中,如果其中一个目标文件(a.o)通过extern的方式引用了另外一个目标文件(b.o)中的符号flag,但很不幸,在连接的过程中b.o没 ...

  5. 用漫画的形式展现——URL和HTTP

    http请求内容:请求头:get.post等发送请求(其他:head.put.delete.option) host 地址 user-Agent cookie 通行证 head:与get请求类似,不同 ...

  6. [C#] 使用 Excel 和 Math.Net 进行曲线拟合和数据预测

    以前在工作中遇到了一个数据错误的问题,顺便写下 用 Math.Net 解决的思路. 1. 错误的数据 上图是同一组探测器在同一天采集到的 19 次数据,总体来说重复性不错,但很明显最后 8 个探测器出 ...

  7. .NET 云原生架构师训练营(模块二 基础巩固 消息队列 介绍与基础)--学习笔记

    2.6.1 消息队列 -- 介绍 主要使用场景 队列的三种形式 消息队列的优点 主要使用场景 典型的异步处理 流量削锋 应用解耦 队列的三种形式 点对点 工作队列 发布与订阅 消息队列的优点 1.屏蔽 ...

  8. HarmonyOS分布式任务调度开发之--你必须知道的bundleName

    背景 最近基于HarmonyOS在写一个通讯录的项目,已经完成了一个java版本的通讯录,通讯录数据全部存储在sqlite数据库中.现在在着手写一个JS版本的通讯录,这时候关于JS版本中数据的读取,我 ...

  9. 安卓手机使用Termux及搭建FTP服务器

    Termux安装配置设置参见: 国光:Termux高级终端使用配置教程 搭建FTP服务器参见: Termux安装使用FTP服务器

  10. tf.argmax(vector,axis)函数的使用

    1.返回值 vector为向量,返回行或列的最大值的索引号: vector为矩阵,返回值是向量,返回每行或每列的最大值的索引号. 2.参数 vector为向量或者矩阵 axis = 0 或1 0:返回 ...