当前位置:首页 » 文件管理 » http请求缓存

http请求缓存

发布时间: 2023-05-24 16:53:17

‘壹’ 浏览器缓存机制

有dns的地方,就有缓存。浏览器、操作系统、Local DNS、根域名服务器,它们都会对DNS结果做一定程度的缓存。

DNS查询过程如下:

首先搜索浏览器自身的DNS缓存,如果存在,则域名解析到此完成。
如果浏览器自身的缓存里面没有找到对应的条目,那么会尝试读取操作系统的hosts文件看是否存在对应的映射关系,如果存在,则域名解析到此完成。
如果本地hosts文件不存在映射关系,则查找本地DNS服务器(ISP服务器,或者自己手动设置的DNS服务器),如果存在,域名到此解析完成。
如果本地DNS服务器还没找到的话,它就会向根服务器发出请求,进行递归查询。

浏览器本地缓存失效后,浏览器会向CDN边缘节点发起请求。类似浏览器缓存,CDN边缘节点也存在着一套缓存机制。CDN边缘节点缓存策略因服务商不同而不同,但一般都会遵循http标准协议,通过http响应头中的
Cache-control: max-age 的字段来设置CDN边缘节点数据缓存时间。

当浏览器向CDN节点请求数据时,CDN节点会判断缓存数据是否过期,若缓存数据并没有过期,则直接将缓存数据返回给客户端;否则,CDN节点就会向服务器发出回源请求,从服务器拉取最新数据,更新本地缓存,并将最新数据返回给客户端。 CDN服务商一般会提供基于文件后缀、目录多个维度来指定CDN缓存时间,为用户提供更精细化的缓存管理。

CDN 优势
CDN节点解决了跨运营商和跨地域访问的问题,访问延时大大降低。
大部分请求在CDN边缘节点完成,CDN起到了分流作用,减轻了源服务器的负载。

http请求报文(request)
请求行
请求方法  空格  URL 空格  协议版本 回车符 换行符
请求头(通用信息头、请求头、实体头)
头部字段名 冒号  值  回车键 换行符
...
头部字段名 冒号  值  回车键 换行符
空行
回车符   换行符
实体主体(只有post请求有)
主体

http响应报文(response)
状态行
协议版本  空格  状态码 空格  状态码描述 回车符 换行符
响应头部
头部字段名 冒号  值   回车符 换行符
...
头部字段名 冒号  值   回车符 换行符
空行
回车符   换行符
响应正文
正文

浏览器初次向服务器发起请求后拿到请求结果,会根据响应报文中HTTP头的缓存标识,决定是否缓存返回的结果,是则将请求结果和缓存标识存入浏览器缓存中

浏览器每次发起请求,都会现在浏览器缓存中查找该请求的结果以及缓存标识
浏览器                浏览器缓存        服务器

——————第一次发起http请求——————>

<——没有该请求的缓存结果和缓存标识————

——————————————发起http请求——————————————>

<——————————返回该请求结果和缓存规则————————————

——将请求结果和缓存标识存入浏览器缓存——>

强制缓存就是向浏览器缓存查找结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程

强制缓存的情况分为三种:
1、不存在该缓存结果和缓存标识,强制缓存失效,直接向服务器发起请求
2、存在该缓存结果和缓存标识,但结果已经失效,强制缓存失效,使用协商缓存
3、存在该缓存结果和缓存标识,且该结果没有失效,强制缓存生效,直接返回该结果

控制强制缓存的字段:Expires,Cache-Control

Expires 是 HTTP/1.0 控制缓存的字段,值为服务器返回该请求的结果缓存时间
即再次发送请求是,客户端时间 小于 Expires的值,直接使用缓存结果

Cache-Control 是HTTP/1.1的规则,主要用于控制网页缓存,主要取值为:
public:所有的内容都缓存(客户端和代理服务器都可以缓存)
private:所有内容只有客户端可以缓存(默认值)
no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
no-store:即不使用强制缓存,也不使用协商缓存
max-age=xxx:缓存内容将在xxx秒后失效

Expires 是一个绝对值
Cache-Control 中 max-age 是相对值,解决了 Expires时期 服务端与客户端 可能出现时间差的问题

注:Expires和Cache-Control同时存在时,只有Cache-Control生效

协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程

协商缓存的两种情况:
1、协商缓存生效,返回304,继续使用缓存
过程:
浏览器                 浏览器缓存     服务器

————————发起http请求————————>

<——该请求的缓存结果失效,只返回缓存标识——

————————携带该资源的缓存标识,发起http请求————————>

<—————————————304,该资源无更新————————————

——————获取该请求的缓存结果——————>

<——————返回该请求的缓存结果——————

2、协商缓存失败,返回200和请求结果
过程:
浏览器                 浏览器缓存     服务器

————————发起http请求————————>

<——该请求的缓存结果失效,只返回缓存标识——

————————携带该资源的缓存标识,发起http请求————————>

