Как исправить эту междоменную ошибку ActionScript 3?
-
08-07-2019 - |
Вопрос
Я собираюсь быть настолько конкретным и подробным, насколько это возможно, и включать часть кода, который я использую. Я уже выполнил поиск и нашел этот вопрос , который кажется аналогичный; однако автор использовал ActionScript 2 вместо 3, и я не мог эффективно применить какой-либо из ответов, приведенных в моей собственной ситуации.
Я пытаюсь эмулировать (ограниченным образом) поведение объекта JavaScript XMLHttpRequest через Flash / ActionScript 3, чтобы преодолеть ограничение того же домена. Но я обнаружил, что ActionScript имеет свои ограничения в этом отношении. Я допускаю, что могу ошибаться, но из того, что я понимаю, теоретически все еще возможно выполнять такого рода междоменные сценарии с использованием ActionScript, при условии, что вы получаете все права. И вот тут у меня проблемы.
Во-первых, я позаимствовал код с открытым исходным кодом для класса AjaxRequest , который я сохранил как /ajax/AjaxRequest.as
. Затем я создал файл Flash с именем /jsajax.fla
, который экспортирует в окончательный 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.
Наконец, я создал простую HTML-страницу с именем /test.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 на втором сервере, он сразу не сработал. Я немного покопался и обнаружил, что, создав файл 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,
Решение
Я только что понял это! Это было связано с командами Security.allowDomain
в моем файле Flash. На самом деле я размещал test.html
на поддомене domainone.com, и это его отбросило. Это должно быть точное совпадение, поддомен и все. Оказывается, мне не нужна была команда Security.allowDomain
, ссылающаяся на domaintwo.com, и мне не нужно было вообще присутствовать в файле crossdomain.xml
для сценария 3
Так как в " реальном " версию этого скрипта, которую я в итоге использую, я не обязательно буду знать, что такое 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) { }
...
Затем в JavaScript, который я использую для встраивания туда SWF, я в основном беру текущий домен страницы из document.location.toString ()
, проверяю, используя http или https, а затем передайте домен как allow
и / или allowhttps
в параметре flashvars. Там может быть "лучше" способ сделать это, не полагаясь на явную настройку домена во Flash Vars (какое-то автоматическое обнаружение из Flash), но я недостаточно разбираюсь в ActionScript, чтобы понять это. И так как этот файл уже выполняет целую кучу двунаправленной связи между JavaScript и ActionScript, это не такая уж большая проблема. Это решение достаточно хорошо для меня.