JS缓存解决方案
一直以来系统每次新功能上线,前端发生改变后,用户均需要客户端清除浏览器缓存才能正常使用新功能,用户体验极差,用于早起倚天系统使用者均是企业内部人员,随着版本的迭代,系统功能不断增强,现在已经开放给企业外部服务商使用。外部人员无法像企业内部人员一样,能得到每次新功能发布后清理缓存。缓存问题已经成为系统推广的绊脚石
缓存产生原因
项目启动时,会将系统使用到的系统控制参数,用户信息,数据字典下拉框等内容缓存到js文件中,浏览器请求到服务内容后会将信息缓存在本地,再次使用是直接使用缓存内容。使用本地内容就可能导致与服务端的内容不一致。
解决思路
每次项目发版,动态的将做过改变的js脚本引入一个版本号,这样当浏览器发现请求的内容与先本地缓存中没有时就会向服务器请求资源,从而保证本地资源和服务器资源是一样的,我采用的是在ftl页面引入js文件时加上个版本号,js有改动就改动版本号
<script type="text/javascript" src="<@modulePath/>/view/supplier/ProductChangeList.js?v=c94e39fb01"></script>
方案选定
gulp可以帮助我们批量完成这个工作
gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器;她不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成;使用她,我们不仅可以很愉快的编写代码,而且大大提高我们的工作效率。
http://www.ydcss.com/archives/18
http://www.tuicool.com/articles/FJVNZf
gulp是基于nodejs,理所当然需要安装nodejs;
Java重写ftl文件
利用Java,将文件重写ftl文件中对js引入的内容
由于gulp是基于node.js开发的,因此你需要对node.js有了解。node.js多为客户端和服务端混搭的预约开发中有很多的优势。由于项目是分布式部署的,就需要我们在所有的服务器上均安装并允许gulp才能在资源发生修改的时候为它动态的追加内容,工作内容主要在与运维人员,因此我们这里使用的是java重写文件的方式完成
实现步骤
- 编写一个监听器,用于在项目启动时,去修改指定的文件内容
代码如下
/**
* 清除前端页面缓存监听器
* @date 2018-09-29
* @author MrDuan
*
*/
public class CleanPageCacheListener implements ServletContextListener {
....
/**
* 上下文初始化时执行
*/
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
// 获取项目目录下的ftl 和 js 文件
ServletContext servletContext = servletContextEvent.getServletContext();
String realPath = servletContext.getRealPath("/appweb/view/");
// 获取ftl 或js文件
List<File> fileList = new ArrayList<File>();
List<File> readFiles = readFiles(realPath,fileList);
// 为ftl追加js文件,文件名路径为 v=...
for (File file : readFiles) {
String readTextFromFile = readTextFromFile(file);
// 完整写法
String case1 = ".js\"></script>";
// 懒汉写法
String case2 = ".js\"/>";
// 已经生成过,解决项目重启的问题
String case3 =".js?v=*\"></script>";
long version = System.currentTimeMillis();
String replace = ".js?v=" + version + "\"></script>";
readTextFromFile = readTextFromFile.replace(case1, replace).replace(case2, replace).replace(case3, replace);
writeFile(file, readTextFromFile);
}
}
...
- 配置web.xml
<listener>
<listener-class>com.yianju.tangram.web.listener.CleanPageCacheListener</listener-class>
<description>clean web page cache</description>
</listener>
这样在项目启动的时候就可以修改指定目录下的指定文件内容,这样就完美的解决了页面缓存问题