美文网首页
http的强缓存以及协商缓存的区别

http的强缓存以及协商缓存的区别

作者: strong9527 | 来源:发表于2018-07-06 09:06 被阅读108次

    参考文章: http://www.cnblogs.com/chenqf/p/6386163.html

    作者: 木上有水

    下方部分图片也同样来自上面的博客

    本文章只是对于上文的简单总结,并且结合自己实践发现的细节问题。

    上半部分是一个简单的总结:

    首先浏览器存在一个缓存数据库,当网络请求成功后,浏览器会根据规则缓存相关数据。

    网络第一次请求

    当然缓存也分两种,一种是强制缓存,一种是协商缓存

    强制缓存:

    强制缓存

    首先对于强制缓存,有两个header的响应字段表明了强缓存的规则:

    (Expires和cache control)字段表明了强缓存的规则。

    Expires

    Expires的值为服务端返回的到期时间,即下一次请求时,请求时间小于服务端返回的到期时间,直接使用缓存数据。
      
      不过Expires是HTTP1.0的东西,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。

    另一个问题是,到期时间是由服务端生成的,但是客户端时间可能跟服务端时间有误差,这就会导致缓存命中的误差。

    所以HTTP 1.1 的版本,使用Cache-Control替代。

    Cache-Control

    Cache-Control 是最重要的规则。

    常见的取值有private、public、no-cache、max-age,no-store,默认为private。

    private: 客户端可以缓存

    public: 客户端和代理服务器都可缓存(前端的同学,可以认为public和private是一样的)

    max-age=xxx: 缓存的内容将在 xxx 秒后失效
    no-cache: 需要使用对比缓存来验证缓存数据(后面介绍)

    no-store: 所有内容都不会缓存,强制缓存,对比缓存都不会触发(对于前端开发

    协商缓存:

    对比缓存,顾名思义,需要进行比较判断是否可以使用缓存。
    浏览器第一次请求数据时,服务器会将缓存标识与数据一起返回给客户端,客户端将二者备份至缓存数据库中。
    再次请求数据时,客户端将备份的缓存标识发送给服务器,服务器根据缓存标识进行判断,判断成功后,返回304状态码,通知客户端比较成功,可以使用缓存数据。

    对比缓存也称协商缓存

    第一次网络请求:

    第一次网络请求

    浏览器再次请求

    浏览器再次请求

    自己在学习实践中的一点发现:

    首先就是如果网络请求没有强缓存字段,会发生什么?

    浏览器再次请求

    可以看到返回字段既没有expire也没有cache-control字段,可是在chrome浏览器中却是走的强缓存!

    而在下方的火狐浏览器当中确实是协商缓存,这是为什么呢?

    火狐协商缓存

    论坛对于这个问题的讨论

    浏览器的缓存有 2 种
    一种叫验证性缓存,用 ETag 、 Last-Modified 、 If-None-Match 、 If-Modified-Since 来控制,其特点是会发一个请求给服务器来确认缓存是否有效,如果有效就返回 304 ,省去传输内容的时间
    另一种叫非验证性缓存,或者有些人称为强缓存,用 Cache-Control 、 Expires 、 Pragma 来控制,其特点是一但有效就在有效期内不会发任何请求到服务器
    从描述也能很容易看出来,非验证性缓存的优先级是高于验证性缓存的,因为有它在就根本不会发请求,自然也没有什么 If-None-Match 之类的东西出现的机会了
    你看到的 200 from memory cache 就是非验证性缓存
    那么为什么在 Chrome 下会有非验证性缓存呢?就是因为你没有设置 Cache-Control 这个头,没有这个头的话,其默认值是 Private ,在标准中也明确说了:
    Unless specifically constrained by a cache-control
    directive, a caching system MAY always store a successful response
    翻译一下:如果没有 Cache-Control 进行限制,缓存系统可以对一个成功的响应进行存储
    很显然, Chrome 是遵守标准的,它在没有检查到 Cache-Control 的时候对响应做了非验证性缓存,所以你看到了 200 from memory cache
    同时 Safari 也是遵守标准的,因为标准只说了可以进行存储,而非应当或者必须,所以 Safari 不进行缓存也是合理的
    我们可以理解为,没有 Cache-Control 的情况下,缓存不缓存就看浏览器高兴,你也没什么好说的。那么你如今的需求是“明确不要非验证性缓存”,则从标准的角度来说,你必须指定相应的 Cache-Control 头

    所以总结来说,如果在chrome当中,响应header不设置cache-control,那么chrome会默认是cache-control:private

    但是这也不能一概而论:我的观察就是在chrome中js以及图片文件是默认添加private的而html文件却不会。我觉得这也很好理解,因为一般js是依附于html文件的,如果js文件有修改,一般都是直接修改js文件的hash值,这样只要保证html是最新的,就肯定能保证js文件是最新的。但是图片文件如果有更新,就会发生问题,因为图片的名字一般不是hash。。。

    如果想要chrome浏览器每一次请求文件,都走协商缓存一个办法就是:设置cache-control: max-age=0

    304

    相关文章

      网友评论

          本文标题:http的强缓存以及协商缓存的区别

          本文链接:https://www.haomeiwen.com/subject/vlnuuftx.html