我将尽可能具体和冗长,并包含我正在使用的一些代码。我已经进行了搜索并找到了这个问题,类似;但是作者使用的是ActionScript 2而不是3,而我似乎无法有效地应用任何给出的答案。

我试图通过Flash / ActionScript 3模拟(以有限的方式)JavaScript的XMLHttpRequest对象的行为,以克服相同的域限制。但我发现ActionScript在这方面有其自身的局限性。我承认我可能会弄错,但据我所知,理论上仍然可以使用ActionScript进行这种跨域脚本编写,只要你获得所有权限。那就是我遇到麻烦的地方。

首先,我为一个名为的类借用了一些开源代码。 AjaxRequest ,我保存为 /ajax/AjaxRequest.as 。然后我创建了一个名为 /jsajax.fla 的Flash文件,该文件导出到最终的SWF文件 /jsajax.swf 。现在,这是包含Flash文件的第一个也是唯一一个框架的ActionScript代码:

import ajax.AjaxRequest;
Security.allowDomain("domainone.com");
Security.allowDomain("domaintwo.com");

function jsAjax(stringURL:String, stringMethod:String, stringData:String):void
{
    var xhr:AjaxRequest = new AjaxRequest(stringURL);
    xhr.contentType = "application/x-www-form-urlencoded";
    xhr.dataFormat = URLLoaderDataFormat.TEXT;

    if ( stringMethod.toUpperCase() == "POST" ) {
        xhr.method = URLRequestMethod.POST;
    } else {
        xhr.method = URLRequestMethod.GET;
    }

    xhr.addEventListener("complete", jsAjaxResponse);
    xhr.send(stringData);
    return;
}

function jsAjaxResponse(evt:Event):void
{
    ExternalInterface.call("jsAjaxResponse", evt.currentTarget.data.toString());
    return;
}

ExternalInterface.addCallback("jsAjax", jsAjax);
ExternalInterface.call("jsAjaxReady");

到目前为止一切顺利。我觉得不需要一个或多个 Security.allowDomain 调用,但他们试图解决这个问题是我的(不成功)尝试。

在我的JavaScript中,我定义了三个函数: jsAjax jsAjaxResponse jsAjaxReady 。最后一个是一个非常基本的函数,用于指示Flash对象成功加载(仅在加载时立即调用一次),而另外两个用于发送和接收数据。如您所见,它们具有相应的ActionScript对应物。

最后,我创建了一个名为 /test.html 的简单HTML页面,它嵌入了这个SWF文件(使用 swfobject )并有几个简单的表单控件来调用 jsAjax 函数。我的所有JavaScript定义也都嵌入在这个HTML文件中。我还创建了一个非常简单的PHP脚本,名为 /test.php ,它打印出 $ _ REQUEST 数组的内容。这是我打算使用这个ajax方法请求的脚本。

我测试了三种情况,但我只能让其中两种工作:


情景一:所有在一台服务器上
如果我将所有这些文件上传到domainone.com,然后请求test.php,它可以正常工作。我的文件/文件夹结构如下所示:

domainone.com/jsajax.swf
domainone.com/test.html
domainone.com/test.php

再次,这可行。 jsAjaxResponse函数接收来自test.php的数据就好了。


情景二:在两台服务器上,左转
当我将HTML和SWF上传到第一台服务器,然后让它在第二台服务器上调用PHP脚本时,它立即无法正常工作。我做了一些挖掘,发现通过在domaintwo.com上创建了一个授予domainone.com访问权限的 crossdomain.xml 文件,修复了它。所以我的文件/文件夹结构如下所示:

domainone.com/jsajax.swf
domainone.com/test.html
domaintwo.com/test.php
domaintwo.com/crossdomain.xml

在crossdomain.xml文件中明确允许domainone.com时,可以使用。同样,jsAjaxResponse函数接收来自test.php的数据就好了。


情景三:在两台服务器上,向右倾斜
当我将除HTML之外的所有内容上传到domaintwo.com时,我再也无法让它工作了。换句话说,domainone.com上的HTML引用了托管在domaintwo.com上的SWF文件

有帮助吗?

解决方案

我刚想通了!它确实与我的Flash文件中的 Security.allowDomain 命令有关。我实际上是在domainone.com的子域上托管 test.html ,这就是把它扔掉了。它必须是完全匹配,子域和所有。事实证明我不需要引用domaintwo.com的 Security.allowDomain 命令,也不需要在场景3中存在 crossdomain.xml 文件。 !

因为在“真实”中我最终使用的这个脚本的版本,我不一定知道domainone.com实际上是什么,我将Flash文件顶部的代码更改为:

import ajax.AjaxRequest;
try {
    var domain1:String = LoaderInfo(this.root.loaderInfo).parameters["allow"];
    if ( domain1.length > 0 ) {
        Security.allowDomain(domain1);
    }
} catch (error:Error) { }
try {
    var domain2:String = LoaderInfo(this.root.loaderInfo).parameters["allowhttps"];
    if ( domain2.length > 0 ) {
        Security.allowInsecureDomain(domain2);
    }
} catch (error:Error) { }
...

然后,在我用来嵌入SWF的JavaScript中,我基本上从 document.location.toString()中获取页面的当前域,检查它是否是使用http或https,然后在flashvars参数中将域作为 allow 和/或 allowhttps 传递。可能有一个“更好”的这样做的方法不依赖于在Flash Vars中明确设置域(从Flash中进行某种自动检测),但我并不熟悉ActionScript,足以弄清楚这一点。而且由于这个文件已经在JavaScript和ActionScript之间进行了大量的双向通信,因此这并不是什么大不了的事。这个解决方案对我来说已经足够了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top