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

发布于 2024-08-18 06:01:34 字数 1236 浏览 1 评论 0 原文

我正在开发我的开源项目 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 因为我必须包含 swf 中的 >base64 解码器这会增加其大小。

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

拔了角的鹿 2024-08-25 06:01:35

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

您得到的返回实际上是:

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

想象您的返回字符串包含一个“<” char - 这将使 xml 无效,并且很难判断原始字节流将翻译哪些字符代码。

您可以在 LiveDocs

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

战皆罪 2024-08-25 06:01:35

我认为问题是由以下事实引起的:flash 需要一个 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 数据,否则这是正确的方法...

i think the problem is caused by the fact, that flash expects a utf8 String and you throw some binary stuff at it. i think for example 0x00FF will not turn out to be valid utf8 ...

you can try fiddling around with flash.system::System.setCodePage, but i wouldn't be too optimistic ...

i guess a base64 decoder is probably really the easiest ... i'd rather worry about speed than about file size though ... this rudimentary decoder method uses less than half a 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;
}

you could simply shorten function names and take a smaller image ... or use ColorTransform or ConvolutionFilter on one image instead of four ... or compile the image into the SWF for smaller overall size ... or reduce function name length ...

so unless you're planning on working with MBs of data, this is the way to go ...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文