需求: 解决 域名 www.a.com 与 www.b.com 之间的通讯问题
采用falsh/flex解决跨域传输数据的关键在于 crossdomain.xml 文件 一、概述
玩过Flex 或者Flash的同学都知道,如果想要在Flash里面跨域获取数据,就必须在对方server上配置crossdomain .xml 。具体来说,比如你的Flash在domain A下面,而你想要访问domain B暴露的web service,那么domain B的server根目录下必须要有一个crossdomain .xml 文件来配置说你有这个权限。这个是Flash Player的安全限制。
二、 测试
我们提供的testpage.htm测试页面放在www.a.com这个机器上。然后在页面中的 SetWebIMNetwork() 这个函数写为 SetWebIMNetwork("www.b.com", 5293) ,这个页面就可以连接到www.b.com所在的服务器。 以下是crossdomain.xml的内容(这个是不限制连接,这样不太安全,最好是只把你自己的域名写上去,避免从未经授权的域名的页面来连接): <?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd" ;> <cross-domain-policy> <allow-access-from domain="*" /> </cross-domain-policy> 如果你需要具体控制,可以使用具体域名和端口,比如: <cross-domain-policy> <allow-access-from domain="*" to-ports="5293" /> <allow-access-from domain="*.foo.com" to-ports="507,516" /> <allow-access-from domain="192.168.0.199" to-ports="2000-6523" /> <allow-access-from domain="www.foo.com" to-ports="507,516-523" /> <allow-access-from domain="www.bar.com" to-ports="*" /> </cross-domain-policy> 另外,A机器上的,testpage.htm中加载B机器上的Flash可以参考以下这样: <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab #version=8,0,0,0" width="83" height="23" id="CommP2" align="middle"> <param name="allowScriptAccess" value="always" /> <param name="movie" value="http://www.b.com/CommP2.swf" ; /> <param name="quality" value="high" /> <param name="bgcolor" value="#ffffff" /> <embed src="http://www.b.com/CommP2.swf" ; quality="high" bgcolor="#ffffff" width="0" height="0" name="external2" align="middle" allowScriptAccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" ; /> </object> A页面调用 flash 的 SetWebIMNetwork,设置要连接到B网络,在连接B时,flash会先访问要连接的服务器上有无crossdomain.xml策略文件,并检查自己所在的域名是否被允许连接,如果允许,就可以连接上,否则返回连接失败。 Js调用Flash的跨域问题,由于我们提供的Flash插件和Js进行交互,如果js和Flash在不同的域,js调用flash内的方法,就会出现错误。所以在加载Flash要使用 <param name="allowScriptAccess" value="always" /> 有这样的跨域机制,您就不用担心其它网站可以连接到您的 WebIM 服务器,您只要在 crossdomain.xml 里写上允许连接的域名就可以了。而且是精确品配,即使是同一个域名的不同二级域名,未在 crossdomain.xml 中授权,也是不能连接您的服务器的。 所以, crossdomain.xml 里,最好不要使用通配符 * ,请限定好您所允许的域名
三、 crossdomain.xml文件格式
crossdomain.xml的格式非常简单,其根节点为<cross-domain-policy> ,其下包含一个或多个<allow-access-from>节点,<allow-access-from>有一个属性domain,其值为允许访问的域,可以是确切的 IP 地址、一个确切的域或一个通配符域(任何域)。下边是两个例子: 程序代码 <?xml version="1.0"?> <cross-domain-policy> <allow-access-from domain="www.163.com" /> ......//可自行添加更多地址. </cross-domain-policy>
对于Flash Player 9之前的版本,这个crossdomain .xml 文件大概如下:
<? xml version = "1.0" encoding = "UTF-8" ?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml /dtds/cross-domain-policy.dtd" > < cross-domain-policy > < allow-access-from domain = "*" secure = "true" /> </ cross-domain-policy >
以上配置允许所有domain访问当前server所暴露的数据(比如web service)。你可以在domain属性里面指定特殊的规则。secure属性用来设置你所暴露的数据是否走https协议。
但是对于Flash Player 9而言,crossdomain .xml 文件内容出现了较大的变化,原因是Flash Player 9的security机制有所改变。所以当我用Flex 3调用cross domain的web service时,还使用上面的crossdomain .xml 文件,结果就报错说security error。于是稍微研究了一下,得到如下解决方案,其实就是要改变crossdomain .xml 的内容:
<? xml version = "1.0" encoding = "UTF-8" ?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml /dtds/cross-domain-policy.dtd" > < cross-domain-policy > < site-control permitted-cross-domain-policies = "all" /> < allow-access-from domain = "*" /> < allow-http-request-headers-from domain = "*" headers = "*" /> </ cross-domain-policy >
以上是Flash Player 9所要求的crossdomain .xml 的内容。可以看到多了两个tag。其中site-control是可选的,但是allow-http-request-headers-from对于cross domain的web service确实必须的。如果没有允许header,就会像我之前一样报错。这些配置项的具体含义以及其他可选配置项,可以参考http://www.adobe.com/devnet/flashplayer/articles/flash_player_9_security.pdf
查看本机flash player 版本: http://www.playerversion.com/