文章目录
引入
看了一道面经,如下:
HTTP缓存
答:分为强缓存和协商缓存
1:首先通过Cache-Control验证强缓存是否可用,如果可用,则直接读取缓存
2:如果不可以,那么进入协商缓存,发起HTTP请求,服务器会通过请求头中是否带上Etag / If-None-Match这些条件请求字段检查资源是否更新
a. 若资源更新,那么返回资源和200状态码
b. 若未更新,那么返回304并告诉浏览器直接使用缓存获取资源
下面是了解了一下浏览器缓存机制
首先我们要了解我们常说的浏览器缓存机制其实就是HTTP缓存机制
那么,在HTTP缓存机制中,又是根据HTTP报文的缓存标识进行的,所以我们先了解一下HTTP的两种报文
-
HTTP请求(Request)报文
报文格式:请求行-HTTP头-请求体(只有post请求才有)
-
HTTP响应(Response)报文
报文格式:状态行-HTTP头-响应体
什么是缓存?
浏览器缓存是浏览器对之前请求过的文件进行缓存,以便下一次访问时重复使用,
节省带宽,
提高访问速度,
降低服务器压力
(这三大优点可以根据后续分析体会到)
为什么需要缓存?
通过HTPP协议,客户端和浏览器建立连接时需要消耗时间,
而大的响应需要在客户端和服务器之间进行多次往返通信才能获得完整的响应,
这拖延了浏览器可以使用和处理内容的时间,
增加了访问服务器的数据和资源的成本,
因此利用浏览器的缓存机制 重用 以前的数据就变成性能优化时需要考虑的事情
浏览器把资源缓存到哪去了?
这里引进两个东西:memory cache 和 disk cache
(随便打开一个网页打开控制台,刷新,浏览器会自动请求一些需要的资源,这张图就是截了随机打开的某一篇博客)
memory cache
就是将资源缓存到 内存 中,等待下次访问时不需要重新下载资源,而是直接在内存中获取。
disk cache
就是将资源缓存到 磁盘 上,等待下次访问时不用重新下载资源,而是直接在磁盘中获取
两者区别
两者都不访问服务器,memory cache的优先级高于disk cache,最后是请求网络资源
针对memory cache
1:是从内存中读取缓存
2:关闭浏览器后,数据将不存在(被释放掉了),再次打开页面,不会出现from memory cache
针对disk cache
1:是从磁盘中读取缓存
2:关闭浏览器,数据依然存在,此资源不会随着该页面的关闭而释放掉,下次打开仍然会是from disk cache
缓存
核心在于HTTP头的设定
相关字段为 Expires, Cache-Control, Last-Modified, Etag
(这四个响应头字段会在后续中解释)
缓存过程分析
第一次请求:
浏览器直接向服务器发送请求拿到返回结果,并将缓存标识存入浏览器缓存,最后页面加载成功
当浏览器再次访问一个已经访问过的资源,它会:
- 看是否命中强缓存,如果命中,就直接使用强缓存
- 如果没有命中强缓存,就发送请求到服务器检查是否命中协商缓存
- 如果命中,服务器会返回304告诉浏览器使用本地缓存
- 否则,返回新的资源,并将获取的请求结果再存入浏览器缓存中
是否要向服务器重新发起HTTP请求?
先了解两个东西:强缓存和协商缓存
强缓存
浏览器不向服务器发送任何请求,直接从本地缓存读取文件并返回status code:200
控制强缓存的字段
- Expires
- Cache-Control
Expires
Expires是HTTP/1.0控制网页缓存的字段,其值为服务器返回该请求结果缓存的到期时间,即再次发送请求,如果客户端的时间小于Expires的值时,直接使用缓存结果
Cache-Control
在HTPP/1.1中,Cache-Control是最重要的规则,主要用于控制网页缓存
问题:为什么Expires会被Cache-Control替代?
原因在于Expires的控制原理是将使用客户端的时间与服务端返回的时间做对比,
但是如果客户端与服务端的时间因为某些原因产生误差,如时区不同,
那么强制缓存就会直接失效,这样强制缓存存在就没有意义
两者对比:
Expires的时间是一个绝对值,而Cache-Control中的max-age是一个相对值
从优先级上看,Cache-Control的优先级高于Expires
协商缓存
字面意思,协商,就是与服务器协商的意思,向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源
控制协商缓存的字段
- Last-Modified / If-Modified-Since
- Etag / If-None-Match
从优先级上看,Etag / If-None-Match的优先级高于Last-Modified / If-Modified-Since
Last-Modified / If-Modified-Since
Last-Modified
是服务器响应请求时,返回该资源文件在服务器最后被修改的时间
If-Modified-Since
是客户端再次发起该请求时,携带上次请求返回的Last-Modified值,通过此字段值告诉服务器该资源上次请求返回的最后被修改时间。服务器收到该请求,发现请求头含有If-Modified-Since字段,则会根据If-Modified-Since的字段值与该资源在服务器的最后被修改时间做对比,若服务器的资源最后被修改时间大于If-Modified-Since的字段值,则重新返回资源,状态码为200;否则则返回304,代表资源无更新,可继续使用缓存文件
Etag / If-None-Match
Etag
是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)
If-None-Match
是客户端再次发起该请求时,携带上次请求返回的唯一标识Etag值,通过此字段值告诉服务器该资源上次请求返回的唯一标识值。服务器收到该请求后,发现该请求头中含有If-None-Match,则会根据If-None-Match的字段值与该资源在服务器的Etag值做对比,一致则返回304,代表资源无更新,继续使用缓存文件;不一致则重新返回资源文件,状态码为200
总结
如图:
小知识扩充:
-
当ctrl+f5强制刷新网页时,直接从服务器加载,跳过强缓存和协商缓存。
-
当f5刷新网页时,跳过强缓存,但是会检查协商缓存。
-
浏览器地址栏中写入URL,回车 浏览器发现缓存中有这个文件了,不用继续请求了,直接去缓存拿。(最快)