HTTP缓存解析
刷新和输入网址后回车的区别
强制刷新(ctrl+F5):不理会缓存协商,全部重新获取.此时请求中的Cache-Control值为no-cache
刷新(F5)时:当点击浏览器上的刷新,客户端发送的请求中的Cache-Control均是max-age=0,表示validate操作,发送请求到服务器要求检查cache,再更新cache,一般得到的是304 Not Modified,表示没变动
输入网址直接回车时:如果Expired或Cache-Control还未过期,则不会返回304状态,因为浏览器已经不用向web服务器发出请求
Expires与Cache-Control的区别
给静态资源(HTML文件,图片文件等)加上Expires/Cache-Control Header。如果HTTP Response中有Expires这样的Header的话,浏览器会Cache这个资源,理想状况下(注意,只是理想状况),在Expire Date之前,不会再发HTTP请求给Server要这个资源,不过Expires的值只能是一个固定日期,比如“Thu 27 Nov 2008 07:00:00 GMT”,不能是一个类似“从现在开始之后10年”这样一个随机浮动的值,如果要这样的效果,可以用Cache-Control这样的Header,如果HTTP Resposne中有这样的Header:“Cache-Control: max-age = 100”,表示这个资源在cache中的最大寿命是100秒。
同一个HTTP Response中可以同时有Expires和Cache-Control,但是Cache-Control权限比Expires大,会override它的。
HTTP/1.0有一个功能比较弱的缓存控制机制:Pragma,使用HTTP/1.0的缓存将忽略Expires和Cache-Control头。
Last-modified/If-Modified-Since与Etag/If-None-Match区别
HTTP的Response中还会有另外一个Header叫Last-Modified,比如“Last-Modified: Thu, 06 Apr 2006 21:17:12 GMT”,浏览器访问一个URI得到这样的Resposne之后,就知道这个资源最后一次的修改时间,下次需要再次获得这个资源的时候,会发一个Request给Server,不过这个Request中有一条“If-Unmodified-Since: Thu, 06 Apr 2006 21:17:12 GMT”,如果在Server端在这个日期之后对这个资源进行了修改,就会照常返回这个资源给Client端,但是如果没有修改,就会返回一个304 (Not Modified) Response而不返回资源,告诉Client端:“这个资源从上次给你之来从来没改过,你放心用你Cache中的好了。” 一个304 Response比一个静态资源通常小多了,这样就节省了网络带宽。
除了Last-Modified,HTTP Response中还可能有另外一个Header: ETag。在多台负载均衡的服务器环境下,同一个文件可能会有不同的etag或者文件修改日期,浏览器每次都会重新下载,这点要根据实际情况考虑设置。
比较一下Expires和Last-Modified这两个东西,似乎Last-Modified比不上Expires,因为虽然它能够节省一点带宽,但是还是逃不掉发一个HTTP请求出去,而Expires却使得浏览器干脆连HTTP请求都不用发。不过当用户在IE或者Firefox里面按F5或者点击Refresh按钮的时候(不是在URL栏里重新输入一遍URL然后回车),就算对于有Expires的URI,一样也会发一个HTTP请求出去,所以,Last-Modified还是要用的(返回304),而且要和Expires一起用。
Apache配置
在expires.conf设置expires,加了expires后,Cache-Control也会有相应换算后的值
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/gif "access plus 1 hour"
ExpiresByType image/jpeg "access plus 2 hour"
</IfModule>
对于一般的纯静态页面,如html、gif、jpg、css、js,默认安装的Apache服务器,不会在响应头添加这个字段。
Firefox浏览器接受到相应请求后,如果发现没有Expires字段,浏览器根据文件的类型和“Last-Modified”字段来推断出一个合适的失效时间,并存储在客户端(Firefox的缓存),推测出的时间一般是接受到响应时间后的三天左右,以后的请求就可以根据Firefox的缓存过期时间(而非http指定)来决定是否使用客户端缓存。
Apache服务器默认情况下,会对所有的静态、动态文件的响应头添加ETag字段。如果要关闭ETag,对于Apache,在httpd.conf或者.htaccess中加一行就搞定了:FileETag none
无论是纯静态页面还是动态页面,Firefox浏览器巧妙地按照接受到服务器响应的时间设置缓存页面的Last-Modified(Firefox的缓存),而不是按照http响应头部中的Last-Modified字段。
一般纯静态页面本身都会有Last-Modified信息,Apache服务器会读取页面文件中的Last-Modified信息,并添加到http响应头部。
对于动态页面,如果在页面内部没有通过函数强制加上Expires,例如header(”Expires:”。 gmdate(”D, [...]