代码改变世界

浏览器端缓存的一个小问题及解决方案

2014-09-17 14:00  FuzhePan  阅读(2972)  评论(2编辑  收藏  举报

浏览器的缓存行为可以提高网页的加载速度,但有时也会带来一些困扰。当用jQuery的get方法异步调用服务端资源的时候,浏览器会把调用结果进行缓存,拿不到实时的数据影响代码的逻辑实现,这种情况最简单的解决方法是在请求的链接后加一个随机数参数,或者用jQuery的ajax方法并设置cache为false。

但上面两种总感觉不太完美,项目中大量的使用了ajax,每一个都加一个随机参数,想想都蛋疼;使用$.ajax并设置cache为false的方式,多少有些繁琐,而且难免有开发人员忽略这个问题使用了$.get引起bug。

于是决定使用jQuery.ajaxSetup()方法,全局禁用浏览器端缓存。在一个全局的js脚本中增加以下代码:

 $.ajaxSetup({ cache: false });

新问题随之而来,这种方式不仅禁用了一般请求的缓存,也禁用js脚本文件的缓存,项目中的js文件比较多,再加上使用了大量的第三方的前端组件,每次刷新页面,这些js都要重新加载一遍,页面响应直接由原来的流畅变为龟速了。

有没有办法禁用ajax的缓存,保留脚本文件的缓存呢?

在jQuery官方文档上找到了这个方法 jQuery.ajaxPrefilter,可以对不同请求类型分别进行配置,于是可以全局禁用缓存,然后针对script开启缓存,最终代码如下:

$.ajaxSetup({ cache: false });
$.ajaxPrefilter('script', function (options) { options.cache = true; });

对于脚本的缓存,还有一个问题需要注意,如果浏览器缓存了该脚本,而服务端有修改了这个脚本,可能会引起一些错误。对脚本文件的url加一个版本号可以解决这个问题,每次修改了脚本后只需要递增这个版本号即可。如果使用mvc的Bundle来管理js文件的话就不用考虑这个了,把web.config的开关设置为release之后,Bundle框架会自动处理js文件的版本问题。