Home » Flash相关 » 未分类 » 利用两个swf之间LocalConnection实现脚本跨域访问

利用两个swf之间LocalConnection实现脚本跨域访问

一般页游都是游戏在一个域,平台商页面在一个域。

比如37.com上面游戏大多是通过iframe引入游戏提供商的游戏页面(一般在另外一个不同的域)。

通常游戏供应商想要跳出iframe,去访问上层的平台商的HTML DOM,则需要进行JS跨域。目前JS跨域,网上已经有了一些方法。这里提供一种跟主流JS跨域不同的解决思路。

那就是通过两个SWF之间的LocalConnection,实现脚本的跨域访问。

LocalConnection是可以在同一台客户端任意两个swf之间进行连接的。具体知识参考Adobe官方的参考手册即可。

我们可以在平台商的页面嵌入一个swf,用于和游戏提供商页面上的游戏swf进行LocalConnection。

第一步:在平台商页面嵌入代码示例如下。注意加入参数allowScriptAccess=always,否则会报安全沙箱错误。当然加入下面的代码

<object width=”100″ height=”1″ classid=”clsid:d27cdb6e-ae6d-11cf-96b8-444553540000″ codebase=”http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0″><param name=”allowScriptAccess” value=”always” /><param name=”src” value=”http://cdnresource.gameContentProducer.com/mygame/stable/CrossDomainAcess.swf” /><embed width=”100″ height=”1″ type=”application/x-shockwave-flash” src=”http://cdnresource.gameContentProducer.com/mygame/stable/CrossDomainAcess.swf” allowScriptAccess=”always” /></object>

第二步:我们来看看CrossDomainAcess.swf里面的逻辑。其实就是创建一个链接,然后把其内部的refresh()方法暴露给其他swf,进行访问。

public class CrossDomainAcess extends Sprite
{
private var tex:TextField ;
private var lc:LocalConnection;
public function CrossDomainAcess()
{
super();
tex = new TextField();
this.addChild(tex);
tex.x = 20;
tex.y = 5;
tex.width = 300;
tex.text = “waiting for command!”;

lc = new LocalConnection();
lc.client = this;

//不跨域是不需要这个设定的。

//lc.allowDomain(“*”);

//Security.allowDomain(“*”);
try
{
lc.connect(“wind_cross_domain”);
}
catch(error:Error)
{
tex.text = “异常:”+error.message;
}
}

private function goToFresh():void
{
//ExternalInterface.call(“eval( alert(‘hello world !’) )”);
// ExternalInterface.call(“eval( document.location.reload() )”);

}
public function refresh(comand:String):void
{
tex.text = comand;
if(ExternalInterface.available)
{
switch(comand)
{
case “refresh”:
{
ExternalInterface.call(“eval( document.location.reload() )”);
break;
}
default:
{
ExternalInterface.call(comand);
break;
}
}
}
}

 

第三步:我在再看看主游戏swf里面的代码。尽管去连接,然后调用“潜伏”在平台商的页面中的swf.让它去执行我们想要的操作(比如刷新浏览器地址)。

private function doSomethingBad():void
{
try
{
var lc:LocalConnection = new LocalConnection();
//lc.allowDomain(“*”);
lc.addEventListener(StatusEvent.STATUS,onLCStatu);
lc.send(“wind_cross_domain”,”refresh”,”refresh”);
}
catch(error:Error)
{
AlertExt.show(error.getStackTrace(),null);
}
}

protected function onLCStatu(event:StatusEvent):void
{
Mgr.chatMgr.showLocalSystemInfo(“状态:”+event.level+”===”+event.toString());
}

 

第四步:上面的代码基本上可以实现我们想要的脚本跨域的需求了。但是蛋疼的问题来。如果玩家同时打开多个这样的页面,但是每个localConnectionName只能使用一次。这样就会出现,我在某个页面的发送刷新指令,而接收刷新指令的确是第一个页面。这就出现一个比较搞笑的现象。当我打开多个游戏小号时,我在某个号里刷新游戏,而该账号的游戏不但没有刷新,反而把另外一个号的游戏界面给刷新了。

这里就需要动态的去管理连接池。并且需要利用shareObject

u=3238905144,2205579118&fm=21&gp=0

进行管理。其过程还是很麻烦的。最后,只能暂时搁浅,不能再项目中实施。

 

 

    分享到: