Flex中通过URL传参时SWF文件缓存问题求助
解决SWFLoader加载带参数SWF无法缓存的问题
嘿,这个场景我之前做Flex项目时也碰到过——每次给SWF URL加不同的查询参数,浏览器会把它当成全新资源,自然就没法缓存了。给你几个实用的解决方案,按优先级推荐:
方案1:先加载纯净SWF,加载完成后传递参数
这是最稳妥的方式,完全分离SWF资源和参数,保证SWF能被正常缓存。思路是先加载不带任何参数的SWF,等加载完成后,通过应用域(ApplicationDomain)调用被加载SWF里的方法来传递参数。
加载端代码示例:
var context:LoaderContext = new LoaderContext(); context.securityDomain = SecurityDomain.currentDomain; context.applicationDomain = new ApplicationDomain(); patViewId.loaderContext = context; // 加载不带参数的纯净SWF,确保URL固定 patViewId.source = "/Sample/view/flex/file21.swf"; // 监听加载完成事件,准备传递参数 patViewId.addEventListener(Event.COMPLETE, onSwfLoadedSuccess); function onSwfLoadedSuccess(e:Event):void { // 获取被加载SWF的实例 var loadedSwfInstance:Object = patViewId.content; // 假设被加载SWF的主类里有一个接收参数的方法:setPatientCode() if (loadedSwfInstance && loadedSwfInstance.hasOwnProperty("setPatientCode")) { // 直接调用方法传递参数 loadedSwfInstance.setPatientCode(patCode); } }
被加载SWF端需要做的:
在file21.swf的主类里,定义一个公开的方法来接收参数:
public function setPatientCode(patientCode:String):void { // 在这里处理参数逻辑,比如赋值给全局变量、初始化界面等 this._patientCode = patientCode; initView(); }
这个方案的优势是参数传递更清晰,完全符合模块化思想,而且SWF的URL固定,浏览器会正常缓存它。
方案2:把参数放到URL的Hash部分(#)
浏览器缓存资源时,通常会忽略URL中#后面的哈希部分,所以我们可以把参数从查询字符串(?)移到哈希里,这样SWF的核心URL不变,依然能被缓存。
加载端代码:
var context:LoaderContext = new LoaderContext(); context.securityDomain = SecurityDomain.currentDomain; context.applicationDomain = new ApplicationDomain(); patViewId.loaderContext = context; // 参数放到#后面 patViewId.source = "/Sample/view/flex/file21.swf#patientCode="+patCode;
被加载SWF端解析参数:
在file21.swf的主类里,通过loaderInfo获取URL并解析哈希部分:
override protected function initializationComplete():void { super.initializationComplete(); parseParamsFromHash(); } private function parseParamsFromHash():void { var fullUrl:String = LoaderInfo(this.root.loaderInfo).url; var hashStartIndex:int = fullUrl.indexOf("#"); if (hashStartIndex != -1) { var paramStr:String = fullUrl.substr(hashStartIndex + 1); var paramPairs:Array = paramStr.split("&"); var params:Object = {}; for each(var pair:String in paramPairs) { var keyValue:Array = pair.split("="); if (keyValue.length == 2) { params[keyValue[0]] = decodeURIComponent(keyValue[1]); } } // 获取patientCode参数 var patientCode:String = params["patientCode"]; if (patientCode) { // 处理参数逻辑 handlePatientCode(patientCode); } } }
这个方案的好处是改动较小,不需要调整加载流程,只需要修改参数的拼接方式和被加载端的解析逻辑。
方案3:通过共享对象(SharedObject)传递参数(同域场景)
如果是同域下的SWF,还可以用本地共享对象提前存储参数,等被加载SWF初始化后读取。不过这个方案不如前两个直接,适合一些特殊场景。
加载端存储参数:
var so:SharedObject = SharedObject.getLocal("PatientParams"); so.data.patientCode = patCode; so.flush(); // 然后加载纯净SWF patViewId.source = "/Sample/view/flex/file21.swf";
被加载端读取参数:
var so:SharedObject = SharedObject.getLocal("PatientParams"); var patientCode:String = so.data.patientCode; if (patientCode) { // 处理参数 // 用完可以清空,避免影响下次加载 so.data.patientCode = null; so.flush(); }
内容的提问来源于stack exchange,提问作者pravin
相关产品推荐
相关产品推荐

