浏览器缓存的前世今生

一、浏览器缓存过程

1)浏览器在加载资源时,先根据这个资源的一些http header判断它是否命中强缓存,强缓存如果命中,浏览器直接从自己的缓存中读取资源,不会发请求到服务器。比如某个css文件,如果浏览器在加载它所在的网页时,这个css文件的缓存配置命中了强缓存,浏览器就直接从缓存中加载这个css,连请求都不会发送到网页所在服务器;

2)当强缓存没有命中的时候,浏览器一定会发送一个请求到服务器,通过服务器端依据资源的另外一些http header验证这个资源是否命中协商缓存,如果协商缓存命中,服务器会将这个请求返回,但是不会返回这个资源的数据,而是告诉客户端可以直接从缓存中加载这个资源,于是浏览器就又会从自己的缓存中去加载这个资源;

3)强缓存与协商缓存的共同点是:如果命中,都是从客户端缓存中加载资源,而不是从服务器加载资源数据;区别是:强缓存不发请求到服务器,协商缓存会发请求到服务器。

4)当协商缓存也没有命中的时候,浏览器直接从服务器加载资源数据。

举例说明:

以常见的请求一个CSS样式来说。

第一次请求

通常服务器会传送这4个字段过来, 可能是4个都要,也可能一个字段也没有。这里主要讲解4个字段都存在的情况。

第二次请求

前端:首先,浏览器会检查Cache-Control与Expires,有Cache-Control的情况下,以其为标准,如果超时,则向后端发送请求,请求中会带上 If-Modified-Since,If-None-Match。

后台:后端服务器接收到请求之后,会对这两个字段进行对比,同样以If-None-Match为标准,没有If-None-Match的情况下,比对If-Modified-Since,如果比对后发现文件没有过期,即Etag没有发生变化,或者Last-Modified与If-Modified-Since一致(只存在If-Modified-Since时)。如果改变了,就会发送新的文件,反之,则直接返回304。

浏览器缓存分类

强缓存

客户端第一次问服务器要某个资源时,服务器丢还给客户端所请求的这个资源同时,告诉客户端将这个资源保存在本地,并且在未来的某个时点之前如果还需要这个资源,直接从本地获取就行了,不用向服务器请求。这种方式缓存下来的资源称为强缓存。

强缓存利用http的返回头部的中Expires(实体首部字段)或者Cache-Control(通用首部字段)两个字段来控制的,用来表示资源的缓存时间。服务器通过这两个首部字段告知客户端资源的缓存过期时间和缓存最大生命周期。客户端得知资源的缓存过期时间和最大生命周期后,即可自行判断是否可不建立与服务器的链接,直接从浏览器缓存中获取资源。

命中强缓存时,浏览器同样会受到status=200的response,chrome中可通过size区分从服务器返回的资源还是强缓存获得的资源。

Expires

该字段是http1.0时的规范,值为一个绝对时间的GMT格式的时间字符串,代表缓存资源的过期时间,在这个时点之前,即命中缓存。其过程如下:

浏览器第一次跟服务器请求一个资源时,服务器在返回这个资源时,在相应头部会加上Expires,

浏览器接收到该资源后,会把这个资源连同response header一起缓存下来;

浏览器再次请求这个资源时,会先从缓存中找到这个资源,然后获取Expires时间与当前的请求时间比较,如果Expires时间比当前浏览器的请求时间晚,说明缓存未过期,即命中缓存;

如果当前请求时间比Expires晚,说明缓存过期,即未命中缓存,浏览器就会发送请求到服务器申请获取资源。

缺点:服务器返回的Expires时点是服务器上的时间,可能与客户端有时间差,时间差太大时可能造成缓存混乱。

Cache-Control:max-age

Cache-Control有很多属性,不同的属性代表的意义也不同。

private:客户端可以缓存

public:客户端和代理服务器都可以缓存

max-age=t:缓存内容将在t秒后失效

no-cache:需要使用协商缓存来验证缓存数据

no-store:所有内容都不会缓存。

该字段是http1.1的规范,强缓存利用其max-age值来判断缓存资源的最大生命周期,它的值单位为秒,Cache-Control : max-age=3600代表缓存资源有效时间为1小时,即从第一次获取该资源起一小时内的请求都被认为可命中强缓存。其过程如下:

浏览器第一次跟服务器请求一个资源时,服务器在返回这个资源时,在相应头部会加上Cache-Control:max-age=XXXXXXXX,

