-3

这个问题是关于 IE到 Opera 12 浏览器的StackOverflow 问题的扩展。

根本问题是geoxml3处理kmz(压缩的kml)文件的问题。

在 Opera 12 中失败的示例

二进制数据在 ZipFile.complete.js 的修改版本中使用 TypedArrays进行处理

传输二进制文件后,Opera 12 中的 Uint8Array 未正确填充,就好像数据被导入为 16 位元素一样。

请求配置如下:

this.req.responseType = 'arraybuffer';
this.req.overrideMimeType('text/plain; charset=x-user-defined');

返回的值是这样处理的:

var fileContents = binStream.req.response;
binStream.length = fileContents.byteLength;
binStream.array = new Uint8Array(fileContents);

在 Opera 12 中,前 8 个字节是这样填充的:

0x004B0050; 给出 4915280 的十进制值

但应该是:

0x4034B50; 十进制值 67324752。

这在 Firefox、Chrome 和 IE 中可以正常工作(有解决方法)。

有谁知道我如何说服 Opera 12 正确填充 Uint8Array?还是一种解决方法,以便它可以工作(某种方式将 16 位字节数组转换为 8 位字节数组,尽可能有效地丢弃不需要的高 8 位)?这是最近在 Opera 12 中实现 TypedArray/XmlHttpRequest 的已知错误吗?

4

2 回答 2

8

Opera 12.00 引入了对responseType; 不幸的是,其中有一个错误,这意味着给定一个text/*MIME 类型,您最终会将文件作为 16 位字。它已在 12.01 中修复,但最简单的修复方法是将覆盖类型设置为application/octet-stream. (这是 CORE-46938,适用于那些希望跟踪封闭错误跟踪器的人。)

于 2012-07-04T04:34:52.593 回答
2

这个“补丁”有效:

var fileContents = binStream.req.response;
binStream.length = fileContents.byteLength;
binStream.array = new Uint8Array(fileContents);

/* patch for Opera */
if (/opera/i.test(navigator.userAgent) && 
    // make sure it is still broken,
    // the first 4 bytes will contain the zip file signature
    // for the geoxml3 use case (so bytes 1 & 3 will not be 0)
    (binStream.array[1] == 0) && (binStream.array[3] == 0))
{    
    fixedArray = new Uint8Array(binStream.length/2);
    for (var i=0; i<binStream.length; i+=2) {
        fixedArray[i/2]=binStream.array[i];
    }
    binStream.array = fixedArray;
    binStream.length = binStream.length/2;
}
/* end patch for Opera */

有没有更有效的方法来做到这一点?有没有人知道不做浏览器特定测试的方法?

编辑:添加检查以确保行为仍然被破坏(以防它是一个错误并已修复)。在一般情况下可能不起作用,但对于 geoxml3 用例,前 4 个字节将包含 zip 文件签名,如果它正常工作,高位字节中不会有 0。

于 2012-07-01T21:20:21.470 回答