浏览器的缓存机制

以前只知道返回的状态码是304说明上次请求的资源没有被修改,可以直接访问,增加访问速度,但是当别人问304是怎么来的时候,却又不知道从何说起了。

所以今天就对于浏览器缓存机制进行了比较全面的理解。

浏览器的缓存机制就是将请求的内容保存在了本地,不用每次请求相同的内容时都需要向服务器发送同样的请求去获取,这样就大大的浪费了带宽,增加了页面的展现速度和增大了服务器的压力。
那么什么时候可以向服务器发送请求,什么时候可以直接使用本地的缓存的内容呢?

当用户第一次访问的时候,很显然必须是要向服务器端发送请求获取资源的,获取资源之后一般会保存到本地缓存,当下次访问同样的资源时,就会进行一系列的比较,会确定到底是应该在本地缓存中获取还是向服务器端获取,那么怎样判断呢?

浏览器会在第一次请求完服务器后得到响应,我们可以在服务器中设置这些响应,从而达到在以后的请求中尽量减少甚至不从服务器获取资源的目的。浏览器是依靠请求和响应中的的头信息来控制缓存的。
先来看一下http响应头中有关缓存的字段信息:
这里写图片描述

在这里我们通过三方面来进行讨论。
①. Cache-Control和Expires(响应)
②. Last-Modified和If-Modified-Since(响应和请求)
③. ETag和If-None-Match(响应和请求)

一、首先来讨论Cache-Control和Expires
是服务器端用来约定和客户端的有效时间的。
这里写图片描述

Expires规定了缓存失效时间(Date为当前时间),而Cache-Control的max-age规定了缓存有效时间(2552s),理论上这两个值计算出的有效时间应该是相同的(上图好像不一致)。Expires是HTTP1.0的东西,而Cache-Control是HTTP1.1的,规定如果max-age和Expires同时存在,前者优先级高于后者。Cache-Control的参数可以设置很多值,譬如 public/private/no-cache/no-store/no-transform/max-age/must-revalidate等等,其中每个值的含义自己可以参考相关文章。

二、 Last-Modified和If-Modified-Since(响应和请求)
这是当上面设置的服务器端时间过期过后,检查服务器端文件是否更新的一种方法。
Last-Modified(响应),标识响应资源的最后修改时间,web服务器在响应资源时,告诉浏览器资源的最后修改时间。
If-Modified-Since(请求),需要配合Cache-Control一起使用。当缓存资源过期后,也就是(Cache-Control:max-age = 0),假设该资源有Last-Modified声明,则再次向服务器请求时带上头 If-Modified-Since,表示请求时间。服务器收到请求后发现有If-Modified-Since,则与被请求资源的最后修改时间进行对比。如果Last-Modified日期比较新,说明在请求的资源被修改过,或者说已经不是缓存中的相同的资源录入,所以http就会返回200。反之说明没被修改,返回状态码304,告知浏览器继续使用所保存的缓存资源,同时更新响应头last-Modified的值(以备下次对比)。

三、 ETag和If-None-Match(响应和请求)
是第二种方式检测服务器端文件是否更新的一种方式,同样需要配合Cache-Control使用。
这里写图片描述

响应头中的ETag(实体标签)不是什么版本号或者什么,它是web服务器(比如Apache将文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。))标识文件的唯一标识符。
当缓存资源过期后,浏览器发现服务器端返回的头部信息中有ETag信息,就会在请求中加入If-None-Match信息(上一次请求后的响应头的ETag),该值在服务端和服务端代表该文件唯一的字符串对比(如果服务端该文件改变了,该值就会变),如果相同,则响应HTTP304,客户端直接读取缓存,如果不相同,则响应HTTP200,返回最新的数据资源,更新ETag值。
Etag的出现主要是为了解决Last-Modified的以下不足:

1。Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间。
2。如果某些文件会被定期生成,但有时内容并没有任何变化(仅仅改变了时间),但Last-Modified却改变了,导致文件没法使用缓存
3。有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形。

简言之,就是当浏览器缓存过期后,客户端就会重新向服务器端发送请求,请求头中带有If-None-Match(上一次请求后的响应ETag)信息,会在服务器端进行匹配,与响应头中的ETag值相等,则没有发生变化,反之发生了变化。

但当上图同时存在If-None-Match和If-Modified-Since时,前者优先。因为前者的出现就是为了解决后者的不足。

当然并不是所有请求都能,或者都被应该缓存。

HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等告诉浏览器不用缓存的请求

需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的

经过HTTPS安全加密的请求(有人也经过测试发现,ie其实在头部加入Cache-Control:max-age信息,firefox在头部加入Cache-Control:Public之后,能够对HTTPS的资源进行缓存,参考《HTTPS的七个误解》)

POST请求无法被缓存

HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存。

这里写图片描述

图片来源:http://www.cnblogs.com/Leo_wl/p/5686610.html

所以接下来简单的总结一下:

在第一次请求资源时,毫无疑问会向服务器端发送请求请求资源,当再次发送请求时就会进行一系列的比较:

首先会检查浏览器是否存在缓存,有的话比较缓存是否过期,没有过期的话,直接读取缓存中的信息,返回304。

如果缓存过期了查看响应头中是否存在ETag(实体标签)信息,有的话向服务器端发送带有If-None-Match(为上一次的ETag值)的请求,对比两个是否相等,相等的话服务器端返回304,读取缓存。不相等的话返回200,更新缓存和ETag。

如果缓存过期了并且响应头中不存在ETag信息,则继续检查是否存在Last-Modified信息,如果存在则在请求头中附上带If-Modified-Since(上次文件修改的时间)的请求。判断两者是否相等,相等的话服务器端返回304,读取缓存。不相等的话返回200,更新缓存和Last-Modified。

若缓存过期了,并且响应头中不存在ETag或者Last-Modified,则直接向服务器发送新的请求,等待请求响应,缓存协商,呈现页面。

以上就是自己对浏览器缓存机制的理解,参照的是http://blog.csdn.net/liujie19901217/article/details/52071481

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值