【问题标题】:How do I access 8-bit binary data from Javascript in Opera?如何在 Opera 中从 Javascript 访问 8 位二进制数据?
【发布时间】:2012-07-02 08:08:41
【问题描述】:

这个问题是 this StackOverflow question about IE 对 Opera 12 浏览器的扩展。

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

Example that fails in Opera 12

二进制数据正在使用 modified version of 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 中是这样填充的:

0x004B0050;给出十进制值 4915280

但应该是:

0x4034B50;十进制值为 67324752。

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

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

【问题讨论】:

    标签: javascript xmlhttprequest opera xmlhttprequest-level2


    【解决方案1】:

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

    【讨论】:

    • 将 MIME 类型设置为 application/octet-stream 确实解决了 Opera 12 中的问题(我一定是第一次在错误的地方更改了它,我将删除说它没有的评论工作)。这就是我更改的内容: this.req.overrideMimeType('application/octet-stream; charset=x-user-defined');
    • @geocodezip 请参阅 Desktop Team BlogOpera Next 了解 12.01 版本。发布日期未知。
    【解决方案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。

    【讨论】:

      猜你喜欢
      • 2021-10-28
      • 2010-12-27
      • 1970-01-01
      • 2018-09-15
      • 1970-01-01
      • 2011-11-04
      • 1970-01-01
      • 2016-10-31
      • 2018-03-16
      相关资源
      最近更新 更多