浏览器缓存
-
memory cache是浏览器为了加快读取缓存的速度而作的优化
读取速度:寄存器 > 高速cache > 内存 > 磁盘
HTTP缓存控制
条件请求
- 没有
If
开头的条件请求
头字段时
1. 用HEAD请求获取该资源的Last-modified 或 ETag
2. 获取到的Last-modified 或 ETag与缓存的资源对比
3. 若资源发生了变化,那么就发送一次GET请求获取新的资源
否则直接用缓存
- HTTP定义了一系列的
If
开头的条件请求
头字段,交由服务端来检验缓存是否过期
客户端 服务端
if-Modified-Since Last-modified (弱检验器)
if-None-Match ETag (强检验器)
-
ETag 全称 Entity Tag,资源的唯一标识符,用于解决Last-modified(单位秒)无法准确区分文件变化的问题
- 强ETag要求资源在字节级别相同
- 弱ETag要求资源在语义上相同即可(值前面有个
W/
标记)
两端缓存控制
- 以前用Expires,缺点就是客户端这边可以修改本地时间,
那就乱了呀
,而现在Cache-Control: max-age=x,用相对响应报文创建的时间(Date头字段)
-
响应报文的头字段没有对缓存进行说明时,浏览器会采用一套
启发式算法来尽量缓存一段时间
-
响应报文提供了Last-modified,但没有提供Cache-Control 或 Expires
RFC建议:max-age =(Date - Last-modified)* 10%
-
如果响应报文连Last-modified都没有呢,这个得看具体客户端是采用什么算法去缓存了
-
-
响应报文的头字段
Cache-Control: max-age=0时,浏览器会不会缓存该资源呢 ?- 会,
浏览器收到数据就会将其缓存起来
,而内部有一套算法去清除,而max-age是浏览器清除缓存的参照物
- 会,
-
返回304和200的区别在于304不会携带实体数据,只是告诉浏览器Not Modified,让它去用缓存
应用
模式1: 不常变化的资源
- 设置很长时间的强制缓存(时效性不强)
Cache-Control: max-age=31536000
模式2: 经常变化的资源
- 设置使用前需要验证的强制缓存(时效性很强)
Cache-Control: no-cache
ETag: xxx
Last-modified: xxxx
模式1和2结合
- 时效性不算太强,也不算太弱,来取个中
no-cache <=> max-age=0,must-revalidate
# 取中间
Cache-Control: max-age=600,must-revalidate
- 很容易导致不同版本的资源组合在一起,导致报错
假设有三种资源: index.html index.js index.css 存入浏览器缓存
1. index.html的缓存有效时间先到期,被浏览器清除,而index.js index.css的缓存仍存在。
2. 而此时浏览器请求到的新版本的index.html和旧版本的index.js和index.css组合很容易会报错
HTTP的代理服务
- 代理一个是链路增长(成本),另一个交由它人处理(可信度)
client <=> proxy1 server <=> ... <=> proxyn server <=> origin server
-
X-Forwarded-For
和Via
头字段经过代理节点就会添加上代理主机的信息- 前者添加
请求方的IP地址
,后者添加代理节点的Host
- X-Real-IP === 仅有一个代理节点的 X-Forwarded-For 添加的IP地址
- 前者添加
-
客户端发送请求报文后,服务端会传来一个TCP报文表示
我将要传输的报文大小,请稍等
步骤2 和 4的TCP报文作用修改为上述描述
-
而服务端发送响应报文,请求方收到后会发送TCP报文表示收到该报文
步骤5 和 7的TCP报文作用修改为上述描述
-
四次挥手并没有规定是从客户端还是服务端开始,而三次握手是客户端主动发起的
- 只不过通常都是客户端主动断开,所以看到是客户端先发送tcp,但服务端也可以主动断开(超时,短链接,节约资源)
-
因为通过X-Forwarded-For || X-IP || Via 都需要修改原始报文,添加上相应的头字段
- 一方面加大了代理节点的工作量
- 其次在SSL/TLS加密的情况下,不允许修改原始报文
-
所以出现了 "代理协议"(The PROXY protocol)
- 反向代理的负载均衡算法有哪些 ?
- 加权随机
- 加权轮询
- 最小连接法 || 最快连接法
- 源地址哈希法
缓存代理
-
需要区分的是private cache 和 public cache
HTTP协议的标准并没有规定默认使用private还是public,具体的看浏览器或代理服务器的实现,一般默认是private
源服务器的缓存控制
-
no-transform
-
An intermediate cache or proxy cannot edit the response body,Content-Encoding,Content-Range,or Content-Type
如:代理有时候会将缓存下来的数据做一些优化(图片生成png 、webp等几种格式),no-transform禁止这些变换
-
-
仅在代理服务器生效的头字段,proxy-revalidate | s-maxage | no-transform
客户端的缓存控制
- 使用
only-if-cached
请求头字段,如果代理上没有缓存或缓存过期,返回504(GateWay Timeout)
请求报文中 max-age,max-stale,min-fresh 对`当前`缓存的有效时间的约束
[min-fresh,)
[start~max-age], start > 0
[max-age,max-stale]
符合上述条件以及相应的 "Last-modified" and "ETag" 也符合的缓存返回
Vary
-
vary主要用在缓存,用来告诉缓存代理此报文依据的是哪些请求头字段返回
1. 返回带有Vary字段的响应报文给代理服务器,然后代理服务器将【w/ URL and hash】作为key,该响应报文作为value存入缓存中 * hash是根据vary字段的值,在该报文中提取出相应的值计算hash所得 2. 当有新的请求访问代理服务器时,通过计算请求报文的相关头字段,得到相应的key,看缓存中是否存在 存在,则返回缓存 否则,向源服务器获取最新资源了