<————————200,资源已更新,重新返回请求和结果———————

——将该请求结果和缓存标识存入浏览器缓存中—>

协商缓存的标识也是在响应报文的HTTP头中和请求结果一起返回给浏览器的

控制协商缓存的字段:
(1) Last-Modified/If-Modified-Since:Last-Modified是服务器响应请求是,返回该资源文件在服务器最后被修改的时间;If-Modified-Since再次发起请求时,携带上次返回的Last-Modified的值,服务器将该字段值与该资源最后修改时间对比,决定是否用缓存
(2)Etag/If-None-Match:Etag服务器响应请求时,返回当前资源文件的一个唯一标识,由服务器生成之;If-None-Match是再次发起请求时,携带上次返回的唯一标识Etag的值,服务器收到后,将该字段值与该资源在服务器上的Etag对比,一致 则返回304,否则返回200

注:Etag/If-None-Match优先级高于Last-Modified/If-Modified-Since,同时存在时只有Etag/If-None-Match生效

浏览器缓存分为:内存缓存 和 硬盘缓存

内存缓存特性:
(1)快速读取:内存缓存会将编译解析后的文件,存入该进程的内存中,便于下次运行时快速读取
(2)时效性:一旦关闭进程,进程内存清空

硬盘缓存特性:
永久性:直接写入硬盘文件中
复杂、缓慢:读取缓存对该缓存存放的硬盘文件进行I/O操作,重新解析

from memory cache:使用内存中的缓存

from disk cache:使用硬盘中的缓存

浏览器读取顺序:memory ——> disk

浏览器将js和图片等文件解析执行后直接存入内存缓存中,F5刷新页面时,from memory cache(使用内存中的缓存)
css文件存入硬盘中,F5刷新页面时,from disk cache(使用硬盘中的缓存)

参考文章
https://segmentfault.com/a/1190000017962411
https://www.cnblogs.com/chengxs/p/10396066.html

‘贰’ Okhttp解析(五)缓存的处理

大家好,之前我们讲解了Okhttp网络数据请求相关的内容,这一节我们讲讲数据缓存的处理。本节按以下内容讲解Okhttp缓存相关的内容。

缓存的使用场景很多,通过它可以将数据通过一定的规则存储起来,再次请求数据的时候就可以快速从缓存中读取了,缓存有以下优势。

HTTP本身提供了一套缓存相关的机制。这套机制定义了相关的字段和规则,用来客户端和服务端进行缓存相关的协商,如响应的数据是否需要缓存,缓存有效期,缓存是否有效,服务器端给出指示,而客户端则根据服务端的指示做具体的缓存更新和读取缓存工作。http缓存可以分为两类:

强制缓存,在缓存数据未失效的情况下,可以直接使用缓存数据,有两个字段Expires和Cache-Control用于标明失效规则。

表示过期时间,由服务端返回。那么下次请求数据时,判断这个Expires过期时间是否已经过了,如果还没有到过期时间,则使用缓存,如果过了过期时间,则重新请求服务器的数据。Expires格式如下:

不过因为服务器和客户端的时间并不是同步的,用一个绝对时间作为过期的标记并不是很明智,所以HTTP1.1之后更多的是Cache-Control,它的控制更加灵活。

表示缓存的控制,有服务端返回。它有以下几个取值:

默认情况下是private,也就是不能共享的。Cache-Control格式如下:

对比缓存,表示需要和服务端进行相关信息的对比,由服务器决定是使用缓存还是最新内容,如果服务器判定使用缓存,返回响应吗304,判定使用最新内容,则返回响应码200和最新数据。对比缓存的判定字段有两组:

ETag表示资源的一种标识信息,用于标识某个资源,由服务端返回,优先级更高。格式如下:

然后客户端再次请求时,加入字段If-None-Match,格式如下:

服务端收到请求的该字段时(之前的Etag值),和资源的唯一标识进行对比,如果相同,说明没有改动,则返回状态码304,如果不同,说明资源被改过了,则返回状态码200和整个内容数据。

Last-Modified表示资源的最近修改时间,由服务端返回,优先级更低。格式如下:

Last-Modified
由服务器返回,表示响应的数据最近修改的时间。


If-Modified-Since
由客户端请求,表示询问服务器这个时间是不是上次修改的时间。如果服务端该资源的修改时间小于等于If-Modified-Since指定的时间,说明资源没有改动,返回响应状态码304,可以使用缓存。如果服务端该资源的修改时间大于If-Modified-Since指定的时间,说明资源又有改动了,则返回响应状态码200和最新数据给客户端,客户端使用响应返回的最新数据。

Last-Modified字段的值(服务端返回的资源上次修改时间),常常被用于客户端下次请求时的If-Modified-Since字段中。

HTTP的缓存规则是优先考虑强制缓存,然后考虑对比缓存。

Okhttp缓存相关的类有如下:

要开启使用Okhttp的缓存其实很简单,只需要给OkHttpClient对象设置一个Cache对象即可,创建一个Cache时指定缓存保存的目录和缓存最大的大小即可。

