2009-10-28 9 views
6

Ho intenzione di essere il più specifico e dettagliato possibile e includere parte del codice che sto usando. Ho già effettuato una ricerca e ho trovato this question, che sembra simile; comunque l'autore stava usando ActionScript 2 invece di 3, e non riuscivo a applicare nessuna delle risposte date alla mia situazione in modo efficace.Come posso risolvere questo errore di ActionScript 3 tra domini diversi?

Sto cercando di emulare (in modo limitato) il comportamento dell'oggetto XMLHttpRequest di JavaScript tramite Flash/ActionScript 3, al fine di superare la limitazione dello stesso dominio. Ma sto scoprendo che ActionScript ha i suoi limiti in questo senso. Ammetto che potrei sbagliarmi, ma da quello che capisco è teoricamente ancora possibile fare questo tipo di scripting cross-domain usando ActionScript, a patto che tu abbia tutte le autorizzazioni corrette. Ed è qui che mi trovo nei guai.

In primo luogo, ho preso in prestito un codice open source per una classe denominata AjaxRequest, che ho salvato come /ajax/AjaxRequest.as. Ho quindi creato un file Flash chiamato /jsajax.fla che esporta nel file SWF finale, /jsajax.swf. Ora, ecco il codice ActionScript che comprende il primo e unico frame del file 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"); 

Fin qui tutto bene. Ho la sensazione che una o più di quelle chiamate Security.allowDomain non siano necessarie, ma erano i miei (non riusciti) tentativi di provare a risolvere questo problema.

Nel mio JavaScript, ho tre funzioni definite: jsAjax, jsAjaxResponse e jsAjaxReady. L'ultimo è solo una funzione di base utilizzata per indicare che l'oggetto Flash è stato caricato correttamente (che viene richiamato solo una volta e immediatamente dopo il caricamento), mentre gli altri due vengono utilizzati per inviare e ricevere i dati. Come puoi vedere, hanno controparti ActionScript corrispondenti.

Infine, ho creato una semplice pagina HTML chiamato /test.html che incorpora il file SWF (utilizzando swfobject) e ha un paio di semplici controlli di modulo per chiamare la funzione jsAjax. Tutte le mie definizioni JavaScript sono incorporate anche in questo file HTML. Ho anche creato uno script PHP molto semplice chiamato /test.php che stampa il contenuto dell'array $_REQUEST. Questo è lo script che intendo richiedere usando questo metodo ajax.

ci sono tre scenari che ho provato, ma sono stato in grado di ottenere due di loro lavorano solo:


SCENARIO UNO: Tutto in un unico server
Se posso caricare tutti questi file per domainone.com, e quindi request test.php, funziona bene. La mia struttura di file/cartelle appare allora come questo:

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

Ancora una volta, questo funziona . La funzione jsAjaxResponse riceve di nuovo i dati da test.php.


SCENARIO DUE: su entrambi i server, appoggiandosi sinistra
Quando ho caricato il codice HTML e SWF al primo server, e poi basta averlo chiamare lo script PHP sul secondo server, non ha lavorare subito. Ho fatto qualche ricerca e ho scoperto che creando un file crossdomain.xml su domaintwo.com che consentiva l'accesso a domainone.com, questo problema era stato risolto.Così la mia struttura di file/cartelle si presentava così:

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

Quando esplicitamente permettendo domainone.com nel file crossdomain.xml, questo funziona. Ancora una volta, la funzione jsAjaxResponse riceve di nuovo i dati da test.php.


SCENARIO A TRE: su entrambi i server, appoggiandosi a destra
Quando ho caricato tutti, ma il codice HTML per domaintwo.com, io non poteva più farlo funzionare. In altre parole, l'HTML su domainone.com fa riferimento a un file SWF ospitato su domaintwo.com e quel file SWF sta tentando di fare una richiesta a domaintwo.com. Ho lasciato lo stesso file crossdomain.xml dallo scenario 2, per ogni evenienza. La mia struttura di file/cartelle si presentava così:

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

Questo è l'unico caso in cui non ho potuto ottenere a lavorare, e questo è il caso ho bisogno di ottenere lavoro. I primi due erano in realtà solo degli scenari di test per vedere se lo script stesse funzionando. Quando provo a fare funzionare la mia funzione jsAjax qui, finisco con un errore che si presenta due volte 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.]. 

Aiuto! Come posso farlo funzionare nello scenario 3?

risposta

4

Ho appena capito! Aveva a che fare con i comandi Security.allowDomain nel mio file Flash. In realtà stavo ospitando lo test.html su un sottodominio di domainone.com, e questo è stato buttato via. Deve essere una corrispondenza esatta, sottodominio e tutto. Risulta che non avevo bisogno del comando Security.allowDomain che faceva riferimento a domaintwo.com, né avevo bisogno del file crossdomain.xml per essere presente a tutti per lo scenario 3!

Dal momento che nella versione "reale" di questo script che finisce per utilizzare, non voglio necessariamente sapere cosa domainone.com in realtà, ho cambiato il codice nella parte superiore del file Flash a questo:

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

Quindi, nel JavaScript che sto usando per incorporare il file SWF, in primo luogo, in pratica, prendo il dominio corrente della pagina da document.location.toString(), controlla se sta usando http o https, e poi passiamo il dominio come allow e/o allowhttps nel parametro flashvars. Potrebbe esserci un modo "migliore" per farlo che non si basa sull'impostazione esplicita del dominio in Flash Vars (una sorta di rilevamento automatico da Flash), ma non sono abbastanza esperto in ActionScript per capire che su. E poiché questo file sta già facendo un sacco di comunicazioni bidirezionali tra JavaScript e ActionScript, non è un grosso problema. Questa soluzione è abbastanza buona per me.

Problemi correlati