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也一样)。延迟一点初始化就可以得到正确的数值了。
目前我还没有发现比延迟初始化更好的解决方案,如果你有更好的办法,欢迎交流!


猜你喜欢
- 这篇文章主要介绍了Pycharm debug调试时带参数过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
- 目录安装PyPDF2模块创建文件,准备PDF文档万事俱备,准备开拆文档的拆分思路python拆分计算公式:具体怎么拆?完整拆分程序:列表拆分
- 本文回答了如下问题:“MySQL服务器有多稳定?”,以及“在本项目中我能依靠My
- 一、requestsrequest的说法网上有很多,简单来说就是就是python里的很强大的类库,可以帮助你发很多的网络请求,比如get,p
- 1、实现的效果示例代码:df=pd.DataFrame({'A':[1,2],'B':[[1,2],[1,2
- 实例如下:<?php /** * @name thumb 缩略图函数 * @param sting  
- 远程登陆SQLServer (2014)数据库,供大家参考,具体内容如下两台电脑,同一个局域网内,IP同一网段配置:Computer1: W
- 网关是什么简单来说,网关就是暴露给外部的请求入口。就和门卫一样,外面的人想要进来,必须要经过门卫。当然,网关并不一定是必须的,后端服务通过h
- 想必很多初次接触python都会见到这样一个语句,if __name__ == "__main__":那么这个语句到底是
- 本文实例讲述了JS实现匀加速与匀减速运动的方法。分享给大家供大家参考,具体如下:/* * 动画帧函数 * * */ var re
- 分页程序sub show_page参数说明:total_records 总记录数everypage_records 每页显示条数
- 出现invalid syntax报错的几种原因这篇文章旨为刚接触python不久的朋友,提供一点帮助,请在检查代码没有主要问题时再看是否存在
- wed的打印方法具我自己懂得知道的有: 1、JQuery插件Jqprint实现 2、JQery打印插件PrintArea实现网页打印 3、C
- 内核:[root@opop ~]# cat /etc/centos-release CentOS release 6.8 (Final)[r
- js中自动清除ie缓存方法 — 常用 对于动态文件,比如 index.asp?id=... 或者 index.aspx?id=... 相信有
- 本文实例为大家分享了vue实现页面添加水印的具体代码,供大家参考,具体内容如下js文件建一个watermark.js文件let setWat
- 本文主要介绍的是vue.js插入dom节点的方法,下面话不多说,来看看详细的介绍吧。html代码:<div id="app&
- Django 开发项目是很快的,有多快?看完本篇文章,你就知道了。安装 Django前提条件:已安装 Python。Django 使用 pi
- 前言有时候在使用Python处理比较耗时操作的时候,为了便于观察处理进度,这时候就需要通过进度条将处理情况进行可视化展示,以便我们能够及时了
- 将一个CSV格式的文件分割成两个CSV文件本项目可以按照比例将一个csv文件分割成两个csv文件,效果是:在C:\algo_file文件夹下