当我使用类似字符串的JSON传递参数时,为什么ExternalInterface会中断?

HoL*_*ieR 14 javascript flash actionscript-3 externalinterface

我对Flash 10和ExternalInterface有一个非常奇怪的问题.我目前正在使用自制网桥使用带有Javascript的RTMFP,每当我尝试传递包含JSON的数据时,我都会收到来自Flash的奇怪的Javascript错误:

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

由于这来自Flash并且它不受任何Javascript文件的约束,因此无法获得更多信息.

要重现此问题,您可以使用此脚本:

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

    }

}
Run Code Online (Sandbox Code Playgroud)

我该怎么做才能避免这个问题,这是一个众所周知的问题吗?

HoL*_*ieR 22

这显然是一个已知的问题,似乎Adobe不会很快修复它.

我发现了这个问题的详细解释,基本上问题似乎是Flash没有处理\&正确的,这可能导致从Flash转移到javascript期间的javascript错误或数据损坏.

将数据从Flash传输到JS时,Flash尝试执行的操作是执行以下操作:

try {
    __flash__toXML(yourJavascriptFunction("[DATA]")) ;
} catch (e) { "<undefined/>"; }
Run Code Online (Sandbox Code Playgroud)

问题在于它会使您的数据处于原始状态,并且根本不会逃避反斜杠.如果您的字符串仅包含\并且您想要调用console.log它,它将尝试执行以下操作:

try {
    __flash__toXML(console.log("\")) ;
} catch (e) { "<undefined/>"; }
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这是无效的javascript.它将在您的Javascript控制台中引发错误,它永远不会调用console.log.

解决方案是要么使用闪存行为,要么做一些讨厌的黑客攻击它.

为了消除闪光车的故障,您可以在转移它们之前逃避黑色闪光.这个解决方案现在可以使用了,但是当Flash修复它时(很可能不会在不久的将来,如果你认为这个bug已经超过4年了),它将会破坏你的应用程序.

另一种可能性是URL编码Flash不处理好(文字\,",&),并将它们在另一侧进行解码.

Flash:

data = data.split("%").join("%25")
           .split("\\").join("%5c")
           .split("\"").join("%22")
           .split("&").join("%26");
Run Code Online (Sandbox Code Playgroud)

Javascript:

data = data.replace(/%22/g, "\"")
           .replace(/%5c/g, "\\")
           .replace(/%26/g, "&")
           .replace(/%25/g, "%");
Run Code Online (Sandbox Code Playgroud)

这很难看,但它确实有效.


ind*_*two 6

诚然,这是行不通的直接输出到Firebug的控制台,但对于大多数其他应用程序(即发送一个潜在的"无效"的字符串为Javascript),escapeunescape应该只是罚款:

AS3:

var testString:String = "\"\\\"\"";
ExternalInterface.call("showString", escape(testString));
Run Code Online (Sandbox Code Playgroud)

然后在Javascript中:

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

<div id="messagebox"></div>
Run Code Online (Sandbox Code Playgroud)