Pergunta

Eu vou ser tão específico e detalhado quanto possível e incluir parte do código que estou usando. Eu já fiz uma pesquisa e encontrou esta questão , que parece semelhante; no entanto, o autor havia usando ActionScript 2 em vez de 3, e eu não conseguia aplicar nenhuma das respostas dadas à minha própria situação de forma eficaz.

Eu estou tentando imitar (de forma limitada) o comportamento do objeto XMLHttpRequest de JavaScript através de Flash / ActionScript 3, a fim de superar a limitação do mesmo domínio. Mas eu estou descobrindo que ActionScript tem suas próprias limitações a esse respeito. Eu admito que eu poderia estar enganado, mas pelo que eu entendo é teoricamente ainda possível fazer esse tipo de scripting cross-domain usando o ActionScript, contanto que você tem todas as permissões direita. E é aí que eu estou correndo em problemas.

Em primeiro lugar, eu pedi emprestado algum código-fonte aberto para uma classe chamada AjaxRequest , que eu tenha guardado como /ajax/AjaxRequest.as. Eu, então, criado um arquivo Flash chamado /jsajax.fla que as exportações para o arquivo SWF final, /jsajax.swf. Agora, aqui está o código ActionScript que compreende o primeiro e único quadro do arquivo de inflamação:

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");

Até aí tudo bem. Tenho a sensação de que uma ou mais dessas chamadas Security.allowDomain não são necessários, mas eles foram minhas tentativas (infrutíferas) para tentar resolver este problema.

Na minha JavaScript, eu tenho três funções definidas: jsAjax, jsAjaxResponse e jsAjaxReady. O último é apenas uma função muito básica usada para indicar que o objeto Flash carregado com êxito (que só é chamado uma vez e imediatamente após o carregamento-lo), enquanto os outros dois são usados ??para enviar e receber os dados. Como você pode ver, eles têm homólogos ActionScript correspondente.

Finalmente, criei uma página HTML simples chamado /test.html que incorpora esse arquivo SWF (usando swfobject ) e tem um par de controles de formulário simples para chamar a função jsAjax. Todas as minhas definições de JavaScript são incorporados neste arquivo HTML também. Eu também criou um script PHP muito simples chamado /test.php que imprime o conteúdo da matriz $_REQUEST. Esse é o roteiro que pretendo pedido usando este método ajax.

Há três cenários que eu testei, mas eu só foi capaz de obter dois deles trabalhando:


Cenário um: Tudo em um servidor
Se eu carregar todos esses arquivos para domainone.com, e, em seguida, solicitar test.php, ele funciona bem. Minha estrutura de arquivo / pasta, em seguida, se parece com isso:

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

Mais uma vez, isso funciona . A função jsAjaxResponse recebe de volta os dados de test.php muito bem.


Cenário dois: em ambos os servidores, inclinada para a esquerda
Quando eu carregado o HTML e SWF para o primeiro servidor, e, em seguida, apenas tem que chamar o script PHP no segundo servidor, não funcionou de imediato. Eu fiz alguma escavação, e descobriu que através da criação de um arquivo crossdomain.xml em domaintwo.com que o acesso concedido a domainone.com, este fixa-lo. Assim, a minha estrutura de arquivo / pasta ficou assim:

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

Ao permitir explicitamente domainone.com no arquivo crossdomain.xml, funciona este . Mais uma vez, a função jsAjaxResponse recebe de volta os dados de test.php muito bem.


Cenário três: em ambos os servidores, inclinando-se para a direita
Quando eu carregado todos, mas o HTML para domaintwo.com, eu já não podia fazê-lo funcionar. Em outras palavras, o HTML em domainone.com está referenciando um arquivo SWF hospedado em domaintwo.com, e esse arquivo SWF está tentandopara fazer um pedido para domaintwo.com. Deixei o mesmo arquivo crossdomain.xml do Cenário 2, apenas no caso. Minha estrutura de arquivo / pasta ficou assim:

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

Este é o único caso que eu não poderia começar a trabalhar, e este é o caso de eu precisar para começar a trabalhar. Os dois primeiros foram realmente apenas cenários de teste para ver se o script estava trabalhando em tudo. Quando tento executar a minha função jsAjax aqui, eu encerrar com um erro que aparece duas vezes no 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.].

Ajuda! Como posso fazê-lo funcionar no cenário 3?

Foi útil?

Solução

Eu só percebi isso! Ele tinha a ver com os comandos Security.allowDomain em meu arquivo do Flash. Eu estava realmente hospeda o test.html em um subdomínio de domainone.com, e que estava jogando fora. Tem que ser uma correspondência exata, subdomínio e tudo. Acontece que eu não precisava do comando Security.allowDomain que referenciou domaintwo.com, nem eu preciso do arquivo crossdomain.xml estar presente em tudo para Cenário 3!

Uma vez que na versão "real" deste roteiro que eu acabar usando, eu não necessariamente sabe o que domainone.com realmente é, eu mudei o código na parte superior do arquivo Flash para o seguinte:

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

Em seguida, no JavaScript que estou usando para incorporar o SWF lá em primeiro lugar, eu basicamente pegar o domínio atual da página de document.location.toString(), verifique se ele está usando HTTP ou HTTPS, e, em seguida, passar o domínio como allow e / ou allowhttps no parâmetro flashvars. Pode haver um "melhor" maneira de fazer isso que não se baseia na criação do domínio-se explicitamente no flash Vars (algum tipo de detecção automática de dentro Flash), mas eu não estou versado em ActionScript bem o suficiente para descobrir isso Fora. E uma vez que este arquivo já está fazendo um monte de comunicação bidirecional entre JavaScript e ActionScript, não é assim tão grande de um negócio. Esta solução é bom o suficiente para mim.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top