作网站,不知道缓存是什么东西怎么能行! 如何实现HTTP缓存呢? 下面咱们来一步一步的探寻实现机制把。html
说明:浏览器向服务器请求资源m.png, 而后服务器响应请求--找到对应的m.png后发送给浏览器。 以后,浏览器再次向服务器请求m.png, 服务器又发回了一样的一张图片....循环往复.....web
优势:浏览器请求,服务器响应,思路清楚简单容易实现。 浏览器
缺点:每次都请求一样的资源时,服务器也在不断地响应,这是很是浪费带宽的。 缓存
说明: 一样,浏览器向服务器请求资源m.png,而后服务器找到后发送给浏览器,这时浏览器把m.png保存在本地(缓存), 这样之后每次再请求m.png时就不须要向服务器要了,直接从本地取就好了,可是下次这个m.png的内容换了呢?服务器
优势: 节省带宽(显然的,后续直接从本地取资源便可)。 网络
缺点: 若是服务器上的m.png内容改变,我就不能获得改变后的资源了,而是始终拿到本地的资源。app
说明: 浏览器向服务器请求资源m.png,而后服务器找到后发送给服务器,同时还附带额外信息---过时时间,如Expires: Friday,26 Feb 2017 10:11:22GMT。 而后浏览器将图片和过时时间同时保存在本地。 网站
浏览器第二次向服务器请求资源,这时它会先查看过时事件是否已经达到,若是在过时事件以内,就直接使用本地缓存(状态304); 若是超出了这个过时时间,就从新向服务器发送请求,服务器再次发回最新资源和最新的过时时间, 浏览器再次保存...url
优势: 一方面能够在过时时间以内就能够再也不从新请求资源,节省了带宽;另外一方面也不会像第二种方案同样,而是能够获得新资源。spa
缺点: 在过时时间以后就要从新请求资源,可是若是资源内容没改变呢? 此次拿回的资源不就浪费了带宽吗?除此以外,这种时间格式复杂,容易比对出错。
说明: 刚才的更新机制是发送来过时时间,而如今服务器在发送资源给浏览器的时候再也不发送具体的时间,而是发送一个Cache-Control,这里能够包含各类信息。如Cache-Control: max-age=300; 这种方式和上面方案相似, 只是时间过时使用数字,不容易出错。另外Cache-Control还能够是下面的一些值:
优势 : 使用max-age更加容易比对,其余的几个值使得缓存机制更增强大。
缺点:同方案三,有可能致使浪费带宽。
说明:为了解决方案四在300s后请求资源时获得了并未更新的资源而致使浪费带宽的状况,咱们在给浏览器返回m.png图片时,不只须要附加 Cache-Control: max-age=300; 再发送一个ETag字段,如 Etag:W/"e-dafdajio54fdaadf/q5w"。而后浏览器将图片和两个附加信息都保存起来, 300s内请求资源时,就从本地取,300s后请求资源时就将以前拿到的ETag信息随着请求发出,服务器接受到请求后先比对获得的ETag和服务器处图片当前的ETag,若是相同,则表示图片内容没变,就发送消息(不包含图片,304);若是ETag改变,就发送新的m.png而且再发送一个新的Etag给浏览器保存,那么这时的max-age应该也是一样须要更新的,如此循环往复......
与Etag功能相似的是Last-Modified/if-Modified-Since ,当资源过时时(max-age超时),发现资源具备Last-Modified声明(是浏览器接收到的资源最新被修改的时间),因而发送请求时带上If-Modified-Since(即刚才的Last-Modified的时间),web服务器收到请求时,将If-Modeified-Since时间的资源与当前资源对比, 若是没变, 就响应HTTP304,让浏览器使用缓存, 若是不是,就发送新的资源。
很多同窗问,不都是刷新吗?还有什么区别?其实,仍是有的。不一样的方式会控制不一样的缓存策略。
其中,在地址栏按回车又分为两种状况。
(1)请求的URI在浏览器缓存中未过时,此时,使用Firefox的firebug插件在浏览器里显示的HTTP请求消息头以下:
Host 192.168.3.174:8080
User-Agent Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language zh-cn,zh;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset GB2312,utf-8;q=0.7,*;q=0.7
Connection keep-alive
HTTP返回状态显示200 OK,可是,后台Nginx服务器的access.log并无找到该请求的记录,说明请求并无真正提交到HTTP服务器。而是被浏览器发现缓存中还有 未过时的文件,直接把请求拦截了,firebug里面显示所谓的“请求头消息”、“响应头消息”都是浏览器“伪造”的。这种刷新,使用的网络流量是最小 的,能够说彻底没有,时间消耗也是最少的。就像你找到一盒没有过时的牛奶,以为确定没有问题,谁都没告诉就喝了。
(2)请求的URI在浏览器缓存中已过时,此时,firebug显示的HTTP请求消息头以下:
Host 192.168.3.174:8080
User-Agent Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language zh-cn,zh;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset GB2312,utf-8;q=0.7,*;q=0.7
Connection keep-alive
If-Modified-Since Mon, 04 Jul 2011 10:12:40 GMT
多了一行If-Modified-Since,后台Nginx服务器的access.log也找到了该请求的记录,说明浏览器对这种状况的处理方法是:再 问一下服务器,请求的URI在某个时间以后有没有被修改过,而这个时间是由上次HTTP响应的Last-Modified决定的。服务器鉴定以后,没有修 改的话,返回304 Not Modified,浏览器收到后,从缓存里读出内容;有修改的话,返回200 OK,并返回新的内容。这种状况,就像你找到一盒已通过期的牛奶,因而问别人,还能不能喝,若是别人说能够,你就把它喝了,若是别人说不行,那你得就另外 找一盒新鲜的牛奶。
至于F5刷新,其HTTP请求消息头以下:
Host 192.168.3.174:8080
User-Agent Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language zh-cn,zh;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset GB2312,utf-8;q=0.7,*;q=0.7
Connection keep-alive
If-Modified-Since Mon, 04 Jul 2011 10:12:40 GMT
Cache-Control max-age=0
又多了一行Cache-Control: max-age=0,意思是说,我无论浏览器缓存中的文件过时没有,都去服务器询问一下,至关于上次HTTP响应的Expires暂时失效。服务器的响应处理流程同上。这种状况,就像你找到一盒牛奶,没有看它的有效期,直接就问别人能不能喝。
最后是Ctrl+F5刷新,其HTTP请求消息头以下:
Host 192.168.3.174:8080
User-Agent Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language zh-cn,zh;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset GB2312,utf-8;q=0.7,*;q=0.7
Connection keep-alive
Pragma no-cache
Cache-Control no-cache
If-Modified-Since没有了,Cache-Control换成了no-cache,此外Pragma行是为了兼容HTTP1.0,做用与 Cache-Control: no-cache是同样的。意思是,我不要缓存中的文件了,强制刷新,直接到服务器上从新下载,因而服务器的响应处理与首次请求这个URI同样,返回 200 OK和新的内容。这种刷新,使用的网络流量是最大的,也是最耗时的。这就像你虽然发现了一盒牛奶,可是把它扔掉了,直接去买一盒新的。
参考:http://www.cnblogs.com/zhuzhenwei918/p/6437574.html