2009-10-28 8 views
6

Ich werde so spezifisch und ausführlich wie möglich sein und etwas von dem Code, den ich benutze, beinhalten. Ich habe bereits eine Suche durchgeführt und gefunden this question, die ähnlich scheint; Allerdings verwendete der Autor ActionScript 2 anstelle von 3, und ich konnte scheinbar keine der Antworten auf meine Situation effektiv anwenden.Wie behebe ich diesen domainübergreifenden ActionScript 3-Fehler?

Ich versuche, das Verhalten des JavaScript-Objekts XMLHttpRequest durch Flash/ActionScript 3 (in eingeschränkter Weise) zu emulieren, um die Beschränkung der gleichen Domäne zu überwinden. Aber ich stelle fest, dass ActionScript in dieser Hinsicht seine eigenen Einschränkungen hat. Ich gebe zu, dass ich mich vielleicht täusche, aber aus dem, was ich verstehe, ist es theoretisch immer noch möglich, diese Art von Cross-Domain-Scripting mit ActionScript zu machen, solange Sie alle Berechtigungen richtig haben. Und da bekomme ich Ärger.

Zuerst lieh ich einige Open-Source-Code für eine Klasse namens AjaxRequest, die ich als /ajax/AjaxRequest.as gespeichert habe. Ich erstellte dann eine Flash-Datei mit der Bezeichnung /jsajax.fla, die in die endgültige SWF-Datei /jsajax.swf exportiert. Nun, hier ist der Actionscript-Code, den den ersten und einzigen Rahmen der Flash-Datei umfasst:

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

So weit so gut. Ich habe das Gefühl, dass einer oder mehrere dieser Anrufe nicht benötigt werden, aber sie waren meine (erfolglosen) Versuche, dieses Problem zu lösen. In meinem JavaScript habe ich drei Funktionen definiert: jsAjax, jsAjaxResponse und jsAjaxReady. Die letzte ist nur eine sehr einfache Funktion, die anzeigt, dass das Flash-Objekt erfolgreich geladen wurde (die nur einmal und unmittelbar nach dem Laden aufgerufen wird), während die anderen beiden zum Senden und Empfangen der Daten verwendet werden. Wie Sie sehen können, haben sie entsprechende ActionScript-Gegenstücke.

Schließlich habe ich eine einfache HTML-Seite namens /test.html, der diese SWF-Datei einbettet (mit swfobject) und hat ein paar einfachen Formular-Steuerelemente für den Aufruf der Funktion jsAjax. Alle meine JavaScript-Definitionen sind ebenfalls in diese HTML-Datei eingebettet. Ich habe auch ein sehr einfaches PHP-Skript namens /test.php erstellt, das den Inhalt des $_REQUEST Arrays ausgibt. Das ist das Skript, das ich mit dieser Ajax-Methode anfordern möchte.

Es gibt drei Szenarien, die ich getestet, aber ich konnte nur zwei von ihnen zum Laufen bringen:


SZENARIO ONE: Alle auf einem Server
Wenn ich all diese Dateien hochladen zu domainone.com, und dann test.php anfordern, es funktioniert gut. Meine Datei/Ordner-Struktur sieht dann wie folgt aus:

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

Wieder diese funktioniert. Die Funktion jsAjaxResponse empfängt die Daten aus der test.php einfach wieder.


ZWEI SZENARIO: Auf beiden Servern linkes Lehnen
Wenn ich die HTML und SWF zum ersten Server hochgeladen, und dann haben sie nur die PHP-Skript aufrufen auf dem zweiten Server, tat es nicht arbeite sofort. Ich habe etwas gegraben und festgestellt, dass dies durch die Erstellung einer crossdomain.xml Datei auf domainwo.com, die den Zugriff auf domainone.com gewährt hat, dies behoben hat.So sah meine Datei/Ordner-Struktur wie folgt aus:

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

Wenn explizit in der Datei crossdomain.xml ermöglicht domainone.com, das funktioniert. Auch hier erhält die Funktion jsAjaxResponse die Daten aus test.php zurück.


SZENARIO DREI: Auf beiden Servern, stützte sich rechts
Wenn ich alle, aber die HTML domaintwo.com hochgeladen, konnte ich nicht mehr bekommen sie zu arbeiten. Mit anderen Worten referenziert der HTML-Code auf domainone.com eine auf domaintwo.com gehostete SWF-Datei, und die SWF-Datei versucht, eine Anfrage an domaintho.com zu stellen. Ich habe die gleiche crossdomain.xml-Datei aus Szenario 2 für alle Fälle zurückgelassen. Meine Datei/Ordner-Struktur sah wie folgt aus:

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

Dies ist der einzige Fall, dass ich nicht arbeiten bekommen konnte, und dies ist der Fall, ich brauche zum Laufen zu bringen. Die ersten beiden waren wirklich nur Testszenarien, um zu sehen, ob das Skript überhaupt funktioniert. Wenn ich versuche, hier meine jsAjax Funktion auszuführen, winden ich mit einem Fehler auf, die zweimal in Firebug zeigt sich:

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.]. 

Hilfe! Wie kann ich in Szenario 3 arbeiten?

Antwort

4

Ich habe es gerade herausgefunden! Es hatte mit den Security.allowDomain Befehlen in meiner Flash-Datei zu tun. Ich hosting die test.html auf einer Subdomain von Domainone.com, und das war es abwerfen. Es muss genau stimmen, Subdomain und alles. Es stellte sich heraus, dass ich weder den Befehl Security.allowDomain, der auf domaintwo.com referenzierte, noch die Datei crossdomain.xml für Szenario 3 benötigte!

Da in der „realen“ Version dieses Skripts, das ich am Ende mit, ich will nicht unbedingt wissen, was domainone.com tatsächlich ist, ich den Code auf der Oberseite der Flash-Datei dies geändert:

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

Dann, in dem JavaScript, das ich zum Einbetten der SWF dort an erster Stelle verwende ich im Grunde die aktuelle Domain der Seite von document.location.toString(), überprüfen Sie, ob es http oder https verwendet, und übergeben Sie die Domäne in als allow und/oder allowhttps im Parameter flashvars. Es gibt möglicherweise einen "besseren" Weg, dies zu tun, der nicht darauf angewiesen ist, die Domain explizit in Flash Vars einzurichten (eine Art automatische Erkennung aus Flash heraus), aber ich bin mit ActionScript nicht gut genug, um das herauszufinden aus. Und da diese Datei bereits eine ganze Reihe von bidirektionaler Kommunikation zwischen JavaScript und ActionScript durchführt, ist das kein großer Deal. Diese Lösung ist gut genug für mich.

Verwandte Themen