URI与URL傻傻分不清楚?
前言
总所周知,缓存是解决Http1.1
协议传输性能的问题中最主要的手段。
缓存既可以存在于浏览器上,也可以存在于服务器中。
而影响缓存的Http
头部有很多,其中Cache-Control
是比较重要的一个,也是取值比较复杂的一个。
下面先聊一聊缓存的工作原理,再说说Cache-Control
的详细取值。
缓存的工作原理
HTTP
缓存是一个以时间为维度的缓存。
浏览器在第一次请求中缓存了响应,而后续的请求可以从缓存提取第一次请求的响应。从而达到:减少时延而且还能降低带宽消耗,因为可能压根就没有发出请求,所以网络的吞吐量也下降了。
工作原理
浏览器发出第一次请求,服务器返回响应。如果得到响应中有信息告诉浏览器可以缓存此响应。那么浏览器就把这个响应缓存到浏览器缓存中。
如果后续再发出请求时,浏览器会先判断缓存是否过期。如果没有过期,浏览器压根就不会向服务器发出请求,而是直接从缓存中提取结果。
比如:访问掘金站点

从Size
中可以看出,disk cache
是从硬盘中提取的缓存信息。
缓存过期了
如果缓存过期了,也并不一定向第一个请求那样服务器直接返回响应。
浏览器的缓存时间过过期了,就把该请求带上缓存的标签发送给服务器。这时如果服务器觉得这份缓存还能用,那就返回304响应码。浏览器将继续使用这份缓存。
比如:选择上面图中的其中一份缓存文件,copy
请求url
在curl
中展示

