js页面缓存的一个解决办法

本文介绍了一种通过在HTML文件中引入JS时添加版本号来解决浏览器缓存问题的方法,并提供了一个使用Ant实现的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      由于效率的缘故,浏览器通常会缓存js文件,这就给我们带了一个问题:当服务器端部署的项目中的js文件进行了修改后,如果再客户端不手动去刷新一次页面,js的修改效果就不会起作用,因为浏览器还是用的缓存在本地的js文件。

 

       为了解决这个问题,我们采用了这个方案,每当发布新的版本部署到服务器上的时候,我们给html页面中引用的js增加一个新的后缀,形如版本号的东西。

 

<script language="javascript" src="view/shell/login.js?version=20081112050245"></script>

 

      为了自动完成这一功能,我们使用了ant,写了一个ant task来完成该项功能。

 

/**
 * 该任务遍历web目录,找出所有的模板文件,给js和css的引用加上版本号
 *
 * @version 1.0 2008-07-02
 * @author huangyuanmu 
 * @since JDK 1.5.0_8
 */
public class AddJsAndCssVersionToVm extends Task {

	private String path;

	public void execute() throws BuildException {
		Date date = new Date();
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMddhhmmss");
		String version = df.format(date);
		addVersionToVm(path, version);
	}

	/**
	 * 遍历web目录中的vm文件,给js和css的引用加上版本号
	 *
	 * @author huangyuanmu 2008-07-02
	 * @param path
	 */
	private void addVersionToVm(String path, String version) {
		File dir = new File(path);
		File[] files = dir.listFiles();
		if (files == null)
			return;
		for (int i = 0; i < files.length; i++) {
			if (files[i].isDirectory()) {
				addVersionToVm(files[i].getAbsolutePath(), version);
			} else {
				String strFileName = files[i].getAbsolutePath().toLowerCase();
				// 如果是符合条件的文件,则添加版本信息
				if (strFileName.endsWith(".vm")
						|| strFileName.endsWith(".html")
						|| strFileName.endsWith(".jsp")) {
					// RandomAccessFile raf = null;
					InputStream is = null;
					OutputStream os = null;
					List<String> contentList = new ArrayList<String>();

					// 读文件
					try {
						is = new FileInputStream(files[i]);
						Reader r = new InputStreamReader(is);
						BufferedReader br = new BufferedReader(r);
						String line = null;
						while ((line = br.readLine()) != null) {
							String modLine = getModLine(line, version);
							if (modLine != null) {
								line = modLine;
							}
							line = line + "\r\n";
							contentList.add(line);
						}
						// 关闭流
						br.close();
						r.close();
					} catch (Exception e) {
						System.out.println("读文件失败");
						e.printStackTrace();
					} finally {
						if (null != is) {
							try {
								is.close();
							} catch (Exception e) {
								e.printStackTrace();
							}
						}

					}

					// 写文件
					try {
						os = new FileOutputStream(files[i]);
						Writer w = new OutputStreamWriter(os);
						BufferedWriter bw = new BufferedWriter(w);
						for (Iterator<String> it = contentList.iterator(); it
								.hasNext();) {
							String line = it.next();
							bw.write(line);
						}
						// 更新到文件
						bw.flush();
						// 关闭流
						bw.close();
						w.close();
					} catch (Exception e) {
						System.out.println("写文件失败");
						e.printStackTrace();
					} finally {
						if (null != os) {
							try {
								os.close();
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					}
				}
			}
		}
	}

	/**
	 * 查找行中是否有js或css的引用,如果有,则加上版本号
	 *
	 * @author huangyuanmu 2008-07-03
	 * @param line
	 */
	private String getModLine(String line, String version) {
		// 增加js版本
		line.trim();
		if (line.startsWith("<script") && line.endsWith("</script>")) {
			int pos = line.indexOf(".js");
			String modLine = line.substring(0, pos) + ".js?version="
					+ version + "\"></script>";
			return modLine;
		} else if (line.startsWith("<link")
				&& line.endsWith("rel=\"stylesheet\" type=\"text/css\">")) {
			int pos = line.indexOf(".css");
			String modLine = line.substring(0, pos) + ".css?version="
					+ version
					+ "\" rel=\"stylesheet\" type=\"text/css\">";
			return modLine;
		} else {
			return null;
		}
	}

	public void setPath(String path) {
		this.path = path;
	}
}

 

      当然,这个程序的实现还有一些缺点。首先,模板文件中对js和css的引用必须规范,符合程序代码中描述的格式。另外,不管文件内容有没有改变,都加上了新的版本号,这会用户访问时不必要的网络流量,可能会对页面展现的速度产生一些影响。

 

      ant的build脚本文件在另外一篇中(http://huangyuanmu.iteye.com/admin/blogs/493144)。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值