Flex crossDomain Security.allDomain() 等跨域机制解析

From: http://help.adobe.com/zh_CN/FlashPlatform/reference/actionscript/3/flash/system/Security.html#allowDomain%28%29

allowDomain

() 方法
public static function allowDomain(... domains):void
语言版本:  ActionScript 3.0
运行时版本:  AIR 1.0, Flash Player 9, Flash Lite 4

允许所标识的域中的 SWF 文件访问包含 allowDomain() 调用的 SWF 文件中的对象和变量。

注意:从 AIR 应用程序沙箱中的代码调用此方法会引发 SecurityError 异常。应用程序安全域以外的内容不能直接跨脚本访问应用程序沙箱中的内容。不过,应用程序沙箱以外的内容可以使用沙箱桥与应用程序安全沙箱中的内容进行通信。

如果两个 SWF 文件来自同一个域(例如,http://mysite.com/swfA.swf 和 http://mysite.com/swfB.swf),则 swfA.swf 可以检查和修改 swfB.swf 中的变量、对象、属性、方法等,而且 swfB.swf 也可以对 swfA.swf 执行同样的操作。这被称为跨影片脚本编写跨脚本编写

如果两个 SWF 文件来自不同的域(例如,http://siteA.com/swfA.swf 和 http://siteB.com/siteB.swf),则在默认情况下,Flash Player 既不允许 swfA.swf 编写 swfB.swf 的脚本,也不允许 swfB.swf 编写 swfA.swf 的脚本。通过调用 Security.allowDomain(),一个 SWF 文件可向其他域中的 SWF 文件授予权限。这称为跨域脚本编写。通过调用 Security.allowDomain("siteA.com"),siteB.swf 可授予 siteA.swf 编写其脚本的权限。

在任何跨域的情况下,明确所涉及的双方非常重要。为了便于进行此讨论,我们将执行跨脚本编写的一方称为访问方(通常是执行访问的 SWF),将另一方称为被访问方(通常是被访问的 SWF 文件)。当 siteA.swf 编写 siteB.swf 的脚本时,siteA.swf 是访问方,siteB.swf 是被访问方。

Flex crossDomain Security.allDomain() 等跨域机制解析_第1张图片

使用 allowDomain() 建立的跨域权限是不对称的。在上一个示例中,siteA.swf 可以编写 siteB.swf 的脚本,但 siteB.swf 无法编写 siteA.swf 的脚本,这是因为 siteA.swf 未调用 allowDomain() 来授予 siteB.com 中的 SWF 文件编写其脚本的权限。可以通过让两个 SWF 文件都调用 allowDomain() 来设置对称权限。

除了防止 SWF 文件受到其他 SWF 文件发起的跨域脚本编写影响外,Flash Player 还可防止 SWF 文件受到 HTML 文件发起的跨域脚本编写的影响。可以使用旧版本的 浏览器函数(如 SetVariable)或通过 ExternalInterface.addCallback() 创建的回调执行 HTML 到 SWF 的脚本编写。当 HTML 到 SWF 的脚本编写跨域时,被访问的 SWF 文件必须调用 allowDomain()(这与访问方是一个 SWF 文件时一样),否则操作将失败。

如果将 IP 地址指定为 allowDomain() 的参数,则不允许所有源自指定 IP 地址的访问方进行访问。相反,只允许 URL 中包含指定 IP 地址的访问方进行访问,而不是允许其域名映射到该 IP 地址的访问方进行访问。

特定于版本的差异

Flash Player 的跨域安全性规则随着版本的升级发生了演变。下表概述了这些差异。

涉及跨脚本编写的最新 SWF 版本 是否需要 allowDomain() 是否需要 allowInsecureDomain() 哪个 SWF 文件必须调用 allowDomain()allowInsecureDomain() allowDomain()allowInsecureDomain() 中可以指定哪些内容?
第 5 版或更低版本 不适用 不适用
6 是的,如果超级域不匹配 被访问的 SWF 文件,或者任何与被访问的 SWF 文件具有相同超级域的 SWF 文件
  • 基于文本的域 (mysite.com)
  • IP 地址 (192.168.1.1)
7 是的,如果域不是完全匹配 是的,如果执行 HTTP 到 HTTPS 的访问(即使域完全匹配) 被访问的 SWF 文件,或者任何与被访问的 SWF 文件具有完全相同域的 SWF 文件
  • 基于文本的域 (mysite.com)
  • IP 地址 (192.168.1.1)
第 8 版或更高版本 是的,如果域不是完全匹配 是的,如果执行 HTTP 到 HTTPS 的访问(即使域完全匹配) 被访问的 SWF 文件
  • 基于文本的域 (mysite.com)
  • IP 地址 (192.168.1.1)
  • 通配符 (*)

控制 Flash Player 行为的版本是 SWF 版本(SWF 文件的发布版本),而不是 Flash Player 本身的版本。例如,当 Flash Player 8 正在播放为第 7 版发布的 SWF 文件时,它应用与第 7 版一致的行为。这种做法可确保播放器升级不会更改已部署 SWF 文件中的 Security.allowDomain() 的行为。

上表中的版本列显示了涉及跨脚本编写操作的最新 SWF 版本。Flash Player 根据执行访问的 SWF 文件的版本或被访问的 SWF 文件的版本(以两者中的较高版本为准)来确定其行为。

下面的段落提供有关涉及 Security.allowDomain() 的 Flash Player 安全性更改的详细信息。

第 5 版。没有跨域脚本编写限制。

第 6 版。引入了跨域脚本编写安全性。默认情况下,Flash Player 禁止跨域脚本编写;Security.allowDomain() 可允许跨域脚本编写。为了确定两个文件是否处于同一域中,Flash Player 将使用每个文件的超级域(即文件 URL 中的完全主机名,去掉第一段,最少剩两段)。例如,www.mysite.com 的超级域为 mysite.com。来自 www.mysite.com 和 store.mysite.com 的 SWF 文件无需调用 Security.allowDomain() 就可以相互编写脚本。

第 7 版。超级域匹配更改为域完全匹配。仅在这两个文件的 URL 中的主机名完全相同时才允许它们相互编写脚本;否则需要调用 Security.allowDomain()。默认情况下,不再允许从非 HTTPS URL 加载的文件编写从 HTTPS URL 加载的文件的脚本,即使这些文件从完全相同的域加载也是如此。由于非 HTTPS 文件容易在下载的过程中被修改,而经过恶意修改的非 HTTPS 文件能破坏 HTTPS 文件,此限制可防止这样的篡改,所以有助于保护 HTTPS 文件。引入了 Security.allowInsecureDomain() 以允许被访问的 HTTPS SWF 文件自主禁用此限制,但不鼓励使用 Security.allowInsecureDomain()

第 8 版。主要有两项更改:

  • 现在,只有被访问的 SWF 文件是调用 Security.allowDomain() 的 SWF 文件时,调用 Security.allowDomain() 才允许跨脚本编写操作。也就是说,现在,调用 Security.allowDomain() 的 SWF 文件仅允许对其自身的访问。在以前的版本中,调用 Security.allowDomain() 允许跨脚本编写操作,其中被访问的 SWF 文件可以是与名为 Security.allowDomain() 的 SWF 文件在同一个域中的任何 SWF 文件。以前调用 Security.allowDomain() 会打开执行调用的 SWF 文件的整个域。
  • 已添加了对具有 Security.allowDomain("*")Security.allowInsecureDomain("*") 的通配符值的支持。通配符 (*) 值允许跨脚本编写操作,操作过程中执行访问的文件可以是从任何位置加载的任何文件。将通配符视为全局权限。根据本地文件安全性规则,需要具有通配符权限才能启用特定类型的操作。具体而言,要使具有网络访问权限的本地 SWF 文件编写 Internet 上的 SWF 文件的脚本,被访问的 Internet SWF 文件必须调用 Security.allowDomain("*"),从而反映本地 SWF 文件的来源是未知的。(如果该 Internet SWF 文件是从 HTTPS URL 加载的,则该 Internet SWF 文件必须改为调用 Security.allowInsecureDomain("*"))。

有时您也可能遇到下面这种情况:您从另一个域中加载一个子级 SWF 文件,并想让该子级 SWF 文件编写父级 SWF 文件的脚本,但您不知道该子级 SWF 文件的最终域。例如,当您使用负载平衡重定向或第三方服务器时就可能发生这种情况。

在这种情况下,您可以使用您传递给 Loader.load() 的 URLRequest 对象的 url 属性。例如,如果将子级 SWF 文件加载到父级 SWF 中,则可以访问父级 SWF 的 Loader 对象的 contentLoaderInfo 属性:

Security.allowDomain(loader.contentLoaderInfo.url)

请务必等待,直至子级 SWF 文件开始加载,以便获得 url 属性的正确值。要确定子级 SWF 何时开始加载,请使用 progress 事件。

也可能出现相反的情况:即您可能创建一个子级 SWF 文件,并想要允许其父级编辑该子级 SWF 文件的脚本,但不知道该父级将来自哪个域。在这种情况下,可以访问作为该 SWF 根对象的显示对象的 loaderInfo 属性。在子级 SWF 中,调用 Security.allowDomain( this.root.loaderInfo.loaderURL)。您不必等待父级 SWF 文件加载;加载子级时,父级已加载完毕。

如果正在为 Flash Player 8 或更高版本进行发布,也可以通过调用 Security.allowDomain("*") 处理这些情况。不过,有时这可能是很危险的便捷手段,因为它允许来自任何域的任何其他 SWF 文件访问执行调用的 SWF 文件。通常,使用 _url 属性更安全。

有关安全性的详细信息,请参阅 Flash Player 开发人员中心主题:安全性。

参数

  ... domains — 一个或多个字符串或者 URLRequest 对象,它们可命名一些您希望允许从中进行访问的域。可指定特殊域“*”,以允许从所有域进行访问。

在 Flash Professional 中,为了从使用 Flash 创作工具中“本地播放安全性”选项的“只访问网络”发布的本地 SWF 文件访问非本地 SWF 文件,指定“*”是唯一的方法。

注意:通配符值在子域中不起作用。例如,不能在 domains 参数中使用 *.foo.com。您可以为跨域策略文件指定带有通配符值的子域(比如在 *.foo.com 中),但是不能以同样方式为 allowDomain() 方法使用通配符值。


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

From: http://bbs.9ria.com/thread-121889-1-1.html

经过这几天的不断试验和查看资料,终于把crossDomain.xml、Security.allowDomain()、allowScriptAccess这三者的关系搞通了。把经验分享给和我一样有这种迷惑的童鞋们,共同进步吧~


flash与环境之间交互的几种情况:

1、swf加载本域图片等(视频/jpg/gif/png/swf...)——啥也不用,crossDomain.xml策略不起作用。


2、swf加载跨域图片等(视频/ jpg/gif/png/swf...)——啥也不用,crossDomain.xml策略不起作用。


3、swf请求本域数据等(txt/jsp/php/.net...)——啥也不用,crossDomain.xml策略不起作用。


4、swf请求跨域数据等(txt/jsp/php/.net...)——对方域根下的crossDomain.xml策略起作用。


5、swf被本域加载和容器js交互——swf内部的Security.allowDomain()不起作用。html容器中的allowScriptAccess参数起作用。


6、swf被跨域加载和容器js交互——swf内部的Security.allowDomain()起作用,需给容器所在的域授权。html容器中的allowScriptAccess参数起作用。


7、swf加载本域swf并访问其内部属性、方法、类等——被加载的swf内部的Security.allowDomain()不起作用。


8、swf加载跨域swf并访问其内部属性、方法、类等——被加载的swf内部的Security.allowDomain()起作用,需给主swf所在的域授权。


参考文档如下:
flash跨域策略文件crossdomain.xml配置详解
http://bbs.9ria.com/thread-120608-1-1.html

Security.allowDomain使用说明
http://livedocs.adobe.com/flash/9.0_cn/ActionScriptLangRefV3/flash/system/Security.html

allowScriptAccess(JS和Flash跨域的互相调用解析)

http://bbs.9ria.com/viewthread.php?tid=121899


--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

From: http://g.kehou.com/t1030858290.html

Flash跨域问题相信不是所有人都可以遇到,如果你在本地发布,或者说直接Ctrl+Enter在FlashIDE中预览,是不会遇到跨域问 题的,当然,跨域有个前提,那就是Flash不是完全独立的,与外界要做一些通信和交互,如果你的Flash是完全独立的文件,没有和外界发生任何交互和 数据通信的话,那么你可以不考虑跨域问题,因为这也不存在跨域问题。

        什么是跨域?跨域简单的说就是访问其他域名的文件或资源,比如a.com的Flash去访问b.com的资源,那么就会引起跨域的问题,因为a.com和b.com不是同一个域名。

        为什么有跨域问题?其实不仅仅是Flash,Javascript等一些脚本也有跨域的问题,这个主要是自身的安全机制所决定的, 因为跨域访问一些文件或资源有一定的危险性,他超过了网站自身的范围,对于站外的资源无法审核其安全性,在网络病毒木马日益猖獗的今天,跨域限制访问是其 安全策略的一个重要解决手段。

        跨域有什么问题?跨域的问题有很多,最直接的就是所访问的文件被限制了,这样一来,你的Flash就不能正常工作了,所以是让人很头疼的一件事情。

        现在的Flash已经不仅仅是作为一个动画了,更多的有了数据交互,所以和外界的通信来作为一个互动性比较强的媒介来展现,跨域也是其中必须解决的一个问题。

        恩,那也许有人说了,既然有跨域的问题,那我把资源都放在同一个域名下不就可以了?恩,的确可以这样做,但是有时候我们也会遇到访 问外部资源的情况,而且在一个比较正规的项目中,Flash和Html往往是分开放的,很多公司也是这样,为了便于维护和管理,所以跨域的问题就容易出 现。

        啰嗦一大堆,下面,就从我实际的项目中来告诉大家该怎样解决跨域问题,相信有了此文,大家今后再遇到跨域问题就能迎刃而解了。

1 Flash自身的安全机制设置

        Flash中,在IDE运行是没有任何安全限制的,但是发布出去的话,就会有不少限制,Flash有2中发布方式,一个是仅访问网 络,一个是仅访问本地,大家可以在文件-发布设置-Flash选项卡中看到,注意必须是在Fla文件有效时才会有哦,如果当前编辑的是as文件是木有这个 选择菜单的:

Flex crossDomain Security.allDomain() 等跨域机制解析_第2张图片

        这里就已经限制了Flash的安全级别,如果是只访问本地,那么Flash中所有的对Web的访问都将禁止,而只访问网络的话,对 本地的文件访问都将禁止,所以大家根据实际的用途来选择,如果你希望你的Flash放到Web上,那么就选择只访问网络,这样的话你测试就务必放在 WebService中测试了,本地运行就会出现各种问题(如果有数据通信的话),例如:测试URLhttp://127.0.0.1/123.swf

2 ActionScript代码设置:

这里我就曾经被绊了几个小时,大家要注意一下,AS2和AS3是不太一样的

AS2写法:System.security.allowDomain("*");//针对不同http资源

                   System.security.allowInsecureDomain("*");//针对需要安全验证的资源,比如https

AS3写法:flash.system.Security.allowDomain("*");

                   flash.system.Security.allowInsecureDomain("*");

        上面就是严格的写法,AS3还好说,大家要注意一下AS2,AS2是木有flash.system这个包的,但是你import flash.system并不会报错,所以如果你把AS3的代码复制进去运行虽然一切正常,但是实际是木有任何效果的。一定要注意!

        上面的代码就是说允许Flash去访问任何URL资源,如果只想访问特定的URl,就把*改成该URL即可,如果多个URl,就用 逗号分隔就可以了,注意allowInsecureDomain是允许访问带验证的URL资源,比如https打头的,如果你访问的只是普通http的话 就不需要了。

3 html的设置:

        如果你需要和页面的JS通信,那么html里就必须有这样一个参数:

<param name="allowScriptAccess" value="always" />

        参数always表示始终允许脚本访问,如果是never,就表示始终不允许

4 加载外部资源:

        如果你要读取一个外部文件,比如swf,picture,mp3等等,那么就需要一个跨域策略文件,这个其实就是一个xml文件,具体内容是:

<?xml version="1.0"?>

<cross-domain-policy>

<allow-access-from domain="www.123.com" />

<allow-access-from domain="*.myhome.com" />

</cross-domain-policy>

        这就是跨域策略文件,allow-access-from domain表示允许访问的URl,如果有多个依次添加,如果允许所有就一个 allow-access-from domain = "*"就可以了

        需要说明一下这个文件该怎么用,如果你的Flash在a.com下,你需要访问b.com的资源,那么把这个xml放在b.com的根目录就可以自动访问了,当然,你也可以访问其他目录的策略文件。

 flash.system.Security.loadPolicyFile(URL:String)

        通过这个loadPolicyFile就可以主动去加载一个安全策略文件了,注意上面是AS3的写法,AS2不一样哦,参考上面的写法。

5 各个浏览器的跨域问题:

        IE就不说了,这个基本没啥问题,包括Flash自己生成的Html就对IE的支持做的很好,这里就说说Chrome和FF的问题:

        在前面一个文章里,我说了对于FLash,IE是认object标签的,但是FF和 Chrome是认embed标签的,所以这个很重要,如果在调试的时候,发现firebug等工具提示"...... is not a Function",我们就要从以下地方查找原因:

                1 addCallback是否成功注册

                2 allowScriptAccess是否允许always,默认不允许

                3 Flash是否完全加载完毕

        一般来说,第三点是我们最容易遇到的,如果你的Flash没有加载完毕就去调用函数的话,是找不到这个函数的,解决方法请参考前一篇文章。

        这里需要注意另外一个错误提示,就是"Error calling method on NPObject",如果出现这个错误,就要小心了:

                1 安全策略问题,请参考上面所有的解决方案

                2 自身函数错误

        如果排除了所有的安全策略问题还是出现这个错误,那么就可能是所调用的函数内部出现了错误,我们可以用个空函数来检查问题,如果空函数没有问题,就一步步查找究竟函数体内哪里出现问题了。        

        以上就是跨域安全策略所能遇到的大部分问题,都具有代表性,也是工作中经常遇到了,希望大家都能够解决这样一个头疼的问题。


你可能感兴趣的:(Flex crossDomain Security.allDomain() 等跨域机制解析)