Q: 浏览器缓存是个什么东东,为什么要学习浏览器缓存涅?

A: 浏览器缓存其实就是浏览器保存通过HTTP获取的所有资源,是浏览器将网络资源存储在本地的一种行为。浏览器缓存可以减少冗余数据的传输,减小服务器的负担,提高网站性能,页面利用缓存快速的响应。

任何事物都是有两面性滴,用的好,可以提升用户体验,用不好,还会降低用户体验。

缓存是什么时候用到的呢,这要从浏览器发起请求说起了,
!(浏览器缓存)[https://user-gold-cdn.xitu.io/2019/1/21/1686e2735297a596?imageView2/0/w/1280/h/960/format/webp/ignore-error/1]

浏览器缓存的分类

  1. 强缓存
  2. 协商缓存

    浏览器再向服务器请求资源时,首先判断是否命中强缓存,再判断是否命中协商缓存!

  • 强缓存
    浏览器在加载资源时,会先根据本地缓存资源的 header 中的信息判断是否命中强缓存,如果命中则直接使用缓存中的资源不会再向服务器发送请求。

这里的 header 中的信息指的是 expires 和 cahe-control.

  • Expires
    该字段是 http1.0 时的规范,它的值为一个绝对时间的 GMT 格式的时间字符串,比如 Expires:Mon,18 Oct 2066 23:59:59 GMT。这个时间代表着这个资源的失效时间,在此时间之前,即命中缓存。这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当服务器与客户端时间偏差较大时,就会导致缓存混乱。
  • Cache-Control
    Cache-Control 是 http1.1 时出现的 header 信息,主要是利用该字段的 max-age 值来进行判断,它是一个相对时间,例如 Cache-Control:max-age=3600,代表着资源的有效期是 3600 秒。cache-control 除了该字段外,还有下面几个比较常用的设置值:
    no-cache:需要进行协商缓存,发送请求到服务器确认是否使用缓存。
    no-store:禁止使用缓存,每一次都要重新请求数据。
    public:可以被所有的用户缓存,包括终端用户和 CDN 等中间代理服务器。
    private:只能被终端用户的浏览器缓存,不允许 CDN 等中继缓存服务器对其缓存。

    Cache-Control 与 Expires 可以在服务端配置同时启用,同时启用的时候 Cache-Control 优先级高。

  • 协商缓存
    当强缓存没有命中的时候,浏览器会发送一个请求到服务器,服务器根据 header 中的部分信息来判断是否命中缓存。如果命中,则返回 304 ,告诉浏览器资源未更新,可使用本地的缓存。
    这里的 header 中的信息指的是 Last-Modify/If-Modify-Since 和 ETag/If-None-Match.
    Last-Modify/If-Modify-Since
    浏览器第一次请求一个资源的时候,服务器返回的 header 中会加上 Last-Modify,Last-modify 是一个时间标识该资源的最后修改时间。
    当浏览器再次请求该资源时,request 的请求头中会包含 If-Modify-Since,该值为缓存之前返回的 Last-Modify。服务器收到 If-Modify-Since 后,根据资源的最后修改时间判断是否命中缓存。
    如果命中缓存,则返回 304,并且不会返回资源内容,并且不会返回 Last-Modify。
    缺点:
    短时间内资源发生了改变,Last-Modified 并不会发生变化。
    周期性变化。如果这个资源在一个周期内修改回原来的样子了,我们认为是可以使用缓存的,但是 Last-Modified 可不这样认为,因此便有了 ETag。
    ETag/If-None-Match
    与 Last-Modify/If-Modify-Since 不同的是,Etag/If-None-Match 返回的是一个校验码。ETag 可以保证每一个资源是唯一的,资源变化都会导致 ETag 变化。服务器根据浏览器上送的 If-None-Match 值来判断是否命中缓存。
    与 Last-Modified 不一样的是,当服务器返回 304 Not Modified 的响应时,由于 ETag 重新生成过,response header 中还会把这个 ETag 返回,即使这个 ETag 跟之前的没有变化。

Last-Modified 与 ETag 是可以一起使用的,服务器会优先验证 ETag,一致的情况下,才会继续比对 Last-Modified,最后才决定是否返回 304。

总结
当浏览器再次访问一个已经访问过的资源时,它会这样做:

  1. 看看是否命中强缓存,如果命中,就直接使用缓存了。
  2. 如果没有命中强缓存,就发请求到服务器检查是否命中协商缓存。
  3. 如果命中协商缓存,服务器会返回 304 告诉浏览器使用本地缓存。
  4. 否则,返回最新的资源

参考资料

学习浏览器缓存(http缓存)的更多相关文章

  1. 透过浏览器看HTTP缓存

    作为前端开发人员,对于我们的站点或应用的缓存机制我们能做的似乎不多,但这些却是与我们关注的性能息息相关的部分,站点没有做任何缓存机制,我们的页面可能会因为资源的下载和渲染变得很慢,但大家都知道去找前端 ...

  2. 透过浏览器看HTTP缓存(转)

    作为前端开发人员,对于我们的站点或应用的缓存机制我们能做的似乎不多,但这些却是与我们关注的性能息息相关的部分,站点没有做任何缓存机制,我们的页面可能会因为资源的下载和渲染变得很慢,但大家都知道去找前端 ...

  3. 透过浏览器看HTTP缓存[转载]

    http://www.admin10000.com/document/6299.html     作为前端开发人员,对于我们的站点或应用的缓存机制我们能做的似乎不多,但这些却是与我们关注的性能息息相关 ...

  4. 浅谈浏览器http的缓存机制

    针对浏览器的http缓存的分析也算是老生常谈了,每隔一段时间就会冒出一篇不错的文章,其原理也是各大公司面试时几乎必考的问题. 之所以还写一篇这样的文章,是因为近期都在搞新技术,想“回归”下基础,也希望 ...

  5. 浏览器 HTTP 协议缓存机制详解

    最近在准备优化日志请求时遇到了一些令人疑惑的问题,比如为什么响应头里出现了两个 cache control.为什么明明设置了 no cache 却还是发请求,为什么多次访问时有时请求里带了 etag, ...

  6. MyBatis学习总结(七)——Mybatis缓存(转载)

      孤傲苍狼 只为成功找方法,不为失败找借口! MyBatis学习总结(七)--Mybatis缓存 一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的 ...

  7. IE浏览器下ajax缓存导致数据不更新的解决方法

    摘自:http://www.iefans.net/ie-ajax-json-shuju-huancun/ 最近做设计的时候遇到一个小问题,当你用jquery的getjson函数从后台获取数据的时候,I ...

  8. HTTP协议学习---(六)缓存

    本文介绍浏览器和Web服务器之间如何处理"浏览器缓存",以及控制缓存的http header. 本文会使用Fiddler来查看HTTP request和Response, 如果不熟 ...

  9. HTML5学习总结-08 应用缓存(Application Cache)

    一 应用缓存(Application Cache) 1 应用缓存 HTML5 引入了应用程序缓存,这意味着 web 应用可进行缓存,并可在没有因特网连接时进行访问. 应用程序缓存为应用带来三个优势: ...

随机推荐

  1. ”MySQL查询优化“学习总结

    查询优化有几种方法,下面分别介绍. 切分查询 一条大的语句(涉及很多行)一次会锁住很多数据(不利于高并发). 占满整个事务日志,耗尽系统资源.阻塞很多小的但很重要的查询. 分解关联查询 关联查询分解方 ...

  2. 01: html常用标签

    目录: 1.1 web开发的三把利器介绍 1.2 网页头部head标签中几个常用标签 1.3 html常用标签归类 1.4 input系列标签 1.5 HTML其他标签 1.1 web开发的三把利器介 ...

  3. Win32 消息响应顺序

    如果窗口处理函数响应了 WM_RBUTTONUP后,不会响应WM_CONTEXTMENU消息了.

  4. Hadoop错误日志

    1.错误日志:Directory /tmp/hadoop-root/dfs/name is in an inconsistent state: storage directory does not e ...

  5. LightOJ 1199 Partitioning Game(sg函数)题解

    题意:可以把一堆石子分成不相等的两堆,不能操作为败 思路:把一个石子拆成两个,变成了两个独立的游戏,mex里加上两者的sg异或.sg打表. 代码: #include<set> #inclu ...

  6. JSON类库Jackson与JSON-lib性能对比[转]

    Jackson:http://jackson.codehaus.org/ JSON-lib:http://json-lib.sourceforge.net/ Gson:http://code.goog ...

  7. Java 类引入 学习记录规整

    之前觉得声明一个类,再把另一个包内的声明数值用第一个类打印出来就可以了(加入引入包类) 结果发现是不对的 看了看demo  得出正确结果    ImportTest 被运行 引入下面的Import类 ...

  8. linux中C语言发送广播报文

    2. 指令的解决方法: oute add -net 255.255.255.255 netmask 255.255.255.255 dev eth0 metric 1 或者 route add -ho ...

  9. (转)Linux I/O 调度方法

    Linux I/O 调度方法 转自https://blog.csdn.net/theorytree/article/details/6259104 操作系统的调度有 CPU调度    CPU sche ...

  10. django模型的继承

    很多时候,我们都不是从‘一穷二白’开始编写模型的,有时候可以从第三方库中继承,有时候可以从以前的代码中继承,甚至现写一个模型用于被其它模型继承.这样做的好处,我就不赘述了,每个学习Django的人都非 ...