如果使用 ActionScript 3.0 编写的两个 SWF 文件或在 AIR 中运行的两个 HTML 文件来自同一域(例如,一个 SWF 文件的 URL 是 http://www.example.com/swfA.swf,另一个的是 http://www.example.com/swfB.swf),则在其中一个文件中定义的代码可检查并修改另一个文件中的变量、对象、属性、方法等,反之亦然。这称为“跨脚本访问”。
如果这两个文件来自不同的域(例如,http://siteA.com/swfA.swf 和 http://siteB.com/swfB.swf),那么,在默认情况下,Flash Player 和 AIR 不允许 swfA.swf 编写 swfB.swf 的脚本,也不允许 swfB.swf 编写 swfA.swf 的脚本。通过调用
Security.allowDomain()
,一个 SWF 文件可授予其他域中的 SWF 文件编写其脚本的权限。通过调用
Security.allowDomain("siteA.com")
,swfB.swf 向来自 siteA.com 的 SWF 文件授予访问其脚本的权限。
在 AVM1 SWF 文件和 AVM2 SWF 文件之间不支持跨脚本访问。AVM1 SWF 文件是使用 ActionScript 1.0 或 ActionScript 2.0 创建的文件。(AVM1 和 AVM2 指的是 ActionScript 虚拟机。)但是,可以使用 LocalConnection 类在 AVM1 和 AVM2 之间发送数据。
在任何跨域的情况下,明确所涉及的双方非常重要。为了便于进行此讨论,我们将执行跨脚本访问的一方称为“访问方”(通常是执行访问的 SWF),将另一方称为“被访问方”(通常是被访问的 SWF)。当 siteA.swf 访问 siteB.swf 的脚本时,siteA.swf 是访问方,siteB.swf 是被访问方,如下图所示:
使用
Security.allowDomain()
方法建立的跨域权限是不对称的。在上例中,siteA.swf 可以访问 siteB.swf 的脚本,但 siteB.swf 无法访问 siteA.swf 的脚本,这是因为 siteA.swf 未调用
Security.allowDomain()
方法来授予 siteB.com 中的 SWF 文件访问其脚本的权限。可以通过使两个 SWF 文件都调用
Security.allowDomain()
方法来设置对称权限。
除了防止 SWF 文件受到其他 SWF 文件发起的跨域脚本编写外,Flash Player 还防止 SWF 文件受到 HTML 文件发起的跨域脚本编写。可以通过
ExternalInterface.addCallback()
方法建立的回调执行 HTML 到 SWF 的脚本访问。当 HTML 到 SWF 的脚本访问跨域时,被访问的 SWF 文件必须调用
Security.allowDomain()
方法(这与访问方是 SWF 文件时一样),否则操作将失败。有关详细信息,请参阅
作者(开发人员)控制
。
此外,Flash Player 还对 SWF 到 HTML 的脚本访问提供安全控制。有关详细信息,请参阅
控制外出 URL 访问
。
Stage 安全性
Stage 对象的某些属性和方法可用于显示列表中的任何 sprite 或影片剪辑。
但是,我们说 Stage 对象有一个所有者,即加载的第一个 SWF 文件。默认情况下,Stage 对象的以下属性和方法只能用于与舞台所有者位于同一安全沙箱中的 SWF 文件:
属性
|
方法
|
align
|
addChild()
|
displayState
|
addChildAt()
|
frameRate
|
addEventListener()
|
height
|
dispatchEvent()
|
mouseChildren
|
hasEventListener()
|
numChildren
|
setChildIndex()
|
quality
|
willTrigger()
|
scaleMode
|
|
showDefaultContextMenu
|
|
stageFocusRect
|
|
stageHeight
|
|
stageWidth
|
|
tabChildren
|
|
textSnapshot
|
|
width
|
|
为使与 Stage 所有者不在同一沙箱中的 SWF 文件能够访问这些属性和方法,舞台所有者 SWF 文件必须调用
Security.allowDomain()
方法来允许外部沙箱的域。有关详细信息,请参阅
作者(开发人员)控制
。
frameRate
属性是一种特殊情况:任何 SWF 文件均能读取
frameRate
属性。但是,只有位于 Stage 所有者的安全沙箱中的文件(或通过调用
Security.allowDomain()
方法被授予权限的文件)才能更改该属性。
此外,对于 Stage 对象的
removeChildAt()
和
swapChildrenAt()
方法还存在一些限制,但是这些限制与其他限制不同。要调用这些方法,不需要与 Stage 所有者位于同一域中,而是代码必须与受影响的子对象位于同一域中,或者子对象可以调用
Security.allowDomain()
方法。