2009-10-28 5 views
6

Je vais être aussi précis et bavard que possible et inclure une partie du code que j'utilise. J'ai déjà fait une recherche et trouvé this question, ce qui semble similaire; Cependant, l'auteur utilisait ActionScript 2 au lieu de 3, et je n'arrivais pas à appliquer efficacement les réponses données à ma propre situation. J'essaye d'émuler (d'une manière limitée) le comportement de l'objet XMLHttpRequest de JavaScript à travers Flash/ActionScript 3, afin de surmonter la limitation du même domaine. Mais je découvre qu'ActionScript a ses propres limites à cet égard. J'avoue que je pourrais me tromper, mais d'après ce que je comprends, il est théoriquement encore possible de faire ce genre de scripts inter-domaines en utilisant ActionScript, tant que vous obtenez toutes les permissions correctes. Et c'est là que je cours des ennuis. Tout d'abord, j'ai emprunté du code open-source pour une classe appelée AjaxRequest, que j'ai enregistrée sous /ajax/AjaxRequest.as. J'ai ensuite créé un fichier Flash appelé /jsajax.fla qui exporte vers le fichier SWF final, /jsajax.swf. Maintenant, voici le code ActionScript qui comprend la première et la seule image du fichier Flash:Comment réparer cette erreur inter-domaine ActionScript 3?

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

Jusqu'à présent, si bon. J'ai l'impression qu'un ou plusieurs de ces Security.allowDomain appels ne sont pas nécessaires, mais ils ont été mes tentatives (infructueuses) pour essayer de résoudre ce problème.

Dans mon JavaScript, j'ai trois fonctions définies: jsAjax, jsAjaxResponse, et jsAjaxReady. Le dernier est juste une fonction très basique utilisée pour indiquer que l'objet Flash a été chargé avec succès (qui n'est appelé qu'une seule fois et immédiatement après son chargement), alors que les deux autres sont utilisés pour envoyer et recevoir les données. Comme vous pouvez le voir, ils ont des contreparties ActionScript correspondantes.

Enfin, j'ai créé une page HTML simple appelée /test.html qui incorpore ce fichier SWF (en utilisant swfobject) et possède quelques contrôles de formulaire simples pour appeler la fonction jsAjax. Toutes mes définitions JavaScript sont également intégrées dans ce fichier HTML. J'ai également créé un script PHP très simple appelé /test.php qui imprime le contenu du tableau $_REQUEST. C'est le script que j'ai l'intention de demander en utilisant cette méthode ajax.

Il y a trois scénarios que j'ai testé, mais je ne en mesure d'obtenir deux d'entre eux travaillent:


SCÉNARIO UN: Tous sur un serveur
Si je télécharger tous ces fichiers domainone.com, puis demande test.php, cela fonctionne très bien. Ma structure fichier/dossier ressemble alors à ceci:

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

Encore une fois, cela fonctionne . La fonction jsAjaxResponse reçoit très bien les données de test.php.


SCÉNARIO DEUX: Sur les deux serveurs, se penchant à gauche
Quand je téléchargé le code HTML et SWF au premier serveur, puis ai juste appeler le script PHP sur le second serveur, il n'a pas travailler tout de suite. J'ai fait quelques recherches, et j'ai trouvé qu'en créant un fichier crossdomain.xml sur domaintwo.com qui permettait l'accès à domainone.com, cela a corrigé le problème.Donc, ma structure fichier/dossier ressemblait à ceci:

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

Lorsque vous autorisez explicitement domainone.com dans le fichier crossdomain.xml, cela fonctionne. Encore une fois, la fonction jsAjaxResponse reçoit très bien les données de test.php.


SCÉNARIO TROIS: Sur les deux serveurs, se penchant droit
Quand je téléchargé tous, mais le code HTML à domaintwo.com, je ne pouvais plus le faire fonctionner. En d'autres termes, le code HTML sur domainone.com fait référence à un fichier SWF hébergé sur domaintwo.com, et ce fichier SWF tente de faire une demande à domaintwo.com. J'ai quitté le même fichier crossdomain.xml du scénario 2, juste au cas où. Ma structure fichier/dossier ressemblait à ceci:

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

C'est le seul cas que je ne pouvais pas travailler, ce qui est le cas, je dois faire fonctionner. Les deux premiers n'étaient vraiment que des scénarios de test pour voir si le script fonctionnait. Lorsque je tente de lancer ma fonction jsAjax ici, je le vent avec une erreur qui apparaît deux fois dans 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.]. 

Aide! Comment puis-je le faire fonctionner dans le scénario 3?

Répondre

4

Je viens de comprendre! Cela avait à voir avec les commandes Security.allowDomain dans mon fichier Flash. J'hébergeais en fait le test.html sur un sous-domaine de domainone.com, et cela le jetait. Cela doit être une correspondance exacte, un sous-domaine et tout. Il s'avère que je n'avais pas besoin de la commande Security.allowDomain qui faisait référence à domaintwo.com, et que je n'avais pas besoin du fichier crossdomain.xml pour être présent du tout pour le scénario 3!

Depuis la version « réelle » de ce script que je finis à l'aide, je sais pas nécessairement ce que domainone.com est en fait, je l'ai changé le code sur le dessus du fichier Flash à ceci:

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

Puis, dans le JavaScript que j'utilise pour intégrer le SWF, je récupère le domaine actuel de la page de document.location.toString(), vérifie s'il utilise http ou https, puis passe le domaine en tant que allow et/ou allowhttps dans le paramètre flashvars. Il pourrait y avoir une «meilleure» façon de faire cela qui ne repose pas sur la définition explicite du domaine dans le Vars de Flash (une sorte de détection automatique à partir de Flash), mais je ne connais pas suffisamment le langage ActionScript pour le comprendre en dehors. Et puisque ce fichier fait déjà beaucoup de communication bidirectionnelle entre JavaScript et ActionScript, ce n'est pas un gros problème. Cette solution est assez bonne pour moi.

Questions connexes