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
投稿

猜你喜欢

  • python用函数创造字典的实例讲解

    2021-04-20 13:55:11
  • Golang Socket Server自定义协议的简单实现方案

    2024-04-25 13:17:40
  • Python爬虫框架scrapy实现的文件下载功能示例

    2023-09-23 09:41:56
  • JS 中forEach,for in、for of用法实例总结

    2024-04-29 13:19:00
  • vue实现添加标签demo示例代码

    2024-05-21 10:14:49
  • 整理几个js日历源代码

    2008-01-03 13:13:00
  • 打败 IE 的葵花宝典:CSS Bug Table

    2010-08-03 12:30:00
  • Pycharm 解决自动格式化冲突的设置操作

    2021-06-14 15:05:31
  • python+pandas+时间、日期以及时间序列处理方法

    2021-09-08 04:46:32
  • Go中sync 包Cond使用场景分析

    2024-01-31 20:50:05
  • python使用py2neo查询Neo4j的节点、关系及路径

    2023-02-01 18:11:52
  • Go语言原子操作及互斥锁的区别

    2024-04-26 17:23:45
  • exe反编译为.py文件的方法

    2022-06-10 16:18:16
  • 一文搞懂JSON(JavaScript Object Notation)

    2024-04-10 10:58:22
  • 段正淳的css笔记(3)标题右侧“更多”的实现

    2007-11-01 21:55:00
  • Python assert关键字原理及实例解析

    2022-11-12 09:24:10
  • go语言yaml转map、map遍历的实现

    2024-05-25 15:19:52
  • MySQL数据库中删除重复记录的方法总结[推荐]

    2024-01-13 07:13:45
  • 一个PHP的QRcode类与大家分享

    2023-06-24 05:39:33
  • 通过Py2exe将自己的python程序打包成.exe/.app的方法

    2021-07-05 11:05:55
  • asp之家 网络编程 m.aspxhome.com