现在的位置: 首页 > 综合 > 正文

浏览器缓存导致flash加载的xml无法更新

2013年12月03日 ⁄ 综合 ⁄ 共 5383字 ⁄ 字号 评论关闭

突狼四人组项目中需要音乐播放功能,在将音乐添加到播放列表的时候出了问题,每次只有第一次添加的歌曲才会显示在浏览器的播放列表中。这个模块的架构是这样的。

页面ShowMusicList.aspx是音乐的列表页面,如下图

点击"试听"按钮,跳转到音乐播放页面MusicShow.aspx。如下图

其中歌曲01是默认添加的,只有02是手动添加的。

回到音乐列表ShowMusicList.aspx页面,在点击“试听”添加一手歌曲,打开音乐播放页面MusicShow.aspx之后发现还是这两首歌曲,新添加的歌曲没有到播放列表上。

这就是遇到的问题。

下面该分析问题了。首先看代码。MusicShow.aspx页面添加了对一个flash的引用,用来播放音乐,如上图所示。代码如下:

 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
		id="FileUploadApp" width="1000" height="500"
		codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab" style="border:1px solid #333333">
		<param name="movie" value="dark_star_xml_mp3_player_final.swf" />
		<param name="quality" value="high" />
		<param name="bgcolor" value="#869ca7" />
		<param name="allowScriptAccess" value="sameDomain" />
		<param name="FlashVars" value="usercategory=">
		<embed src="FileResize.swf" quality="high" bgcolor="#869ca7"
			width="520" height="440" name="FileUploadApp" align="middle"
			play="true"
			loop="false"
			quality="high"
			allowScriptAccess="sameDomain"
			type="application/x-shockwave-flash"
			FlashVars="usercategory="
			pluginspage="http://www.adobe.com/go/getflashplayer">
		</embed>
        </object>   

项目下有一个名称为“xml”的文件夹。里面有一个名为“songs.xml”的xml文件,每次点击“试听“按钮,都会讲歌曲信息添加到这个xml文件中,然后上面的falsh插件读取xml文件,,将最新的歌曲添加到上图所示的播放器的播放列表里。如下图

<?xml version="1.0" encoding="UTF-8"?>
<songs>
  <song url="Music/Random/Mr.Saxobeat.mp3" artist="Mr.Saxobeat" track="Alexandra Stan" />
  <song url="Music/UserUpLoad/lsm/Sash - Mirror Mirror (Marc Lime & K Bastian Extended Mix).mp3" artist="Sash - Mirror Mirror (Marc Lime & K Bastian Extended Mix).mp3" track="" />
</songs>

大概就是上面这么个流程。

根据上面的流程,进行调试,测试,发现几个问题

  1. .每次点击”试听“按钮,歌曲信息其实都添加到了xml文件中,但是播放列表未更新
  2. 打开音乐列表页面,第一次点击”试听“按钮打开播放器页面的时候,歌曲能够显示到播放列表中,再次添加别的歌曲的时候就只是写到xml文件中,但是无法显示到播放列表里
  3. .关闭浏览器,重新打开音乐列表页面,然后再次点击”试听“按钮,歌曲仍然可以显示到播放列表里。但是接着”试听“按钮,情况就和上面一样了

综合上面3个问题,归纳出下面2点

  1. 第一次点击”试听“按钮后建立了缓存,以后再次点击就直接从缓存里加载,导致新的歌曲不能添加到播放列表里,那么这个缓存是服务器缓存还是客户端的浏览器缓存呢?
  2. 每次关闭浏览器再重新打开就正常执行一次,说明是客户端的浏览器缓存,因为浏览器关闭后会清除内存中的一些值,这些值指示着某个要请求的文件是否在客户端有缓存,如果有的话就从缓存 中加载,如果没有就去服务器端获取最新的,关于这点只是猜想。后面会证实这一点。

到这里可能有些人会糊涂,点击”试听按钮“后不是flash播放器在服务器端读取songs.xml文件,然后将新添加的歌曲信息添加到播放列表里吗?事实上不是这样的。这涉及到flash的一些基本问题,其实我也不怎么了解。但是可以通过调试搞清楚这个过程中到底发生了什么

首先我们要清楚,falsh是客户端插件,就是说其只有借助浏览器才能发挥作用。

前几天在讲cookie的时候也说了下IE的临时目录的作用。下面就对比临时目录的变化来分析

一切都恢复到最原始的样子。

首先清除songs.xml中的歌曲信息列表,只保留第一个默认歌曲信息

然后打开IE的临时目录,清除临时目录中的所有文件。

临时目录的路径为:C:\Users\Administrator\AppData\Local\Microsoft\Windows\Temporary Internet Files,打开方法有很多,这里不说了

打开音乐列表页面ShowMusicList.aspx,然后查看IE的临时目录文件

好,不要研究这些东东,大概就是包括刚刚访问的网页地址和一些资源文件,包括css,js,图片,网站logo等。

忽略这些,随便选一个哥,点击”试听“按钮,打开播放页面,然后刷新IE临时目录,如下图

上面的东西不少,只需要留意鼠标选中的两个文件,一个是用来播歌曲的flash插件,一个是歌曲信息文件songs.xml。

将songs.xml文件复制出来,用记事本打开(不要用浏览器打开哟),发现代码如下

<?xml version="1.0" encoding="UTF-8"?>
<songs>
  <song url="Music/Random/Mr.Saxobeat.mp3" artist="Mr.Saxobeat" track="Alexandra Stan" />
  <song url="Music/UserUpLoad/lsm/Sash - Mirror Mirror (Marc Lime & K Bastian Extended Mix).mp3" artist="Sash - Mirror Mirror (Marc Lime & K Bastian Extended Mix).mp3" track="" />
</songs>

