Returning a byte string to ExternalInterface.call throws an error

actionscript-3, arrays, externalinterface, flash, javascript

Solution

When data is being returned from javascript calls it's being serialized into an XML string. So if the "raw string" returned by JSZip will include characters which make the XML non-valid, which is what I think is happening here, you'll get errors like that.

What you get as a return is actually:

<string>[your JSZip generated string]</string>

Imagine your return string includes a "<" char - this will make the xml invalid, and it's hard to tell what character codes will a raw byte stream translate too.

You can read more about the external API's XML format on LiveDocs

Problem

I am working on my open source project Downloadify, and up until now it simply handles returning Strings in response to `ExternalInterface.call` commands. I am trying to put together a test case using JSZip and Downloadify together, the end result being that a Zip file is created dynamically in the browser, then saved to the disk using `FileReference.save`. However, this is my problem: The JSZip library can return either a `base64` encoded string of the Zip, or the raw byte string. The problem is, if I return that byte string in response to the `ExternalInterface.call` command, I get this error: ``` Error #1085: The element type "string" must be terminated by the matching end-tag "</string>" ``` ActionScript 3: ``` var theData:* = ExternalInterface.call('Downloadify.getTextForSave',queue_name); ``` Where `queue_name` is just a string used to identify the correct instance in JS. JavaScript: ``` var zip = new JSZip(); zip.add("test.txt", "Hello world!\n"); var content = zip.generate(true); return content; ``` If I instead return a normal string instead of the byte string, the call works correctly.I would like to avoid using `base64` as I would have to include a `base64` decoder in my `swf` which will increase its size. Finally: I am not looking for a AS3 Zip generator. It is imperative to my project to have that part run in JavaScript I am admittedly not a AS3 programmer by trade, so if you need any more detail please let me know.

Original source