“公司网站的一次改版后,大批用户反映看到的页面出现错乱的情况,也有不少用户表示他们对这次的改版非常满意。不同的用户竟然看到了不同的效果……”
上面的情形,相信不少同仁都遇到过,在不同PC上看到的网页效果不同。怎么解决这样的问题呢?这就需要做好静态资源的版本控制。
原理
我们先来分析一下出现这个问题的原因:
用户在浏览器浏览某个网页,浏览器在加载网页中包含的各个资源(JS、css、图片)时,先会判断缓存中是否已经包含了此资源(当然这与Header中定义的Cache-Control有关,静态 很少有设置成不缓存的,我这里默认它们都是可缓存),如果包含,就不去服务器获取了。
比如改版时更改了样式表:Global.css,浏览过网站的用户,缓存里面还存在着Global.css,所以浏览器会“自作聪明”地使用缓存中的版本,自然看到的和我们期望的效果不一样了。
解决方案
如果要让浏览器的缓存更新,就需要改变此资源的URL (统一资源定位符 Uniform Resource Locator)。改变URL不意味着 需要改名,只需要在名后面增加一个后缀,比如:“Global.css?v=yyyyMMddv”,虽然定位到的资源仍然是Global.css,但如果v的值不同,浏览器会认为是不同的资源。同理,对于JS、图片来说,也是如此。
也就是说,我们每次对静态资源有更改,只需对其URL做相应更改,所有的用户就能够获取到最新的资源。
我们再来分析一下这个URL:
Global.css?v=yyyyMMddv
Global.css | 资源的位置 |
v | 可随意定义,这里的v代表“version” |
yyyyMMddv | 可随意定义,这里用“年 + 月 + 日 + 当天修订版本”,这样的URL可读性比较强。也有用随机字符串代表的 |
新的问题
在解决了上述问题后,我们可能又会遇到新的难题:如果某个CSS或者JS被上百个页面所引用,每个引用的URL又不尽相同,结果是用户看到的同样的样式定义,在页面A和页面B的效果是不一样的。如何能统一,又能有效控制所有页面引用资源的URL呢?
改进后的解决方案
本文标题是:“ASP.NET Web 开发……”,那我们这里就看一下ASP.NET的方法:
定义一个用户控件:CssGlobal.aspx:
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
在所有需要引用Global.css的页面上,使用该控件替代传统的引用:
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
以后凡是有Global.css的更改,只需要修改用户控件CssGlobal.aspx中Global.css的URL即可
对于JS、图片等其他静态资源,我们也可以用同样的方法实现良好的版本控制
本方案的缺点
1、无法在“设计”视图里看到实时的效果。不过如果美工与程序分离的不错的情况下,相信这不是大的问题;
2、在静态页面,比如.html或者.htm等无法使用用户控件的页面里,没有更好的办法。在此抛砖引玉,期待各位同仁更好的解决方案。
更新:
2008-10-14 23:42 | 12楼 chunchun的方案
对于aspx页面不需要走用户控件,aspx支持SSI命令,直接写一个CssGlobal.inc文件,文件内容:<link rel="stylesheet" type="text/css" href="http://demo.com/CSS/Global.css?v=yyyyMMddv" />
在需要引用该CSS的页面的位置<!--#include file="CssGlobal.inc"-->
最终生成的页面是经过Ssinc.dll解析的,只会看到<link rel........不会看到<!--#include ......
对于静态页面,CV文章生成页面可以生成shtml文件(或.stm、.shtm )不生成.html这样在页面中都可以用<!--#include file="CssGlobal.inc"-->
改版时要更改样式的版本号只需修改CssGlobal.inc这一个文件即可,动,静态页面都跟着改变。
对于象logo图片这种百年不变的东西 可以象baidu的节日logo那样设一个N长的客服端缓存,客户端第一次加载完了后基本在他重装系统或清浏览器缓存之前都不会到服务器下载,节省很多带宽。 换logo图片时修改的图片名。