此时和服务器端的songs.xml对比,发现代码一致。

回到音乐列表页面ShowMusicList.aspx,再随便选一首歌曲点击”试听”,又打开播放页面。此时发现三个问题

  1. 播放器的播放列表中没有最新添加的歌曲
  2. 服务器端的songs.xml文件中已经添加了刚刚“试听”的歌曲信息,如下图

<?xml version="1.0" encoding="UTF-8"?>
<songs>
  <song url="Music/Random/Mr.Saxobeat.mp3" artist="Mr.Saxobeat" track="Alexandra Stan" />
  <song url="Music/UserUpLoad/lsm/Sash - Mirror Mirror (Marc Lime & K Bastian Extended Mix).mp3" artist="Sash - Mirror Mirror (Marc Lime & K Bastian Extended Mix).mp3" track="" />
  <song url="Music/UserUpLoad/lsm/Niels Van Gogh ft. Daniel Strauss - Punkd (Damn Stupid Remix).mp3" artist="Niels Van Gogh ft. Daniel Strauss - Punkd (Damn Stupid Remix).mp3" track="" />
</songs>

3.IE临时目录下的songs.xml文件没有刚刚“试听”的歌曲信息,还是两首歌曲,如下图

<?xml version="1.0" encoding="UTF-8"?>
<songs>
  <song url="Music/Random/Mr.Saxobeat.mp3" artist="Mr.Saxobeat" track="Alexandra Stan" />
  <song url="Music/UserUpLoad/lsm/Sash - Mirror Mirror (Marc Lime & K Bastian Extended Mix).mp3" artist="Sash - Mirror Mirror (Marc Lime & K Bastian Extended Mix).mp3" track="" />
</songs>

根据上面三点,可以得出一个结论,flash播放器读取的是客户端的songs.xml文件中的歌曲信息,而不是服务器端的。

好,得出上面的结论之后,问题就是如何确保在每次点击“试听”按钮后都从服务器端获取最新的songs.xml文件,这样播放器的播放列表就是最新的了

还记得上面的一个结论吗?我说这是IE的缓存造成的。每次点击“试听”按钮,并没有从服务器端获取到最新的songs.xml文件,而是直接从IE缓存中读取了。

那么如何解决这个问题呢?类似的问题,我们刚刚讲过。刷新验证码的时候,在文件地址后面加上?,然后后面是随机数,这样就可以欺骗浏览器,从而从服务器端获取最新的文件了。可能有的同学还是不大明白为什么加上?随机数就可以实现上述效果了。下面简单分析一下:

每当浏览器向服务器请求某个文件的时候,都会首先检查一下本地有没有这个文件的缓存,那么到底缓存到哪里了呢?没错,你猜对了。就是我们在IE的临时目录下看到的这些文件。比如songs.xml。向服务器请求的songs.xml的地址是http://localhost:2444/songs.xml,而临时目录下的songs.xml的地址也是这个(这个如何看呢?打开IE,按F12,刷新播放页面,你就能看到了,当然还有一种更直接的方法,双击songs.xml文件,用浏览器打开,看看地址栏上的地址)。两个文件的地址一样,所以浏览器就直接从本地读取,而不去服务器获取了。此时我们在请求的时候在http://localhost:2444/songs.xml的后面加上?id=Math.random(),这时候和客户端的songs.xml的地址就不一样了。浏览器认为这是请求的不同的地址,就会去浏览器上获取了。

好,既然如此,我们使用这种方式来加载songs,xml文件不就可以了吗?但是我左看右看,上看下看,也找不到在MusicShow.aspx中任何指定songs.xml路径的代码,后来问了阿邱,也不知道咋回事,只是这个flash插件就要求这样用(建一个同级的xml文件夹,然后在里面添加名为songs.xml的文件),那么很显然,对songs.xml的路径指定,肯定是写到了flash插件的内部了。经过学生反编译这个flash,发现果然如此。

到此为止,这个问题的根本原因就找到了,剩下就是修改falsh文件的事情了,但是这个似乎很不容易,要是没办法,就只能换个flash插件了。

正文结束

后记

通过上面的过程,大家应该明白下面几点:

  1. 既然知道了IE的临时目录下存储的就是缓存文件,那么就应该想到在第二次点击“试听”按钮之前,删除临时目录下的songs,xml文件,这样,浏览器找不到之后,就只能去服务器获取最新的了。事实上也是这样。
  2. 在开始为了证实是客户端浏览器缓存而不是服务器缓存惹的祸,可以使用IE自带的调试工具确定,方法是按F12打开工具,在点击“试听”无法将歌曲添加到播放列表之后,选择“缓存”菜单,然后选择“清除浏览器缓存”,或者“清除此域的浏览器缓存“。如下图。然后刷新播放列表MusicShow.aspx,就会发现以前添加过但是没显示的歌曲全部都显示出来了,这有利的证明了自己的观点-浏览器缓存惹的祸。

学会客户端调试也很有用

3. 也许有人还记得,关闭浏览器重新打开后,再次点击”试听“,是正常的。有人可能会想到,既然恢复正常了,是不是缓存删除了呢?因为我们说过是缓存的问题。但是在关闭浏览器第二次打开之前查看临时目录,发现songs.xml文件并没有被删除。既然没有删除,为什么浏览器还要去服务器获取呢?还记得在开始说过的要证明的问题吗?内存中应该有一个值,这个值指示缓存的文件是否存在,如果不存在就直接去服务器获取,存在的话就读取本地的。当浏览器关闭时,浏览器维护的内存释放,再次打开浏览时请求文件时,在内存中读不到这个值,就直接去服务器读取了。当然对于这一点知识猜想,这要等比较深入的研究浏览器的缓存机制之后才能证明。

抱歉!评论已关闭.