给js动态添加版本号解决浏览器的缓存问题

我们知道打开网页时浏览器会加载需要的资源,比如图片、音频、js文件、css文件等。并且会把这些资源作为缓存保存下来,再次打开网页时缓存好的资源就不需要再次加载了。但是,这样有一个问题,就是当程序猿更新了网页内容后,因为浏览器缓存的存在,可能没有办法显示出更新后的内容。

今天我就遇到了这样的问题,做了一个小游戏的网页,用到了大量的图片和音频,测试时更新的js不能立刻反馈,总是需要清除缓存后刷新才能看到更新。但是大量的图片和音频,每次都需要清除缓存也太麻烦了,我就百度了一下有没有好的解决方法。

百度找到的解决方案就是给js添加版本号,这样每次更新版本号,浏览器就会重新加载js文件,如下:

document.write(<script src="js/main.js?v=+Math.random()+"></script>);

通过随机数来自动添加版本号,不需要自己手动去添加,实在是省时省力!

不过,考虑到随机数有重复的可能性,即便两次随机数正好一样的可能性及其微小,也不为0,而且随机数也不够直观,不如直接使用时间戳,如下:

document.write(<script src="js/main.js?t=+new Date().getTime()+"></script>);

永远不会停止流动的时间不可能重复,更何况还精确到了毫秒,而且时间戳也总比随机数更加明了,可以明确知道js版本的先后。

使用上述方式改了我的程序后,成功避免了缓存问题,不过打开控制台后,发现了新的问题......

谷歌浏览器对document.write()发出了警告,查看了谷歌浏览器的警告页,了解到了使用document.write()方式链接js文件会导致加载变慢,对网速不好的用户体验会变差,不过谷歌举的例子是使用2g的用户。

???

现在还有使用2g的史前人类吗?本来想无视这个警告,不过往下看后发现...谷歌浏览器在55版本之后,对于网速不好的用户,会禁止document.write()方式链接的js文件,范围扩大到了3g和状况不好的wifi...

这已经是不能忽视的情况了。

想到的解决方法如下:

<!DOCTYPE html>
<html>
	<head>
	<title> 动态的为js添加版本号,去除缓存 </title>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<meta http-equiv="Expires" content="0">
	<meta http-equiv="Pragma" content="no-cache">
	<meta http-equiv="Cache-control" content="no-cache">
	<meta http-equiv="Cache" content="no-cache">
	<link href="css/public.css" rel="stylesheet" type="text/css" />
	<link href="css/cplb.css" rel="stylesheet" type="text/css" />
	<script src="js/jquery-2.1.1.min.js" type="text/javascript"></script>


	<!-- 通过下面的方式,动态的为js添加版本号,去除缓存  -->
	<script> 
	document.write(<script src="http://localhost:8000/aaaa.js?v=+Math.random()+"></script>);
	document.write(<script src="bbbb.js?v=+Math.random()+"></script>);
	document.write(<script src="http://localhost:8000/cccc.js?v=+Math.random()+"></script>);
	</script>
	
	
	<script src="js/xxxx.js" type="text/javascript"></script>
	<script type="text/javascript">
	// JS 代码
	</script>
</head>
<body>
	<h1>给引用的js文件动态添加版本号 </h1>
</body>
</html>
<script type="text/javascript" src="js/1.js"></script>
<script type="text/javascript" src="js/2.js"></script>
<script type="text/javascript" src="js/3.js"></script>
<script type="text/javascript" src="js/4.js"></script>
<script type="text/javascript" src="js/5.js"></script>
<script>
var scripts = document.getElementsByTagName("script");
    for(var i = 0;i < scripts.length;i ++){
        if(scripts[i].src){
            scripts[i].src = scripts[i].src+"?t="+new Date().getTime();
        }
    }
</script>

添加一段代码,动态添加时间戳。但是这样做有个弊端,可能会使浏览器加载两次js文件。

暂时没有想到更好的办法,先这样,有更好的办法再补充。

经验分享 程序员 微信小程序 职场和发展