将字节字符串返回到ExternalInterface.call会引发错误

时间:2010-01-21 05:57:00

标签: javascript flash actionscript-3 bytearray externalinterface

我正在开发我的开源项目Downloadify,直到现在它只是处理返回的字符串以响应ExternalInterface.call命令。

我正在尝试使用JSZip和Downloadify组合测试用例,最终结果是在浏览器中动态创建Zip文件,然后使用FileReference.save保存到磁盘。但是,这是我的问题:

JSZip库可以返回Zip的base64编码字符串或原始字节字符串。问题是,如果我返回该字节字符串以响应ExternalInterface.call命令,我会收到此错误:

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

其中queue_name只是用于标识JS中正确实例的字符串。

JavaScript的:

var zip = new JSZip();
zip.add("test.txt", "Hello world!\n");
var content = zip.generate(true);
return content;

如果我改为返回普通字符串而不是字节字符串,则调用正常。我想避免使用base64,因为我必须在{{1}中包含base64解码器这会增加它的大小。

最后:我正在寻找AS3 Zip生成器。我的项目必须让该部分在JavaScript中运行

我确信不是 AS3程序员的交易,所以如果您需要更多详细信息,请告诉我。

2 个答案:

答案 0 :(得分:3)

当从javascript调用返回数据时,它被序列化为XML字符串。因此,如果JSZip返回的“原始字符串”将包含使XML无效的字符,这就是我认为这里发生的错误,那么你会得到类似的错误。

你得到的回报实际上是:

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

想象一下你的返回字符串包含一个“&lt;” char - 这会使xml无效,并且很难说原始字节流也将转换为字符代码。

您可以在LiveDocs

上详细了解外部API的XML格式

答案 1 :(得分:1)

我认为这个问题是由闪存需要一个utf8字符串并且你抛出一些二进制内容这一事实引起的。我认为例如0x00FF不会变成有效的utf8 ...

你可以尝试摆弄flash.system::System.setCodePage,但我不会太乐观......

我认为base64解码器可能真的是最简单的...我宁愿担心速度而不是文件大小...虽然这个基本的解码器方法使用不到半个K:

public function decodeBase64(source:String):ByteArray {
 var ret:ByteArray = new ByteArray();
 var map:Object = new Object();
 var i:int = 0;
 for each (var char:String in "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("")) map[char] = i++;
 map["="] = 0;
 source = source.split("\n").join("").split("\r").join("");//remove linebreaks
 for (i = 0; i < source.length/4; i++) {
  var buf:int = 0;
  for each (char in source.substr(i * 4, 4).split("")) buf = (buf << 6) + map[char];
  ret.writeByte(buf >>> 16);
  ret.writeShort(buf);
 }
 return ret;
}

您可以简单地缩短功能名称并拍摄较小的图像......或者在一张图像上使用ColorTransformConvolutionFilter而不是四张...或者将图像编辑到SWF中以获得更小的整体尺寸...或减少函数名称长度...

所以,除非你打算使用MB数据,否则这就是你想要的方法......