http可以说是现在前端领域(甚至整个互联网)发展过程中使用最多的一个应用层协议。其传输层一般都是使用tcp协议来保证可靠传输的,由于tcp3次握手以及4次挥手的链接建立与断开机制,导致每一次进行http请求所消耗的网络资源相对较大。。所以减少请求次数,合理的数据缓存成为互联网开发的重中之重!!
尤其在前端领域,http缓存在加快网页性能和为用户节约网络资源。作为一名小前端,又恰好面试的时候又被问蒙蔽了。。就在这里对http缓存机制进行一个小小的总结吧~~
总的来说,浏览器要从服务器上面真正的拿到数据还要通过下面几关:
Cache-Control
Cache-control是http响应头的一个字段。就是用来与客户端约定响应的数据的缓存的有效时间。
在上图中可以发现Cache-Control有一个max-age=691200的参数。这个就是表示该资源的最大生存时间为691200秒。在这个时间过后才会再次向服务器发出请求申请新的资源,否则直接使用本地资源。不过,就算生存时间过了,服务器不会这么温顺地给你发新的资源(你说发就发岂不是很丢脸???),还会进一步的进行判断,是否应该发送新的资源(看到后面就知道啦~)
除了max-age之外,Cache-Control还有别的参数可以选择:
- public:所有内容都将被缓存(客户端和代理服务器都可缓存)
- private:内容只缓存到私有缓存中(仅客户端可以缓存,代理服务器不可缓存);
- no-cache: 表示必须先与服务器确认返回的响应是否被更改,然后才能使用该响应来满足后续对同一个网址的请求。因此,如果存在合适的验证令牌 (ETag),no-cache 会发起往返通信来验证缓存的响应,如果资源未被更改,可以避免下载;
- no-store: 表示所有内容都不会被缓存到缓存或 Internet 临时文件中;
- max-age:就是我上面说的那个了(记住是秒为单位,这个最常用)~
- min-fresh:表示客户端可以接收响应时间小于当前时间加上指定时间的响应;
- max-stale:表示客户端可以接受超出超时期间的响应消息。如果指定max-stale消息的值,那么客户端可以接收超出超时期指定值之内的响应消息。
另外,浏览器的不同行为例如enter f5也会有不同的表现哦。(这个后面再总结吧~)
更多的介绍可以看看下面百科和几位老哥的总结:
百度百科:http://baike.baidu.com/link?url=pJ9rIXuRJycpHnwWae0NN_6Gl9wEOJTtp9753YOhHMMe5J1KauV3oLDQoFnTfgBej6JqH_ZBkKfVm7CK8VBLQVqr1jP3ckkjQC2jhZQ0Xbu
相关博客:http://blog.csdn.net/adparking/article/details/6673454
相关博客:https://my.oschina.net/mickelfeng/blog/103180
眼尖的盆友,可能会发现 上面的图中还有一个Expires字段,有些还有Pragma,其实这两个都是个http1.0的旧产物,跟Cache-Control设置max-age是一个意思。由于Cache-Control是http1.1提出的,而且在http1.1甚至http2.0大行其道的今日,这两个东西已经没有作用了。当Cache-Control和上面两个东西同时在http头中存在时,优先使用Cache-Control。
注意:浏览器要发出请求必须要先在max-age时间过后(可以用ctrl+F5,来跳过这个检查)。如果在一个时间内在发出请求,chrome的network会返回一个假200(其实是读缓存的假请求2333333)。
一句话总结:Cache-Control是一个用于控制(告诉)客户端,该响应的资源应该存哪里,存多久。
时间的维度上检查文件是否被修改
当浏览器发现max-age(或其他)时间过后,浏览器就开始向服务器请求获取新的资源。但是服务器并不会轻易的把新的资源返回给客户端。
当浏览器第一次访问某个网站,请求服务器时,服务器在返回的http响应头中加入Last-Modified字段,故名思意表示该资源最后一次修改是在某一个时间,如下图
浏览器在收到了Last-Modified后,在以后的每一次请求中(请求头)都会带上一个字段If-Modified-Since,这个字段的值就是上一次收到的Last-Modified的值。
服务器端则根据查看该资源是否在这个时间点后被修改过!!~如果没有被修改过,则服务器会返回304,表示资源未被修改过,使用缓存就可以了。否则如果有Etag则进行下一步判断(后面说),没有则200返回新资源。
Last-Modified 表面上非常靠谱,但是也存在一种情况,如果在服务器上,一个资源被修改了,但其实际内容根本没发生改变,会因为Last-Modified时间匹配不上而返回了整个实体给客户端(即使客户端缓存里有个一模一样的资源)。
资源内容是否被修改
ETag是http1.1中为了解决上面问题的一个http字段(一般是在响应头里面的)。这个ETag的值的什么呢?一般是由服务器根据资源的内容通过md5(或者其他)计算出的一个唯一标志。ok,浏览器得到这个东西之后,每次请求该资源的时候就会带上这个值,这个值是放在请求头的if-None-Match中,表示如果不匹配就给我新的吧,匹配就返回304~~
还有这个if-Match,这个我就不是很理解到底是什么意思了。。。知道的朋友可以告诉我一下。。。
什么是412错误,先决条件失败是什么意思。。
总结
最后盗个图:
另外,浏览器有多个刷新页面的方法,下面来看看对缓存来说都有什么区别吧(用chrome来测试,据说不同浏览器不同哦~):
- 地址栏输入地址+enter
从上面图中可以看出,这种形式的刷新页面,是会判断过期的(max-age)。。就是说是按整个缓存流程走下去。。
- F5刷新页面
哇 好多304。。说明F5刷新页面跳过了过期判断(包括了max-age、expire等等),直接从ETage开始。。
- ctrl+F5(或者network勾选Disable cache)
全部200!!说明 这个是真·强刷·无双!!从请求头的图中,可以看到浏览器是同配置Cache-Control: no-cache来叫服务器重发请求的!~
第一次写博客,各位老哥,给个面子,有错就提出来哈~~
by the offer, of the offer, for the offer!!~~~
相关参考:
浅谈浏览器http的缓存机制: http://www.cnblogs.com/vajoy/p/5341664.html
http状态码:http://www.cnblogs.com/DeasonGuan/articles/Hanami.html
浏览器行为对缓存影响:http://www.iefans.net/liulanqi-shuaxin-huancun-jizhi/