2011-03-01 8 views
14

Tengo un problema muy extraño con Flash 10 y ExternalInterface. Actualmente estoy usando un puente hecho en casa para utilizar RTMFP con Javascript y cada vez que intento pasar los datos que contiene JSON, me sale un error extraño Javascript que proviene de inflamación:¿Por qué ExternalInterface se rompe cuando paso el parámetro con JSON como string?

missing) after argument list 
try { __flash__toXML(Flash.Utilities.A..."")) ; } catch (e) { "<undefined/>"; } 

Es imposible obtener más información ya que esta viene de Flash y no está vinculado a ningún archivo Javascript.

Para reproducir este problema, puede utilizar este script:

package 
{ 
    import flash.display.Sprite; 
    import flash.events.Event; 
    import flash.external.ExternalInterface; 

    public class Main extends Sprite 
    { 

     public function Main():void 
     { 
      if (stage) init(); 
      else addEventListener(Event.ADDED_TO_STAGE, init); 
     } 

     private function init(e:Event = null):void 
     { 
      removeEventListener(Event.ADDED_TO_STAGE, init); 
      var test:String; 

      test = "\"\\\"\""; 

      ExternalInterface.call("console.log", test); 
     } 

    } 

} 

¿Qué puedo hacer para evitar este problema y se trata de un problema conocido?

+0

está usando 'json_encode'? – kjy112

+0

@ kjy112 No, supongo que ExternalInterface.call se ocupará de escapar correctamente de los datos que le estoy pasando. – HoLyVieR

+0

@holyvier http://maccherone.com/larry/projects/a-pretty-json-encoder-for-actionscript-3-as3/ – kjy112

Respuesta

22

Esto aparentemente es un problema conocido y no parece que Adobe vaya a solucionarlo pronto.

encontré una detailled explaination de este problema y, básicamente, el problema parece ser que Flash no maneja el \ y la & adecuadamente que puede conducir a javascript error o corrupción de datos durante la transferencia de Flash a javascript.

Qué Flash intenta hacer cuando se transfieren datos de Flash a JS es ejecutar lo siguiente:

try { 
    __flash__toXML(yourJavascriptFunction("[DATA]")) ; 
} catch (e) { "<undefined/>"; } 

El problema es que pone los datos en bruto y que no escapa a la barra invertida en absoluto . Si la cadena contiene sólo \ y que desea llamar console.log en él, se tratará de hacer lo siguiente:

try { 
    __flash__toXML(console.log("\")) ; 
} catch (e) { "<undefined/>"; } 

como se puede ver esto es válido Javascript. Lanzará un error en su consola de Javascript y nunca llamará al console.log.

La solución es o bien bloquear el comportamiento del flash o hacer algún truco desagradable para evitarlo.

Para ducktape Flash buggyness puede escapar de la barra negra antes de transferirlos. Esta solución funcionará por el momento, pero cuando Flash lo solucione (lo más probable es que no lo haga en un futuro próximo, si considera que este error se conoce desde hace más de 4 años), romperá su aplicación.

La otra posibilidad es codificar el carácter url que Flash no maneja bien (\, ", &) y decodificarlos en el otro lado.

de inflamación:

data = data.split("%").join("%25") 
      .split("\\").join("%5c") 
      .split("\"").join("%22") 
      .split("&").join("%26"); 

Javascript:

data = data.replace(/%22/g, "\"") 
      .replace(/%5c/g, "\\") 
      .replace(/%26/g, "&") 
      .replace(/%25/g, "%"); 

Es feo, pero funciona.

+0

El truco "feo" no funcionó, pero el escape de abajo sí lo hizo. Aún así, la explicación es lo suficientemente extensa como para aportar algo positivo. – Wernight

6

Es cierto que esto no funcionaría directamente para la salida a la consola en Firebug, pero para la mayoría de las otras aplicaciones (es decirel envío de una potencialmente cadena 'no válido' de Javascript), escape y unescape debería funcionar bien:

AS3:

var testString:String = "\"\\\"\""; 
ExternalInterface.call("showString", escape(testString)); 

Y luego, en Javascript:

function showString(msg) { 
    console.log(unescape(msg)); 
    document.getElementById('messagebox').innerHTML = unescape(msg); 
} 

<div id="messagebox"></div> 
Cuestiones relacionadas