首先加-I
获取原始请求,查看etag
或last-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状态码给Cache
。Cache
就重新计时,从缓存中找出响应带上Age:0
头部返回给Client3
。
vary缓存
vary
头部是可以做一些更为复杂的缓存匹配条件,只有vary
头部指定的头部必须与请求中的头部相匹配才能使用缓存。
vary
的定义:
- "*": 意味着一定匹配失败
- 1个或多个
field-name
:指定的头部必须与请求中的头部相匹配才能使用缓存
如图所示:
1、 当Client1
携带Accept-Encoding:*
头部的GET
请求发送给server
。server
返回的是gzip
编码的响应,以及vary:Content-Encoding
头部,表示着编码方式一样的时候才能使用缓存。
2、当Client2
携带Accept-Encoding:br
头部的GET
请求发送给server
,这时请求的是br
编码。所以Cache
不能使用缓存,因为不匹配vary
的中的值,只能转发请求给源服务器server
。
3、当Client3
携带Accept-Encoding:br
头部的GET
请求发送给server
,这时Cache
有br
编码的缓存,能匹配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-age
和expires
- 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傻傻分不清楚?的更多相关文章
- URL URI傻傻分不清楚,dart告诉你该怎么用
目录 简介 dart中的URI encode和decode 解析URI 总结 简介 如果我们要访问一个网站,需要知道这个网站的地址,网站的地址一般被称为URL,他的全称是Uniform Resourc ...
- JS魔法堂:属性、特性,傻傻分不清楚
一.前言 或许你和我一样都曾经被下面的代码所困扰 var el = document.getElementById('dummy'); el.hello = "test"; con ...
- 傻傻分不清之 Cookie、Session、Token、JWT
傻傻分不清之 Cookie.Session.Token.JWT 什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证明“你是你自己”(比如:你每天上下班打卡,都需要通过指纹打 ...
- JDBC、ORM、JPA、Spring Data JPA,傻傻分不清楚?一文带你厘清个中曲直,给你个选择SpringDataJPA的理由!
序言 Spring Data JPA作为Spring Data中对于关系型数据库支持的一种框架技术,属于ORM的一种,通过得当的使用,可以大大简化开发过程中对于数据操作的复杂度. 本文档隶属于< ...
- MVP MVC MVVM 傻傻分不清
最近MVC (Model-View-Controller) 和MVVM (Model-View-ViewModel) 在微软圈成为显学,ASP.NET MVC 和WPF 的Prism (MVVM Fr ...
- Java:接口和抽象类,傻傻分不清楚?
01. 来看网络上对接口的一番解释: 接口(英文:Interface),在 Java 编程语言中是一个抽象类型,是抽象方法的集合.一个类通过继承接口的方式,从而来继承接口的抽象方法. 兄弟们,你们怎么 ...
- [转帖]十分钟快速理解DPI和PPI,不再傻傻分不清!
十分钟快速理解DPI和PPI,不再傻傻分不清! https://baijiahao.baidu.com/s?id=1605834796518990333&wfr=spider&for= ...
- OCA,OCP,OCM傻傻分不清?
可能大家知道OCA.OCP.OCM的关系是一个比一个难考,一个比一个含金量高,但是你知道具体的考试科目.考试方式.就业形势区别吗?不知道的话这篇通俗易懂的文章会让你一目了然. 区别一:含金量 ■OCA ...
- 学点经济学:M0、M1、M2、M3,傻傻分不清?(转载)
来源:http://t.10jqka.com.cn/pid_97006727.shtml 学点经济学:M0.M1.M2.M3,傻傻分不清? 25,508人浏览 2018-08-03 11:06 常听人 ...
随机推荐
- JAVA 实体类List<Entity >转 List<Map>
public static <T extends IdEntity> List<Map<Object,Object>> EntityConvertMap(List& ...
- Class的一些使用技巧?
1.forName和newInstance结合起来使用,可以根据存储在字符串中的类名创建对象.例如 Object obj = Class.forName(s).newInstance(); 2.虚拟机 ...
- javaScript编写9*9口诀
学习html+css+javaScript<!DOCTYPE html> <html> <head> <title>chaoba</title&g ...
- Java学习日报7.9
今日内容 阅读了构建之法第一章 工程师的宗旨:我构建,故我在. 哲学家的宗旨:我思,故我在. 科学家的宗旨:我发现故我在. 明天继续研究构建之法这本书!
- 如何理解SQL的可重复读和幻读之间的区别?
从本源来理解比较容易理解,如果只是描述概念和定义,容易让人云里雾里找不到方向.正好这两天在浏览mysql的文档,我可以简单在这里总结一下,帮助其他还没有理解的朋友,如果有错误也麻烦帮忙指正. 先讲一点 ...
- 我是这样理解EventLoop的
我是这样理解EventLoop的 一.前言 众所周知,在使用javascript时,经常需要考虑程序中存在异步的情况,如果对异步考虑不周,很容易在开发中出现技术错误和业务错误.作为一名合格的jav ...
- 强化学习 1 --- 马尔科夫决策过程详解(MDP)
强化学习 --- 马尔科夫决策过程(MDP) 1.强化学习介绍 强化学习任务通常使用马尔可夫决策过程(Markov Decision Process,简称MDP)来描述,具体而言:机器处在一个环境 ...
- 第十二章节 BJROBOT 摄像头寻线 【ROS全开源阿克曼转向智能网联无人驾驶车】
关于摄像头:普通摄像头, USB 免驱摄像头都可以使用. 1.如下图所示,用红色胶布在地板上贴一条线,小车摆放在线的一头处,让线在小车的中间位置,摄像头角度往下调整倾斜一点,好让摄像头识别到红线.注意 ...
- 【并发编程】- 内存模型(针对JSR-133内存模型)篇
并发编程模型 1.两个关键问题 1)线程之间如何通信 共享内存 程之间共享程序的公共状态,通过写-读内存中的公共状态进行隐式通信 消息传递 程之间没有公共状态,线程之间必须通过发送消息来显式进行通信 ...
- ARM杂散知识
画重点: 1.存储器格式:重点是大小端识别 经常考 2.对齐后结构体占用空间大小:使用aligned,packed,#pragma pack()三种方式都要会 Thumb指令集 Thumb指令集能够以 ...