一、浏览器缓存
在我们讨论浏览器缓存机制之前,我们首先要知道什么是浏览器缓存?
可能对于这个概念我们已经听过很多次,但是对它依然没有概念。但是我们一定遇见过这样的场景,当我们打开一个网页,手动刷新后,发现它加载的时间比第一次打开时快。
这是因为我们第一次打开一个网站的时候,电脑上会自动把这个网站上的一些图片和文件下载到你的电脑,当你第二次要访问这个网站的时候,图片就直接从本地显示出来了,加快打开网站的速度,这就是浏览器缓存。
二、缓存的分类
-
强缓存(本地缓存)
用户发送请求后,直接从客户端缓存中获取,不经过服务器。 -
弱缓存(协商缓存)
用户发送请求到服务器,由服务器判断是否资源发生了更新,是否从缓存中获取资源。 -
共同点
无论是强缓存还是弱缓存,最终都是从客户端缓存中获取了资源。 -
区别
强缓存不经过服务器,协商缓存经过服务器。 -
状态码
强缓存200,弱缓存304。
当我们在说浏览器缓存的时候,其实是在说这两种情况:
强缓存与弱缓存
三、缓存原理
浏览器第一次请求资源时,必须下载所有的资源,然后根据响应的header内容来决定,如何缓存资源。可能采取强缓存,也可能是弱缓存。
缓存原理流程图:
缓存流程
步骤:
1、先查找内存,如果内存中存在,从内存中加载(强缓存);
2、如果内存中未查找到,选择硬盘获取,如果硬盘中有,从硬盘中加载(强缓存);
3、如果硬盘中未查找到,那就进行网络请求(比对资源是否更新,未更新则命中弱缓存);
4、未命中弱缓存,请求后加载到的资源缓存到硬盘和内存;
四、缓存策略
通过http header来配置缓存策略,但是强缓存和弱缓存配置的字段不同。
强缓存
强缓存是利用Expires和Cache-Control,让服务器为文件设置一个过期时间,如果时间未过期,则在此时间内认为文件是最新的,命中强缓存,使用缓存文件不发送请求到服务器。
-
Expires
Expires
Expires用于设置资源的“失效时刻”,对应的值是一个具体的 GMT(格林尼治时间)。
-
Cache-Control
在HTTP1.0中,Expires 所定义的缓存时间是相对服务器上的时间而言的,因为其定义的是资源“失效时刻”,所以如果浏览器上的时间跟服务器上的时间不一致(特别是用户修改了自己电脑的系统时间),那缓存时间可能就没什么意义了。
所以为了解决这种无法保证和浏览器时间统一的问题,HTTP 1.1引入了Cache-Control,当Expires和Cache-Control同时存在时,Cache-Control优先级高于Expires。到期设置:
max-age
max-age=XX:设置缓存存储的最大周期,超过这个时间被认为过期(单位秒)。
可缓存性:
public:public
表明响应可以被任何对象缓存,包括发送请求的客服端,代理服务器等等。
private:private
表明只有用户自己的浏览器可以缓存,公共代理服务器不能缓存。
no-cache:no-cache
强制浏览器在使用cache前先提交一个请求到服务器进行确认。http请求没有减少,会减少一个响应体(文件内容),这种个选项类似弱缓存。
only-if-cache:only-if-cache
表明客户端只接受已经缓存的响应,并且不像服务器检查是否有更新。其他设置:
no-store:no-store
告诉浏览器任何情况下都不要进行缓存,不在本地保留可拷贝数据。 -
命中强缓存
命中强缓存时,有两种状态,200 (from memory cache) cache & 200 (from disk cache)。
具体区别请点这里:from memory cache与from disk cache
弱缓存
如果强缓存没有设置或者时间过期,导致未命中,则进入弱缓存阶段。
-
Last-Modified & if-modified-since:
Last-Modified
Last-Modified:服务器告诉客户端,资源最后一次修改的时间。
If-Modified-Since: 再次请求时,请求头中带有该字段,服务器会将Last-Modified和If-Modified-Since字段进行对比,如果相等,则表示没有修改过资源,返回304,使用缓存;否则,表示修改过资源,返回200和数据。
一对报文在一个请求中出现
只有这一对报文判断是否命中协商缓存的缺陷:
1、If-Modified-Since最小单位是秒,如果资源更新的速度是秒以下,缓存无法使用。
2、如果文件是通过服务器动态生成的,那么该方法的更新时间永远是生成的时间(文件内容并不改变)但是依旧起不到缓存的作用。 -
ETag
Etag和If-no-match
Etag存储的是文件的特殊标识(一般是hash生成的)。
Etag和If-no-match是一对报文。
ETag是首次请求的时候,服务器返回的。
If-None-Match也是浏览器发送到服务器验证文件是否改变的。
如果请求报文的ETag与服务器的不一致,则表示该资源已经被修改过来,需要发最新的内容给浏览器。
-
Etag/lastModified过程如下:
1、客户端第一次向服务器发起请求,服务器将附加Last-Modified/ETag到所提供的资源上去;
2、当再一次请求资源,如果没有命中强缓存,在执行在验证时,将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器;
3、服务器检查该Last-Modified或ETag,并判断出该资源页面自上次客户端请求之后还未被修改,返回响应304和一个空的响应体。使用时,需要同事使用这两个报文头,只有当两个都匹配的时候,才会命中弱缓存,否则需要重新请求资源。
网友评论