浏览器接收到资源后,连同response header一起缓存下来;

浏览器再次跟服务器请求同一个资源时,会先从缓存中找到这个资源,获取date(第一次资源返回的响应时间)和max-age并计算出一个有效期(date + max-age),然后再和浏览器请求时间比较最后判断是否命中缓存(逻辑同Expires);

如果没有命中缓存,浏览器直接从服务器请求资源,Cache-Control会在重新获取到服务器返回资源时更新。

Cache-Control描述的是相对时间,采用本地时间来计算资源的有效期,所以相比Expires更可靠。

这两个Header可以只用其一,也可以一起使用。一起使用时以Cache-Control为准。

协商缓存

客户端第一次问服务器要某个资源时,服务器丢还给客户端所请求的这个资源同时,将该资源的一些信息(文件摘要、或者最后修改时间)也返回给客户端,告诉客户端将这个资源缓存在本地。当客户端下一次需要这个资源时,将请求以及相关信息(文件摘要、或者最后修改时间)一并发送给服务器,由服务器来判断客户端缓存的资源是否需要更新:如不需要更新,就直接告诉客户端获取本地缓存资源;如需要更新,则将最新的资源连同相应的信息一并返回给客户端。

当强缓存未命中时,浏览器就会发送请求到服务器,服务器会验证协商缓存是否命中,如果协商缓存命中,请求返回的http状态为304,并会显示说明Not Modified,浏览器收到该返回后,就会从缓存中加载了。

协商缓存利用Last-Modified , If-Modified-Since 和 ETag , If-None-Match这两对Header来管理。

Last-Modified & If-Modified-Since

Last-Modified为实体首部字段,值为资源最后更新时间,随服务器response返回。

If-Modified-Since为请求首部字段,通过比较两个时间来判断资源在两次请求期间是否有过修改,如果没有修改,则命中协商缓存,浏览器从缓存中获取资源;如果有过修改,则服务器返回资源,同时返回新的Last-Modified时间。其过程如下:

  1. 浏览器第一次请求服务器资源,且服务器返回了该资源时,会在response headers中加上Last-Modified,这个header表示这个资源在服务器上的最后一次修改时间;
  2. 当浏览器再次请求该资源时,会在request headers中加上If-Modified-Since,这个值即为上一次服务器返回的Last-Modified时间;
  3. 服务器再次收到资源请求时,将If-Modified-Since时间和资源在服务器上的最后修改时间与对比,如果If-Modifid-Since与最后修改时间一致,则命中缓存,服务器返回304,浏览器从缓存中获取资源;若未命中缓存,服务器返回资源同时,浏览器缓存资源的Last-Modified会被更新。

ETag & If-None-Match

有些情况下仅判断最后修改日期来验证资源是否有改动是不够的:

存在周期性重写某些资源,但资源实际包含的内容并无变化;

被修改的信息并不重要,如注释等;

Last-Modified无法精确到毫秒,但有些资源更新频率有时会小于一秒。

为解决这些问题,http允许用户对资源打上标签(ETag)来区分两个相同路径获取的资源内容是否一致。通常会采用MD5等密码散列函数对资源编码得到标签(强验证器);或者通过版本号等方式,如W/”v1.0”(W/表示弱验证器)。

ETag为相应头部字段,表示资源内容的唯一标识,随服务器response返回;

If-None-Match为请求头部字段,服务器通过比较请求头部的If-None-Match与当前资源的ETag是否一致来判断资源是否在两次请求之间有过修改,如果没有修改,则命中协商缓存,浏览器从缓存中获取资源;如果有过修改,则服务器返回资源,同时返回新的ETag。其过程如下:

  1. 服务器第一次收到浏览器发出的资源请求时,会在response headers中加上ETag,这个ETag是根据该资源生成的唯一标识,这个唯一标识是个字符串,只要服务器认为资源有变化且应该提供新的资源,则ETag就必须有变化。浏览器将资源连同ETag一并缓存。
  2. 当浏览器再一次向服务器发送该资源的请求时,会在request headers中加上If-None-Match,该值即为第一次服务器返回的ETag值;
  3. 服务器收到资源请求后,会根据要请求的资源重新计算生成相应的ETag,然后与If-None-Match比较。对比结果一致即命中缓存,不一致则未命中缓存,返回资源同时将新的ETag发送至浏览器。

协商缓存管理

Last-Modified , If-Modified-Since和ETag , If-None-Match一般同时启用,这是为了处理Last-Modified不可靠的情况。

  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值