浏览器的缓存机制

浏览器的缓存机制

浏览器缓存的全过程:

1、浏览器第一次加载资源,服务器返回200,浏览器从服务器下载资源文件,并缓存资源文件与response header,以供下次加载时对比使用。

2、下一次加载资源时,由于强制缓存优先级较高,先比较当前时间与上一次返回200时的时间差,如果没有超过cache-control设置的max-age,则没有过期,并命中强缓存,直接从本地读取资源。如果浏览器不支持HTTP1.1,则使用expires头判断是否过期。

3、如果资源已过期,则表明强制缓存没有被命中,则开始协商缓存,向服务器发送带有If-None-MatchIf-Modified-Since的请求;服务器收到请求后,优先根据Etag的值判断被请求的文件有没有做修改,Etag值一致则没有修改,命中协商缓存,返回304;如果不一致则有改动,直接返回新的资源文件带上新的Etag值并返回200;如果服务器收到的请求没有Etag值,则将If-Modified-Since和被请求文件的最后修改时间做比对,一致则命中协商缓存,返回304; 不一致则返回新的last-modified和文件并返回200

在这里插入图片描述

很多网站的资源后面都加了版本号,这样做的目的是:每次升级了 JSCSS 文件后,为了防止浏览器进行缓存,强制改变版本号,客户端浏览器就会重新下载新的 JSCSS 文件 ,以保证用户能够及时获得网站的最新更新。

协商缓存和强缓存的区别

强缓存

使用强缓存策略时,如果缓存资源有效,则直接使用缓存资源,不必再向服务器发起请求。
强缓存策略可以通过两种方式来设置,分别是http头信息中的Expires属性和Cache-Control属性:

  • (1)服务器通过在响应头中添加 Expires 属性,来指定资源的过期时间。在过期时间以内,该资源可以被缓存使用,不必再向服务器发送请求。这个时间是一个绝对时间,它是服务器的时间,因此可能存在这样的问题,就是客户端的时间和服务器端的时间不一致,或者用户可以对客户端时间进行修改的情况,这样就可能会影响缓存命中的结果。

  • (2)Expireshttp1.0中的方式,因为它的一些缺点,在 HTTP 1.1中提出了一个新的头部属性就是 Cache-Control 属性,它提供了对资源的缓存的更精确的控制。
    Cache-Control 可设置的字段:

    • public:设置了该字段值的资源表示可以被任何对象(包括:发送请求的客户端、代理服务器等等)缓存。这个字段值不常用,一般还是使用max-age=来精确控制;
    • private:设置了该字段值的资源只能被用户浏览器缓存,不允许任何代理服务器缓存。在实际开发当中,对于一些含有用户信息的 HTML, 通常都要设置这个字段值,避免代理服务器(CDN)缓存;
    • no-cache:设置了该字段需要先和服务端确认返回的资源是否发生了变化,如果资源未发生变化,则直接使用缓存好的资源;
    • no-store:设置了该字段表示禁止任何缓存,每次都会向服务端发起新的请求,拉取最新的资源;
    • max-age=:设置缓存的最大有效期,单位为秒;
    • s-maxage=:优先级高于max-age=,仅适用于共享缓存(CDN),优先 级高于max-age或者Expires头;
    • max-stale[=]:设置了该字段表明客户端愿意接收已经过期的资源, 但是不能超过给定的时间限制。

一般来说只需要设置其中一种方式就可以实现强缓存策略,当两种方式一起使用时,Cache-Control 的优先级要高于Expires
no-cacheno-store很容易混淆:

  • no-cache 是指先要和服务器确认是否有资源更新,在进行判断。也就是说没有强缓存,但是会有协商缓存;
  • no-store 是指不使用任何缓存,每次请求都直接从服务器获取资源。
协商缓存

如果命中强制缓存,我们无需发起新的请求,直接使用缓存内容,如果没有命中强制缓存,如果设置了协商缓存,这个时候协商缓存就会发挥作用了。
上面已经说到了,命中协商缓存的条件有两个: max-age=xxx 过期了 值为 no-store 使用协商缓存策略时,会先向服务器发送一个请求,如果资源没有发生修改,则返回一个 304 状态,让浏览器使用本地的缓存副本。如果资源发生了修改,则返回修改后的资源。

协商缓存也可以通过两种方式来设置,分别是http头信息中的EtagLast-Modified属性。

(1)服务器通过在响应头中添加 Last-Modified 属性来指出资源最后一次修改的时间,当浏览器下一次发起请求时,会在请求头中添加一个 If-Modified-Since 的属性,属性值为上一次资源返回时的 Last-Modified 的值。当请求发送到服务器后服务器会通过这个属性来和资源的最后一次的修改时间来进行比较,以此来判断资源是否做了修改。如果资源没有修改,那么返回 304 状态,让客户端使用本地的缓存。如果资源已经被修改了,则返回修改后的资源。使用这种方法有一个缺点,就是 Last-Modified 标注的最后修改时间只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,那么文件已将改变了,但是 Last-Modified 却没有改变,这样会造成缓存命中的不准确。

(2)因为 Last-Modified 的这种可能发生的不准确性,http 中提供了另外一种方式,那就是 Etag 属性。服务器在返回资源的时候, 在头信息中添加了 Etag 属性,这个属性是资源生成的唯一标识符, 当资源发生改变的时候,这个值也会发生改变。在下一次资源请求时, 浏览器会在请求头中添加一个 If-None-Match 属性,这个属性的值就是上次返回的资源的 Etag 的值。服务接收到请求后会根据这个值 来和资源当前的 Etag 的值来进行比较,以此来判断资源是否发生改 变,是否需要返回资源。通过这种方式,比 Last-Modified 的方式更加精确。 当 Last-ModifiedEtag 属性同时出现的时候,Etag 的优先级更高。使用协商缓存的时候,服务器需要考虑负载平衡的问题,因此多个服务器上资源的 Last-Modified 应该保持一致,因为每个服务器上 Etag 的值都不一样,因此在考虑负载平衡时,最好不要设置 Etag 属性。

总结
  • 强缓存策略和协商缓存策略在缓存命中时都会直接使用本地的缓存副本,区别只在于协商缓存会向服务器发送一次请求。它们缓存不命中时,都会向服务器发送请求来获取资源。
  • 在实际的缓存机制中,强缓存策略和协商缓存策略是一起合作使用的。
  • 浏览器首先会根据请求的信息判断,强缓存是否命中,如果命中则直接使用资源。如果不命中则根据头信息向服务器发起请求,使用协商缓存,如果协商缓存命中的话,则服务器不返回资源,浏览器直接使用本地资源的副本,如果协商缓存不命中,则浏览器返回最新的资源给浏览器。

拓展:
点击刷新按钮或者按F5按Ctrl+F5(强制刷新)地址栏回车有什么区别?

  • 点击刷新按钮或者按F5:浏览器直接对本地的缓存文件过期,但是会带上If-Modifed-SinceIf-None-Match,这就意味着服务器会对文件检查新鲜度,返回结果可能是304,也有可能是200
  • 用户按Ctrl+F5(强制刷新):浏览器不仅会对本地文件过期,而且 不会带上If-Modifed-SinceIf-None-Match,相当于之前从来没有请求过,返回结果是200
  • 地址栏回车: 浏览器发起请求,按照正常流程,本地检查是否过期,然后服务器检查新鲜度,最后返回内容。
  • 12
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值