当用户上报一个线上的bug后,开发者修改前端代码的bug上新后,用户反映问题依旧存在的问题...这种情况是不是曾经遇到过,这个问题跟浏览器的缓存机制有很大关系(强制缓存和协商缓存,这里我就不介绍具体的缓存机制了,网上资料一搜一大把,并且讲的很详细),这里我来说下我们是如何解决这个问题的。。。
最简单粗暴的办法就是禁止强制缓存,我们本地开发的时候经常打开chrome这个功能,启用方法如下,这样我们每次刷新页面都是最新的代码,浏览器不会缓存任何静态资源(不知道这么说是不是真的合理...)
当然这种方法是不使用于生产环境的情况:用户每次打开页面都请求所有的资源(假设我们每次不会改所有文件),那每次打开太慢了,这你受的了吗?(陈震腔)。我们在生产环境是强制缓存和协商缓存并用的,其实大部分资源走协商缓存,只有少数文件禁止强制缓存(其中就包括*.html文件)。
我们知道浏览器请求资源是根据url来判定的,如果url变了,就会使本地缓存失效,向服务器请求新的资源,我们现在在使用的前端框架大部分使用webpack构建项目,而webpack中的loader提供针对css和js文件添加hash值得方法,这样我们在发布新版本后,就会使浏览器缓存失效,从而用户能获取新的资源...但是index.html文件就悲催了(我没见过有对html文件添加hash值的...),针对html文件的缓存的策略一般是禁止强制缓存,每次请求都向服务器请求最新的资源(听说大厂spa基本都是这样,我看掘金网这样的...)。然而针对html强制不缓存有两种方法:
第一种方法就是在html文件中添加meta标签,告诉浏览器强制不缓存此文件。这种方法有一个致命问题就是添加的meta只有浏览器认识,如果中间环节恰好有缓存服务器,缓存服务器是会缓存的....,其他的问题就应该浏览器的兼容性问题,毕竟这html5的新标签。
<meta http-equiv=Cache-Control content="no-cache, no-store, must-revalidate"> <meta http-equiv=Pragma content=no-cache> <meta http-equiv=Expires content=0>
第二种方法就是在nginx服务器location配置不缓存html类型的文件。
其实以上方法就可以开头我们提到的问题了...在最后我贴一个nginx针对一个特定文件的强制不缓存策略配置,我们在项目中遇到了,我们使用了一个dyConfig.js,这个文件暂时没想到版本控制加hash办法,这个文件是独立于代码的。。。
location / { root html; index index.html index.htm;
if ($request_filename ~* .*dyConfig.js$) { add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate"; } }
最后,提醒下大家,在location中使用if指令要多加小心,if这个指令是有坑的,nginx官方wiki有介绍:If Is Evil
参考资料:如何解决静态资源的缓存问题