Почему ExternalInterface ломается, когда я передаю параметр с JSON-подобной строкой? - PullRequest
14 голосов
/ 01 марта 2011

У меня очень странная проблема с Flash 10 и ExternalInterface.В настоящее время я использую самодельный мост для использования RTMFP с Javascript, и всякий раз, когда я пытаюсь передать данные, содержащие JSON, я получаю странную ошибку Javascript, исходящую от Flash:

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

Получить дополнительную информацию невозможноэто происходит из 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);
        }

    }

}

Что я могу сделать, чтобы избежать этой проблемы, и этоизвестная проблема?

Ответы [ 2 ]

22 голосов
/ 03 марта 2011

Это, по-видимому, известная проблема, и похоже, что Adobe не собирается исправлять ее в ближайшее время.

Я нашел подробное объяснение этой проблемы, и в принципе проблема кажетсячтобы Flash не обрабатывал \ и & должным образом, что может привести к ошибке javascript или повреждению данных при переносе из Flash в javascript.

Что Flash пытается делать при передаче данныхот Flash до JS - выполнить следующую вещь:

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

Проблема в том, что он помещает ваши данные в исходное состояние и вообще не избегает обратной косой черты.Если ваша строка содержит только \ и вы хотите вызвать console.log, она попытается сделать следующее:

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

Как вы можете видеть, это недопустимый JavaScript.Он выдаст ошибку в вашей консоли Javascript и никогда не вызовет console.log.

. Решение состоит в том, чтобы либо использовать поведение Flash Ducktape, либо совершать некоторые неприятные действия, чтобы обойти его.Вспышка глючит, вы можете избежать черной косой черты, прежде чем передавать их.Это решение пока работает, но когда Flash исправит его (скорее всего, не в ближайшем будущем, если вы считаете, что эта ошибка известна более 4 лет), оно сломает ваше приложение.

другая возможность заключается в URL-кодировании символа, который Flash плохо обрабатывает (\, ", &), и декодировании их на другой стороне.

Flash:

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

Это некрасиво, но работает.

6 голосов
/ 18 ноября 2011

По общему признанию, это не будет работать напрямую для вывода на консоль в Firebug, но для большинства других приложений (т. Е. Отправка потенциально 'недопустимой' строки в Javascript), escape и unescape должны работает просто отлично:

AS3:

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

А затем в Javascript:

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

<div id="messagebox"></div>
...