资源版本管理的优化 - 问题分析 ¶
本文导航
作者:KK
发表日期:2016.11.06
- 提示:如果你的项目是前后端分离开发,前端使用gulp或fis等独立构建的话就一般不会出现这些问题,而后端输出模板并在模板里嵌PHP标签的非前后分离开发就会有这些问题
其实核心问题很简单,浏览器正常情况下只要加载过/a.js
的话,那如果再加载就会从缓存里取,不会再次请求服务器
然而当/a.js有修改时,某些情况下还是无法请求服务器获取新的,而是从缓存里面取(这里的原因并不是浏览器有BUG或者服务器有BUG,而是一些中间网络节点的影响)
所以要解决的问题就是用户如何能在我们修改了js的时候,保证他们的浏览器能实时加载到
办法就是让网址变得不同就行了,比如变成/a.js?version=1
,然后再换成/a.js?version=2
又会再重新加载了
其实这里不止是JS,而是html静态文件、css、图片等都会这样
而其中如果用?version=1
这种方案加上CDN缓存的话就存在遭遇CDN攻击的风险,所以我建议改成?version={文件MD5}
这样的方式
Yii自带的解决方法 ¶
早期的Yii2框架虽然没法解决,但大概在2.0.5版本以后就支持了Assets包输出时间戳作为版本号防止缓存
用法是配置assetsManager
组件的appendTimestamp
属性为true即可,你会发现register后模板输出的资源是一个带有时间戳作为版本标识的(这个时间戳就是文件的最后修改时间)
但是这里会导致每次输出版本资源都会读文件的修改时间(读文件信息),我则想有更好的效果,就是只更新一次版本号,所以才写了本系列的文章
看上去解决这个问题是有点儿麻烦的事情,但作为一个用心做事的人,我会从方方面面去解决各种遇到的问题,它所带来的好处是一劳永逸的————这是我2015年2月做的事情,那时候Yii2推出还不到半年