2009-10-28 2 views
6

Я собираюсь быть как можно более конкретным и подробным и включать некоторые из кода, который я использую. Я уже выполнил поиск и нашел this question, который кажется похожим; однако автор использовал ActionScript 2 вместо 3, и я, похоже, не мог эффективно применить ни один из ответов, которые были даны моей собственной ситуации.Как исправить эту ошибку междоменного ActionScript 3?

Я пытаюсь подражать (в ограниченном смысле) поведению объекта XMLHttpRequest JavaScript через Flash/ActionScript 3, чтобы преодолеть ограничение для одного домена. Но я обнаружил, что ActionScript имеет свои ограничения в этом отношении. Я признаю, что могу ошибаться, но из того, что, как я понимаю, теоретически все еще возможно сделать такой кросс-доменный скриптинг с использованием ActionScript, пока вы получите все права на право. И тут я столкнулся с бедой.

Во-первых, я позаимствовал некоторый открытый код для класса с именем AjaxRequest, который я сохранил как /ajax/AjaxRequest.as. Затем я создал файл Flash с именем /jsajax.fla, который экспортирует в окончательный SWF-файл, /jsajax.swf. Теперь, вот код 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-копии.

Наконец, я создал простую HTML-страницу под названием /test.html, которая вставляет этот SWF-файл (с использованием swfobject) и имеет пару простых элементов управления формой для вызова функции jsAjax. Все мои определения JavaScript встроены в этот HTML-файл. Я также создал очень простой PHP-скрипт под названием /test.php, который выводит содержимое массива $_REQUEST. Это сценарий, который я намерен запросить с помощью этого метода ajax.

Есть три сценария, которые я тестировал, но я только был в состоянии получить два из них работают:


СЦЕНАРИЙ ONE: Все на одном сервере
Если я загрузить все эти файлы в domainone.com, а затем запросить test.php, он отлично работает. Моя структура файла/папки будет выглядеть следующим образом:

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

Опять же, это работает . Функция jsAjaxResponse возвращает данные из test.php только штрафа.


СЦЕНАРИЙ ВТОРОЙ: На обоих серверах, наклоняясь влево
Когда я загрузил HTML и SWF на первый сервер, а затем просто иметь его вызвать PHP скрипт на втором сервере, это не так работать сразу. Я сделал кое-что, и обнаружил, что, создав файл crossdomain.xml на domaintwo.com, который предоставил доступ к domainone.com, это исправило это.Так что моя структура файла/папки выглядит следующим образом:

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

При явном виде позволяет domainone.com в файле crossdomain.xml, это работает. Опять же, функция jsAjaxResponse возвращает данные из test.php просто отлично.


СЦЕНАРИЙ ТРЕТИЙ: На обоих серверах, опираясь правой
Когда я загрузил все, кроме HTML для domaintwo.com, я уже не мог заставить его работать. Другими словами, HTML на domainone.com ссылается на SWF-файл, размещенный на domaintwo.com, и этот SWF-файл пытается сделать запрос на domaintwo.com. На всякий случай я оставил один файл crossdomain.xml из сценария 2. Моя структура файла/папки выглядит следующим образом:

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?

ответ

4

Я только что понял! Это имело отношение к командам Security.allowDomain в моем файле Flash. Я действительно принимал test.html на субдомене domainone.com, и это отбрасывало его. Это должно быть точное совпадение, субдомен и все. Оказывается, мне не нужна команда Security.allowDomain, на которой ссылается domaintwo.com, и мне не нужен файл crossdomain.xml, который будет присутствовать вообще для сценария 3!

Поскольку в «реальной» версии этого сценария, который я в конечном итоге с помощью, я не обязательно знать, что domainone.com на самом деле, я изменил код на верхней части файла флэш к этому:

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) { } 
... 

Затем, в JavaScript, который я использую, чтобы встроить SWF в первую очередь, я в основном захватываю текущий домен страницы с document.location.toString(), проверяю, использует ли он http или https, а затем передал домен как allow и/или allowhttps в параметре flashvars. Возможно, существует «лучший» способ сделать это, не полагаясь на то, чтобы установить домен вверх явно в Flash Vars (какое-то автоматическое обнаружение из Flash), но я недостаточно разбираюсь в ActionScript, чтобы понять, что вне. И поскольку этот файл уже выполняет целую кучу двунаправленной связи между JavaScript и ActionScript, это не так уж и важно. Это решение для меня достаточно.