今天这1课,我们主要学习下cache(缓存)。
一、缓存分类
cache(缓存)分为客户端缓存和服务端缓存
服务端缓存又分为 代理服务器缓存 和 反向代理服务器缓存(也叫网关缓存,比如 Nginx反向代理、Squid等),其实广泛使用的 CDN (快播貌似就是用的这个)也是一种服务端缓存,目的都是让用户的请求走”捷径“,并且都是缓存图片、文件等静态资源。
客户端缓存一般指的是浏览器缓存,浏览器缓存控制机制有两种:HTML Meta标签 vs. HTTP头信息。目的就是加速各种静态资源的访问,想想现在的大型网站,随便一个页面都是一两百个请求,每天 pv 都是亿级别,如果没有缓存,用户体验会急剧下降、同时服务器压力和网络带宽都面临严重的考验。
本篇主要讲http客户端缓存机制
二、fiddler查看缓存
打开fiddler抓包,用浏览器打开测试部落论坛:http://120.25.145.237/upload/forum.php
如果浏览器是第一次打开网站(以前没打开过这个论坛),抓包情况如下:
在http请求headers里cache区域,有两个参数,显示no-cache
第一次请求后,我们再次刷新(F5)下这个页面,抓包情况如下:
会看到左侧区域,有很多304显示(右侧cache中已经有了参数)说明浏览器已经使用了缓存数据
三、浏览器请求流程图
浏览器第一次请求流程图:
浏览器再次请求时:
四、服务器如何判断缓存是否过期
web服务器通过2种方式来判断浏览器缓存是否是最新的。
第一种, 浏览器把缓存文件的最后修改时间通过 header ”If-Modified-Since“来告诉Web服务器。
第二种, 浏览器把缓存文件的ETag, 通过header "If-None-Match", 来告诉Web服务器。
五、If-Modified-Since
用F5刷新当前页面(找到/upload/data/cache...这项),会发现不管怎么刷新,If-Modified-Since后面的请求时间都没有变,并且If-Modified-Since时间大于response headers里的Data时间,如下图:
说明浏览器缓存是最新的,服务器会返回304,告诉客户端使用本地缓存就行了
六、If-None-Match和ETag
Etag:
1.ETag是Web服务端产生的,然后发给浏览器客户端。浏览器客户端是不用关心Etag是如何产生的。
2. ETag是实体标签(Entity Tag)的缩写, 根据实体内容生成的一段hash字符串(类似于MD5或者SHA1之后的结果),可以标识资源的状态。 当资源发送改变时,ETag也随之发生变化。
3. ETag默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。
If-None-Match:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。
当按F5再次刷新论坛主页时,对比客户端If-None-Match和服务端Etag值是一样的,说明不用更新缓存。
七、为什么使用ETag呢?
1. 某些服务器不能精确得到文件的最后修改时间, 这样就无法通过最后修改时间来判断文件是否更新了。
2. 某些文件的修改非常频繁,在秒以下的时间内进行修改. Last-Modified只能精确到秒。
3. 一些文件的最后修改时间改变了,但是内容并未改变。 我们不希望客户端认为这个文件修改了
八、Ctrl F5
Ctrl F5是强制刷新页面,明确告诉服务端,不使用缓存
可以再部落论坛主页ctrl f5试试,左侧请求区域不会看到304了
Pragma: no-cache的作用和Cache-Control: no-cache一模一样。 都是不使用缓存。
Pragma: no-cache 是HTTP 1.0中定义的, 所以为了兼容HTTP 1.0. 所以会同时使用Pragma: no-cache和Cache-Control: no-cache
九、浏览器设置不使用缓存
打开IE。点击工具栏上的, 工具->Internet选项->常规->浏览历史记录 设置. 选择“从不”。然后保存。
然后点击“删除” 把Internet临时文件都删掉 (IE缓存的文件就是Internet临时文件)。
十、回车刷新、F5刷新、Ctrl F5刷新区别?
看到这里有不少小伙伴要怀疑了,这三种刷新还有区别么,不看不知道,一看吓一跳,区别还挺大哦。
回车刷新:可以先清空fiddler页面的所有请求(命令行输入cls,回车),然后在部落论坛首页,回车查看请求结果,会发现只有16条左右请求发送出去。而且几乎没有图片的请求,这是因为请求时会先检查本地是不是缓存了请求的图片,如果有缓存而且没有过期(过期可以通过该图片请求的header查看),他就不会发出这个图片request。
F5刷新:f5刷新比enter略慢,为什么呢,因为他还是把所有请求(大概70多条)都发给了server,只是在request里的header里有cache信息,服务器判断还没有过期,就直接返回304not modified,在fiddler里看就是这些304的请求都为灰色。因为直接返回304这样的信息,而不是图片等内容,他比ctrl f5快,但是比enter慢,因为他还是把所有请求都发了一遍,比enter的不发请求自然是慢的。
Ctrl F5刷新:这个就要慢了,应为所有的请求都是重新发送,重新从server读取内容,一点cache都没有读。为了防止在server的cache里读取,在ctrl f5刷新时,在request header 里会加pragma:no-cache cache control:no-cache。这两个就是告诉服务器到浏览器中间的所有节点,没有cache,看到这个中间节点也不查自己的cache,保证请求都是从server获得的。
如果你对这三种刷新方式已经很清楚了,能清楚说明他们的区别,说明http的缓存方式,已经基本掌握了。
十一、缓存是开发最大的敌人
先说说缓存的好处:
1. 减少了冗余的数据传输,节省了网费。
2. 减少了服务器的负担, 大大提高了网站的性能
3. 加快了客户端加载网页的速度
当然往往BUG的产生,都是因为缓存处理不当导致的。
你清空下缓存试试,然后bug就不见了!
,