Вопрос

Я собираюсь быть настолько конкретным и подробным, насколько это возможно, и включать часть кода, который я использую. Я уже выполнил поиск и нашел этот вопрос , который кажется аналогичный; однако автор использовал 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, это не такая уж большая проблема. Это решение достаточно хорошо для меня.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top