浏览器的缓存(强缓存和协商缓存)
作者:互联网
浏览器的缓存机制指的是通过在一段时间内保留已接收到的 web 资源的一个副本,如果在资源的有效时间内,发起了对这个资源的再一次请求,那么浏览器会直接使用缓存的副本,而不是向服务器发起请求。使用 web 缓存可以有效地提高页面的打开速度,减少不必要的网络带宽的消耗。
web 资源的缓存策略一般由服务器来指定,可以分为两种,分别是强缓存策略和协商缓存策略。
使用强缓存策略时,如果缓存资源有效,则直接使用缓存资源,不必再向服务器发起请求。强缓存策略可以通过两种方式来设置,分别是 http 头信息中的 Expires 属性和 Cache-Control 属性。
cache control和expires的区别
< meta http-equiv = "Cache-Control" content = "max-age=7200" />
< meta http-equiv = "Expires" content = "Mon, 20 Jul 2009 23:00:00 GMT" />
Expires 表示存在时间,允许客户端在这个时间之前不去发请求,等同max-age的效果。但是如果同时存在,则被Cache-Control的max-age覆盖。
Expires:response header里的过期时间,浏览器再次加载资源时,如果在这个过期时间内,则命中强缓存。
Cache-Control:当值设为max-age=300时,则代表在这个请求正确返回时间(浏览器也会记录下来)的5分钟内再次加载资源,就会命中强缓存。
cache-control除了该字段外,还有下面几个比较常用的设置值:
(1)no-cache:不使用本地缓存。需要使用缓存协商,先与服务器确认返回的响应是否被更改,
如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。
(2)no-store:直接禁止浏览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。
(3)public:可以被所有的用户缓存,包括终端用户和CDN等中间代理服务器。
(4)private:只能被终端用户的浏览器缓存,不允许CDN等中继缓存服务器对其缓存。
使用协商缓存策略时,会先向服务器发送一个请求,如果资源没有发生修改,则返回一个 304 状态,让浏览器使用本地的缓存副本。如果资源发生了修改,则返回修改后的资源。协商缓存也可以通过两种方式来设置,分别是 http 头信息中的 Etag 和 Last-Modified 属性。
完整的协商缓存的过程:
发请求-->看资源是否过期-->过期-->请求服务器-->服务器对比资源是否真的过期-->
没过期-->返回304状态码-->客户端用缓存的老资源。
当服务端发现资源真的过期的时候,会走如下流程:
发请求-->看资源是否过期-->过期-->请求服务器-->服务器对比资源是否真的过期
-->过期-->返回200状态码-->客户端如第一次接收该资源一样,记下它的cache-control中的max-age、etag、last-modified等。
所以协商缓存步骤总结:
请求资源时,把用户本地该资源的 etag 同时带到服务端,服务端和最新资源做对比。
如果资源没更改,返回304,浏览器读取本地缓存。
如果资源有更改,返回200,返回最新的资源。
补充一点,response header中的etag、last-modified在客户端重新向服务端发起请求时,会在request header中换个key名:
// response header
etag: '5c20abbd-e2e8'
last-modified: Mon, 24 Dec 2018 09:49:49 GMT
// request header 变为
if-none-matched: '5c20abbd-e2e8'
if-modified-since: Mon, 24 Dec 2018 09:49:49 GMT
在实际的缓存机制中,强缓存策略和协商缓存策略是一起合作使用的。
(1)浏览器首先会根据请求的信息判断,强缓存是否命中,如果命中则直接使用资源。
(2)如果不命中则根据头信息向服务器发起请求,使用协商缓存,如果协商缓存命中的话,则服务器不返回资源,浏览器直接使用本地资源的副本,如果协商缓存不命中,则浏览器返回最新的资源给浏览器。(解释如下:)
浏览器请求资源时
1.浏览器第一次加载资源,服务器返回200,
浏览器将资源文件从服务器上请求下载下来,并把response header及该请求的返回时间一并缓存;
2.下一次加载资源时,先比较当前时间和上一次返回200时的时间差,
如果没有超过cache-control设置的max-age,则没有过期,命中强缓存,不发请求直接从本地缓存读取该文件
(如果浏览器不支持HTTP1.1,则用expires判断是否过期);
如果时间过期,则向服务器发送header带有If-None-Match和If-Modified-Since的请求
3.服务器收到请求后,优先根据Etag的值判断被请求的文件有没有做修改,
Etag值一致则没有修改,命中协商缓存,返回304;
如果不一致则有改动,直接返回新的资源文件带上新的Etag值并返回200;;
4.如果服务器收到的请求没有Etag值,
则将If-Modified-Since和被请求文件的最后修改时间做比对,一致则命中协商缓存,返回304;
不一致则返回新的last-modified和文件并返回200
1、既生Last-Modified何生Etag?
(1)Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
(2)如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
(3) 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。
Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最
标签:缓存,浏览器,请求,--,协商,服务器,资源 来源: https://blog.csdn.net/weixin_48730616/article/details/118250003