Flash 如何修复此跨域ActionScript 3错误?

Flash 如何修复此跨域ActionScript 3错误?,flash,actionscript-3,cross-domain,urlrequest,urlloader,Flash,Actionscript 3,Cross Domain,Urlrequest,Urlloader,我将尽可能的具体和详细,包括我正在使用的一些代码。我已经做了一次搜索并找到了,这似乎很相似;然而,那里的作者使用的是ActionScript2而不是3,我似乎无法将给出的任何答案有效地应用到我自己的情况中 我试图通过Flash/ActionScript 3模拟(以有限的方式)JavaScript的XMLHttpRequest对象的行为,以克服相同的域限制。但我发现ActionScript在这方面有自己的局限性。我承认我可能弄错了,但据我所知,理论上仍然可以使用ActionScript编写这种跨域

我将尽可能的具体和详细,包括我正在使用的一些代码。我已经做了一次搜索并找到了,这似乎很相似;然而,那里的作者使用的是ActionScript2而不是3,我似乎无法将给出的任何答案有效地应用到我自己的情况中

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

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

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文件(使用),并有两个简单的表单控件用于调用
jsAjax
函数。我所有的JavaScript定义也都嵌入到这个HTML文件中。我还创建了一个名为
/test.PHP
的非常简单的PHP脚本,用于打印
$\u请求
数组的内容。这就是我打算使用这种ajax方法请求的脚本

我测试了三个场景,但我只能让其中两个正常工作:


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

domainone.com/jsajax.swf
domainone.com/test.html
domainone.com/test.php
domainone.com/jsajax.swf
domainone.com/test.html
domaintwo.com/test.php
domaintwo.com/crossdomain.xml
domainone.com/test.html
domaintwo.com/jsajax.swf
domaintwo.com/test.php
domaintwo.com/crossdomain.xml
同样地,这是有效的。jsAjaxResponse函数从test.php接收回的数据很好


场景二:在两台服务器上,向左倾斜
当我将HTML和SWF上传到第一台服务器,然后让它在第二台服务器上调用PHP脚本时,它没有立即工作。我做了一些挖掘,发现通过在domaintwo.com上创建一个
crossdomain.xml
文件,允许访问domainone.com,这就解决了这个问题。因此,我的文件/文件夹结构如下所示:

domainone.com/jsajax.swf
domainone.com/test.html
domainone.com/test.php
domainone.com/jsajax.swf
domainone.com/test.html
domaintwo.com/test.php
domaintwo.com/crossdomain.xml
domainone.com/test.html
domaintwo.com/jsajax.swf
domaintwo.com/test.php
domaintwo.com/crossdomain.xml
当在crossdomain.xml文件中显式允许domainone.com时,这是有效的。同样,jsAjaxResponse函数从test.php接收回的数据很好


场景三:在两台服务器上,向右倾斜
当我把除了HTML以外的所有内容都上传到Domainwo.com时,我再也无法让它工作了。换句话说,domainone.com上的HTML引用了一个托管在Domainwo.com上的SWF文件,而该SWF文件正试图向Domainwo.com发出请求。我留下了场景2中相同的crossdomain.xml文件,以防万一。我的文件/文件夹结构如下所示:

domainone.com/jsajax.swf
domainone.com/test.html
domainone.com/test.php
domainone.com/jsajax.swf
domainone.com/test.html
domaintwo.com/test.php
domaintwo.com/crossdomain.xml
domainone.com/test.html
domaintwo.com/jsajax.swf
domaintwo.com/test.php
domaintwo.com/crossdomain.xml
这是我唯一不能工作的情况,这是我需要工作的情况。前两个只是测试场景,看看脚本是否工作正常。当我尝试在这里运行jsAjax函数时,我遇到了一个在Firebug中出现两次的错误:

uncaught exception: Error calling method on NPObject! [plugin exception: Error in Actionscript. Use a try/catch block to find error.].
uncaught exception: Error calling method on NPObject! [plugin exception: Error in Actionscript. Use a try/catch block to find error.].


救命啊!在场景3中如何让它工作?

我刚想出来!它确实与Flash文件中的
Security.allowDomain
命令有关。我实际上是在domainone.com的一个子域名上托管了
test.html
,这就把它扔了。它必须是完全匹配的,子域和所有。事实证明,在场景3中,我不需要引用domaintwo.com的
Security.allowDomain
命令,也不需要出现
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
和/或
allowhtps
的形式传递该域。也许有一种“更好”的方法可以做到这一点,它不依赖于在flashvars中显式地设置域(Flash中的某种自动检测),但我对ActionScript还不够精通,无法理解这一点。由于这个文件已经在JavaScript和ActionScript之间进行了大量的双向通信,所以没什么大不了的。这个解决方案对我来说已经足够好了