首先先简单科普一下相关内容(其实我就是做个笔记w-。-)
HTTP协议中常用的缓存信息头关键字大概有四个:Cache-Control(HTTP1.1),Pragma(HTTP1.0),Expires和last-Modified。
Cache-Control和Pragma都是可以控制页面缓存与否的,只是支持的协议版本不同而已,通常这两个信息头都是同时存在的。而为了保险,一般也会加上Expires。
Expires则是网页缓存的失效日期,这个必须设置GMT格式时间。也可以设置成0,此时失效日期默认为Wed, 31 Dec 1969 23:59:59 GMT,页面缓存肯定是过期的。
last-Modified是页面最后的更新时间,同样需要时GMT格式时间。如果更新这个时间,Client端可以选择是使用缓存还是重新从服务器更新站点信息。
值的一提的是在JSP中设置Expires和last-Modified时要使用long值(也许和dtd有关),也就是那个1970年1月1日 00:00:00以来到期望时间点的毫秒数。
目前IE常用的HTTP协议通常都属于HTTP1.1,这里就说说这个Cache-Control。(非IE的浏览器大多都有自己的缓存机制,就不多说了。)
Cache-Control在处理缓存的时候常用的值有如下四个:
①no-cache,浏览器和缓存服务器都不应该缓存页面信息;
②public,浏览器和缓存服务器都可以缓存页面信息;
③no-store,请求和响应的信息都不被存储;
④must-revalidate,客户端每次发出请求都要验证缓存是否已经过期;
然后说说最近遇到的一个问题,最近发现IE11的一些较新的版本的补丁包更新之后,读取缓存中的非循环gif时,gif不能动了,只有首次请求该gif资源的时候才能动一次。
于是我在web.xml里添加了一个过滤类XxxFilter,重写了servlet-api.jar里面的Filter接口中的doFilter方法,在里面给ServletResponse的对象设置了header属性。
大概就是这么设置的:response.setHeader("Cache-Control", "no-cache");response.setHeader("pragma", "no-cache");
然后考虑到不可能把页面所有的资源都不做缓存,这样每次请求都要下载资源,实在有点不爽,就又增加了一层判断。
大概是这么判断的:
if(request.getServletPath().endsWith(".gif") || request.getServletPath().endsWith(".GIF")){
response.setHeader("Cache-Control", "no-cache");
response.setHeader("pragma", "no-cache");
}
这样判断当次请求的相对路径是不是一个gif图片的请求,这样就可以只把gif的缓存屏蔽掉了,瞬间觉得舒服多了。
一切搞定之后在我的64位Win7打开IE8试了一下,非常完美,只有gif文件没有缓存下来。
IE9试了下没问题,IE10有一点小问题,缓存没有能够屏蔽掉,gif文件仍然被缓存了下来,但是gif文件每次都是会动的可以原谅它了。
IE11试了下,完蛋,不仅缓存没有屏蔽掉,gif读取缓存的时候就不会动了,我又试了一下比较老的IE11补丁包,和IE10的状况是一样的,不过gif读缓存是可以动的。
经过一番查找发现,原来从IE10开始已经无法解析no-cache了,只能换用no-store了,于是把no-cache换成了no-store,同时pragma的也换掉,之前测试过的全版本IE都没有问题了。
if(request.getServletPath().endsWith(".gif") || request.getServletPath().endsWith(".GIF")){
response.setHeader("Cache-Control", "no-store");
response.setHeader("pragma", "no-store");
}
最后说下另一种处理gif再次播放不会动的办法,就是请求gif的时候给gif文件加一个时间后缀,这样每次请求都是新的gif地址,不过这样会有大量冗余缓存,不是太好。
OK收工。