如何修复此跨域 ActionScript 3 错误? [英] How do I fix this cross-domain ActionScript 3 error?

查看:21
本文介绍了如何修复此跨域 ActionScript 3 错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm going to be as specific and verbose as possible and include some of the code I'm using. I already did a search and found this question, which seems similar; however the author there was using ActionScript 2 instead of 3, and I couldn't seem to apply any of the answers given to my own situation effectively.

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

I am trying to emulate (in a limited way) the behavior of JavaScript's XMLHttpRequest object through Flash/ActionScript 3, in order to overcome the same-domain limitation. But I'm discovering that ActionScript has its own limitations in that regard. I admit that I might be mistaken, but from what I understand it is theoretically still possible to do this sort of cross-domain scripting using ActionScript, so long as you get all the permissions right. And that's where I'm running into trouble.

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

First, I borrowed some open-source code for a class called AjaxRequest, which I have saved as /ajax/AjaxRequest.as. I then created a Flash file called /jsajax.fla which exports to the final SWF file, /jsajax.swf. Now, here's the ActionScript code that comprises the first and only frame of the Flash file:

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 调用,但它们是我尝试解决此问题的(失败)尝试.

So far so good. I have a feeling that one or more of those Security.allowDomain calls are not needed, but they were my (unsuccessful) attempts to try to solve this problem.

在我的 JavaScript 中,我定义了三个函数:jsAjaxjsAjaxResponsejsAjaxReady.最后一个只是一个非常基础的函数,用于表示Flash对象加载成功(只调用一次,加载后立即调用),另外两个用于发送和接收数据.如您所见,它们具有相应的 ActionScript 对应项.

In my JavaScript, I've got three functions defined: jsAjax, jsAjaxResponse, and jsAjaxReady. The last one is just a very basic function used to indicate that the Flash object loaded successfully (which is only called once and immediately upon loading it), while the other two are used for sending and receiving the data. As you can see, they have corresponding ActionScript counterparts.

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

Finally, I created a simple HTML page called /test.html that embeds this SWF file (using swfobject) and has a couple of simple form controls for calling the jsAjax function. All of my JavaScript definitions are embedded in this HTML file too. I also created a very simple PHP script called /test.php that prints out the contents of the $_REQUEST array. That's the script I intend to request using this ajax method.

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

There are three scenarios that I tested, but I was only able to get two of them working:

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

SCENARIO ONE: All on one server
If I upload all of these files to domainone.com, and then request test.php, it works fine. My file/folder structure then looks like this:

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

同样,这行得通.jsAjaxResponse 函数从 test.php 接收回数据就好了.

Again, this works. The jsAjaxResponse function receives back the data from test.php just fine.

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

SCENARIO TWO: On both servers, leaning left
When I uploaded the HTML and SWF to the first server, and then just have it call the PHP script on the second server, it didn't work right away. I did some digging, and found that by creating a crossdomain.xml file on domaintwo.com that granted access to domainone.com, this fixed it. So my file/folder structure looked like this:

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

当在 crossdomain.xml 文件中明确允许 domainone.com 时,这有效.同样,jsAjaxResponse 函数从 test.php 接收回数据就好了.

When explicitly allowing domainone.com in the crossdomain.xml file, this works. Again, the jsAjaxResponse function receives back the data from test.php just fine.

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

SCENARIO THREE: On both servers, leaning right
When I uploaded all but the HTML to domaintwo.com, I could no longer get it to work. In other words, the HTML on domainone.com is referencing an SWF file hosted on domaintwo.com, and that SWF file is trying to make a request to domaintwo.com. I left the same crossdomain.xml file from Scenario 2, just in case. My file/folder structure looked like this:

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

这是我无法开始工作的唯一情况,这就是我需要开始工作的情况.前两个实际上只是测试场景,以查看脚本是否正常工作.当我尝试在这里运行我的 jsAjax 函数时,我最终遇到了一个在 Firebug 中出现两次的错误:

This is the only case I could not get working, and this is the case I need to get working. The first two were really just test scenarios to see if the script was working at all. When I try to run my jsAjax function here, I wind up with an error that shows up twice in 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 中工作?


Help! How do I get it working in scenario 3?

推荐答案

我刚刚想通了!它确实与我的 Flash 文件中的 Security.allowDomain 命令有关.我实际上是在 domainone.com 的一个子域上托管 test.html ,这让我放弃了.它必须是完全匹配的,子域等等.事实证明,我不需要引用 domaintwo.com 的 Security.allowDomain 命令,也不需要为场景 3 提供 crossdomain.xml 文件!

I just figured it out! It did have to do with the Security.allowDomain commands in my Flash file. I was actually hosting the test.html on a subdomain of domainone.com, and that was throwing it off. It has to be an exact match, subdomain and all. It turns out I didn't need the Security.allowDomain command that referenced domaintwo.com, nor did I need the crossdomain.xml file to be present at all for Scenario 3!

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

Since in the "real" version of this script that I end up using, I won't necessarily know what domainone.com actually is, I changed the code on the top of the Flash file to this:

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 的了解不够好,无法弄清楚出去.因为这个文件已经在 J​​avaScript 和 ActionScript 之间进行了大量的双向通信,所以这没什么大不了的.这个解决方案对我来说已经足够了.

Then, in the JavaScript I'm using to embed the SWF there in the first place, I basically grab the current domain of the page from document.location.toString(), check whether it's using http or https, and then pass the domain in as allow and/or allowhttps in the flashvars parameter. There might be a "better" way to do this that doesn't rely on setting the domain up explicitly in the Flash Vars (some kind of automatic detection from within Flash), but I'm not versed in ActionScript well enough to figure that out. And since this file is already doing a whole bunch of bidirectional communication between JavaScript and ActionScript, it's not that big of a deal. This solution is good enough for me.

这篇关于如何修复此跨域 ActionScript 3 错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