那么下面我们来看看Okhttp缓存执行的大概流程

Okhttp的缓存流程分为读取缓存和存储缓存两个过程,我们分别分析。

读取使用缓存的流程从HttpEngine的sendRequest发送请求开始。

接下来我们分析

从Cache的get方法开始。它按以下步骤进行。

如果存在缓存的话,在指定的缓存目录中,会有两个文件“****.0”和“****.1”,分别存储某个请求缓存的响应头和响应体信息。(“****”是url的md5加密值)对应的ENTRY_METADATA响应头和ENTRY_BODY响应体。缓存的读取其实是由DiskLruCache来读取的,DiskLruCache是支持Lru(最近最少访问)规则的用于磁盘存储的类,对应LruCache内存存储。它在存储的内容超过指定值之后,就会根据最近最少访问的规则,把最近最少访问的数据移除,以达到总大小不超过限制的目的。

接下来我们分析CacheStrategy缓存策略是怎么判定的。

直接看CacheStrategy的get方法。缓存策略是由请求和缓存响应共同决定的。

接来下我们看看CacheControl类里有些什么。

可以发现,它就是用于描述响应的缓存控制信息。

然后我们再看看Okhttp存储缓存是怎么进行的。

存储缓存的流程从HttpEngine的readResponse发送请求开始的。

可以看到这里先通过maybeCache写入了响应头信息,再通过cacheWritingResponse写入了响应体信息。我们再进去看Cache的put方法实现。

我们继续看Cache的writeTo方法,可以看到是写入一些响应头信息。

到这里Okhttp缓存的读取和存储流程我们就清楚了。可以说,缓存的使用策略基本都是按照HTTP的缓存定义来实现的,所以对HTTP缓存相关字段的理解是很重要的。然后关于DiskLruCache是如何管理缓存文件的,这个其实也很好理解,首先的原则就是按照LRU这种最近最少使用删除的原则,当总的大小超过限定大小后,删除最近最少使用的缓存文件,它的LRU算法是使用LinkedHashMap进行维护的,这样来保证,保留的缓存文件都是更常使用的。具体实现大家可以分析DiskLruCache和LinkedHashMap的实现原理。

‘叁’ 浏览器缓存(http缓存)

浏览器缓存有两种:强制缓存和协商缓存

向浏览器缓存中查找请求结果,根据【缓存规则】决定是否使用该结果。

强制缓存失效后,携带缓存标识请求服务器,服务器根据缓存标识判断是否使用缓存

当浏览器向服务器发送请求的时候,服务器会将缓存规则放入HTTP响应的报文的HTTP头中和请求结果一起返回给浏览器(ps:下文说的时间点均为类似:Sat Aug 14 2021 11:01:52,秒级)

两个字段:Expires和Cache-Control,优先级:Cache-Control > Expires,客户端比较时间

Expires :HTTP/1.0,返回值为【到期时间点】,再次请求,客户端的时间< Expires,直接用缓存(ps:客户端与服务器端时间可能存在误差,出问题)

Cache-Control :HTTP/1.1,有以下字段

Last-Modified / If-Modified-Since 和 Etag / If-None-Match,优先级Etag > Last-Modified,服务器比较时间
Last-Modified(服务端返回客户端) / If-Modified-Since(客户端传入服务端) :两个册慎值相同,表示:资源文件在服务器最后裂姿谈被修改的时间【时间点】。

Etag(服务端返回客户端) / If-None-Match(客户端传入服务端) ,两个值相同,为当前资源文件的一个唯一标识(由服务器生成)

Etag什么时候用
雅虎禁用了Etag:因为ETag的值和服务器有关,那么对于同样的文件,可能下次请求的时候是发给不同的服务器,结果也会重新发送数据,所以就会影响网页加载速度,增加服务器的压力(但Last-Modified也与服务器有关)
主要解决的问题:

浏览器的每个tab都是一个进程
两个缓存的肆碰地方 from memory cache(内存缓存) from disk cache(硬盘缓存) ,读取顺序为memory > disk

热点内容
安卓安装证书没有怎么办 发布:2025-02-08 21:32:10 浏览:358
外交官拉杆箱怎么设密码 发布:2025-02-08 21:21:55 浏览:797
vivo手机z系列哪个配置性价比最高 发布:2025-02-08 21:17:43 浏览:10
什么是白标和服务器 发布:2025-02-08 21:15:50 浏览:481
租完服务器怎么搭建ip 发布:2025-02-08 21:11:47 浏览:394
c语言赋值后 发布:2025-02-08 21:08:40 浏览:757
dosphp 发布:2025-02-08 21:01:27 浏览:703
sm3杂凑算法 发布:2025-02-08 20:55:00 浏览:286
抽奖源码带后台 发布:2025-02-08 20:33:54 浏览:226
欧博中央空调原始密码是多少 发布:2025-02-08 20:33:47 浏览:336