本文说的是HTTP中控制客户端缓存的头有哪些。网上这方面的文章不少了,这里就说下我的的理解。css
在请求一个静态文件的时候(图片,css,js)等,这些文件的特色是文件不常常变化,将这些不常常变化的文件存储起来,对客户端来讲是一个优化用户浏览体验的方法。那么这个就是客户端缓存的意义了。html
windows下客户端的缓存文件存放在临时文件夹中,可是这里有个问题就是这个缓存文件存放多久呢?这个是由服务端进行设置的。算法
HTTP头中的Expires和Cache-Control就是完成这个事情的。windows
当客户端第一次访问资源的时候,服务端在返回资源内容的同时也返回了Expires: Sun, 16 Oct 2016 05:43:02 GMT。浏览器
服务端告诉浏览器: 你Y的先把这个文件给我缓存起来,在这个过时时间以前,这个文件都不会变化了,你下次须要这个文件的时候,你就不要过来找我要了,你就去缓存中拿就行了,又快又好。缓存
浏览器回答说:诺。服务器
因而在第二次html页面中又要访问这个资源的时候,而且访问的日期在Sun, 16 Oct 2016 05:43:02 GMT以前,浏览器就不去服务器那边获取文件了,本身从缓存中自食其力了。优化
可是呢,浏览器毕竟是在客户端的,客户端的时间但是不许确的,用户能够随着本身的喜爱修改本身机器的时间,好比我把我机器的时间调成Sun, 16 Oct 2016 05:43:03 GMT,那么呢?个人浏览器就不会再使用缓存了,而每次都去服务器获取文件。因而,服务器怒了:给你个绝对时间,你因为环境被修改无法判断过时,那么我就给你相对时间吧。因而就返回了Cache-Control: max-age:600,浏览器你给我缓存个10分钟去。因而浏览器只有乖乖的缓存10分钟了。url
可是问题又来了,若是有的服务器同时设置了Expires和Cache-Control怎么办呢?(不是闲的没事干,而是因为Cache-Controll是HTTP1.1中才有的)那么就是根据更先进的设置Cache-Control来为标准。htm
好了,如今有个问题,我有个文件可能时不时会更新,服务端很是但愿客户端能时不时过来问一下这个文件是否过时,若是没有过时,服务端不返回数据给你,只告诉浏览器你的缓存尚未过时(304)。而后浏览器使用本身存储的缓存来作显示。这个就叫作条件请求。
客户端第一次访问资源的时候,服务端返回资源内容的同时返回了Last-Modifed:Wed, 07 Aug 2013 15:32:18 GMT 服务端在告诉客户端:你获取的这个文件我最后的修改时间是Wed, 07 Aug 2013 15:32:18 GMT 。浏览器在获取这个文件存到缓存中的时候,给缓存中的文件同时记录上这个最后修改时间。
第二次访问的时候(咱们假设这里没有设置expires或者cache-control)。那么服务端访问资源的时候会带上If-Modify-since:Wed, 07 Aug 2013 15:32:18 GMT ;
客户端询问服务端:喂,我须要的这个资源其实我这边已经有缓存了,个人缓存文件的最后修改时间是这个是,若是你那边的资源在这个时间之后没有修改的话,你就告诉我一下就行了,不须要返回实际的资源内容。反之,要是你有修改的话,你就把文件内容返回给我吧。
服务端回应说:哦。行为是看下资源是否在这个时间后没有修改过,若是没有修改返回个304告诉客户端,我没有修改过。若是有变化了,我就返回200,而且带上资源内容。
这个条件请求还有另一种方法,打标签(Tag)。
第一次客户端访问资源的时候,服务端返回资源内容的同时返回了ETag:1234,告诉客户端:这个文件的标签是1234,我若是修改了我这边的资源的话,这个标签就会不同了。
第二次客户端访问资源的时候,因为缓存中已经有了Etag为1234的资源,客户端要去服务端查询的是这个资源有木有过时呢?因此带上了If-None-Match: 1234。告诉服务端:若是你那边的资源仍是1234标签的资源,你就返回304告诉我,不须要返回资源内容了。若是不是的话,你再返回资源内容给我就好了。服务端就比较下Etag来看是返回304仍是200。
理解了上面的缓存标签以后就很好理解各类刷新了。
刷新有三种
假设对一个资源:
浏览器第一次访问,获取资源内容和cache-control: max-age:600,Last_Modify: Wed, 10 Aug 2013 15:32:18 GMT
因而浏览器把资源文件放到缓存中,而且决定下次使用的时候直接去缓存中取了。
浏览器url回车
浏览器发现缓存中有这个文件了,好了,就不发送任何请求了,直接去缓存中获取展示。(最快)
下面我按下了F5刷新
F5就是告诉浏览器,别偷懒,好歹去服务器看看这个文件是否有过时了。因而浏览器就胆胆襟襟的发送一个请求带上If-Modify-since:Wed, 10 Aug 2013 15:32:18 GMT
而后服务器发现:诶,这个文件我在这个时间后还没修改过,不须要给你任何信息了,返回304就好了。因而浏览器获取到304后就去缓存中欢欢喜喜获取资源了。
可是呢,下面咱们按下了Ctrl+F5
这个但是要命了,告诉浏览器,你先把你缓存中的这个文件给我删了,而后再去服务器请求个完整的资源文件下来。因而客户端就完成了强行更新的操做...
还有说一下,那个ETag实际上不多人使用,由于它的计算是使用算法来得出的,而算法会占用服务端计算的资源,全部服务端的资源都是宝贵的,因此就不多使用etag了。
http://hi.baidu.com/thinkinginlamp/item/2fd6e732bf1a8ed56d15e9d0
《HTTP权威指南》