Flash在某些多标签浏览器中的“伪沙箱”问题

作者:qhwa 来源:aliued 时间:2011-01-06 12:37:00 


在Flash播放器运行时,将不同来源的资源划分到独立的沙箱(sandbox)内,不同沙箱之间不能彼此操作数据(除非目标沙箱做过一些设置,授权其他沙箱可访问),这就是Flash的跨沙箱问题。当Flash文件(.swf) 和页面(.html)不在同一个域名下时,如果不经过Flash内部声明System.allowDomain,html无法访问flash定义的接口;不经过html设置allowScriptAccess为’always’,Flash也无法调用页面上的js函数。

那么如果html和flash都设置了互相可以访问,是否Flash和html之间就可以互相访问了呢?理论上是的,然而实际上却不是。


在Chrome、Firefox等非IE浏览器上,是没有问题的。在“纯正”的IE6、IE7、IE8上也是正常的。但是在傲游、360浏览器、腾讯浏览器等基于IE的多标签浏览器中,刷新页面的时候,Flash播放器还是会抛安全沙箱错误。

点击访问测试页面

使用上面说的“基于IE的多标签浏览器”访问,你会看到,第一次是正常的,刷新之后就不正常。如果你安装的是debug版本的播放器,可以看到Flash运行时发生了异常。

SecurityError: Error #2060: 安全沙箱冲突:ExternalInterface 调用者 http://q.pnq.cc/works/test/test-dmm-crssmn.html。
at flash.external::ExternalInterface$/_initJS()
at flash.external::ExternalInterface$/call()
at Main/start()
at Main/init()
at Main()

Flash的源码:

package{import flash.display.Sprite;import flash.external.ExternalInterface;import flash.system.Security;import flash.text.TextField;/** * Flash缓存造成的伪沙箱问题演示 * @author qhwa */public class Main extends Sprite{public function Main():void{var tf:TextField = new TextField();tf.text = 'flash ready';tf.autoSize = 'left';addChild(tf);//允许被所有其他沙箱中的js或flash调用Security.allowDomain("*");start();}private function start():void{//在基于IE的多标签浏览器中,这里运行时可能出错ExternalInterface.call("alert", "Hi, flash is ready!");ExternalInterface.addCallback('drawCircle', drawCircle);}private function drawCircle():void{TextField(getChildAt(0)).appendText('\nDraw a circle');graphics.beginFill(Math.random() * 0xFFFFFF, .5);graphics.drawCircle(Math.random() * stage.stageWidth,Math.random() * stage.stageHeight,50);graphics.endFill();}}}

似乎一旦swf是从缓存中读取的,allowScriptAccess这个配置就不起作用?为了验证是不是缓存引起的,我们每次为swf文件地址后面加上随机的数字,发现就不存在上面的问题了。可见这个问题确实是浏览器缓存造成的。

为swf文件动态加时间戳或随机数,通过防止缓存可以回避掉这个问题。不过这不是一个很好的方案,因为这会极大增加服务器的压力,并且导致页面加载速度一直都很慢。

不过好消息是,目前有个比这个更好的方案:延迟Flash的初始化功能。通过将Flash的ExternalInterface.addCallback时机延后一些,就可以解决这个问题。

修改一下Flash的代码,加一个setTimeout:

...(略)public class Main extends Sprite{public function Main():void{...(略)//start();setTimeout(start, 500);}...(略)}}

测试修改后的效果

那么,延迟多少比较合适呢?如果太多,用户会感觉到明显的延迟;太少,一些性能较差的电脑上问题依然存在。根据我一年多总结的经验,500ms是比较合理的数字。目前阿里巴巴中国网站上使用的Flash应用程序,如果有需要和js通信,都是延迟500ms初始化。

顺便说一下,延迟500ms还有另外的一个作用。IE6中,Flash初始化的时候无法得到 stage.stageWidth正确的数字,返回是0(stageHeight也一样)。延迟一点初始化就可以得到正确的数值了。

目前我还没有发现比延迟初始化更好的解决方案,如果你有更好的办法,欢迎交流!

标签:标签,浏览器,伪沙箱
0
投稿

猜你喜欢

  • 数据库自动化技术弥补数据库DBA短缺难题

    2009-02-04 16:53:00
  • IE和Firefox的js兼容性整理

    2007-11-21 19:40:00
  • 开展全面的网站评估

    2007-09-27 19:21:00
  • 社会化音乐:在夹缝中生出花来

    2009-08-24 12:37:00
  • 关于ASP代码的加密

    2007-10-15 12:30:00
  • JavaScript 组件之旅(四):测试 JavaScript 组件

    2009-10-13 20:32:00
  • AspJpeg 2.0组件使用教程(GIF篇)

    2008-12-16 19:37:00
  • 清除浮动的最简写法

    2009-03-30 15:58:00
  • CSS实现垂直居中的5种方法

    2009-03-04 12:53:00
  • 用AspJpeg调整文字水印透明,生成图片水印的效果

    2008-12-29 19:43:00
  • 谈切图优化加速图片显示—淘宝实例

    2008-01-30 12:24:00
  • Ajax+asp应用实例 注册模块,表单提交

    2011-04-08 10:47:00
  • 17个javascript自定义函数库

    2008-02-26 11:49:00
  • 小谈MySQL字符集

    2009-02-13 13:30:00
  • 利用ASP在线维护数据库

    2007-10-12 13:53:00
  • 基于RSA算法在asp中加密与解密对应的函数

    2007-11-07 21:39:00
  • PHP结构型模式之代理模式

    2023-05-25 06:55:34
  • ASP 内建六大对象简介

    2009-06-04 18:08:00
  • 如何防止页面中的敏感信息被提取

    2008-05-04 11:59:00
  • asp如何显示全部的环境变量?

    2010-06-08 09:34:00
  • asp之家 网络编程 m.aspxhome.com