首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JavaScript Zlib解压缩

JavaScript Zlib解压缩
EN

Stack Overflow用户
提问于 2014-09-05 08:21:41
回答 3查看 9.3K关注 0票数 11

我正在尝试解压缩zlib‘’ed XML,例如:https://drive.google.com/file/d/0B52P0MZLTdw8ZzQwQzVpZGZVZWc

上传到联机解压缩服务可以工作,如:http://i-tools.org/gzip

在PHP中,我使用了这段代码并运行良好,得到了XML字符串:

代码语言:javascript
运行
复制
$raw = file_get_contents("file_here");
$uncompressed = zlib_decode($raw);

但是,我想在JavaScript中这样做。

  • 该应用程序是一个客户端Chrome扩展,它使用从网络日志中读取的chrome.devtools.network
  • 读取二进制响应。在顶部的Google链接的示例
  • JS需要解压缩对原始XML的响应,然后解析为对象。

我唯一的问题是zlib解压缩部分。

最新更新,解压缩库工作,但解压缩不起作用。请跳到底部的更新9月16日。

我已经尝试过几个JavaScript库,但仍然无法使其工作:

Pakohttps://github.com/nodeca/pako

unpack()代码:https://codereview.stackexchange.com/questions/3569/pack-and-unpack-bytes-to-strings

代码语言:javascript
运行
复制
function unpack(str) {
    var bytes = [];
    for(var i = 0, n = str.length; i < n; i++) {
        var char = str.charCodeAt(i);
        bytes.push(char >>> 8, char & 0xFF);
    }
    return bytes;
}

$.get("file_here", function(response){
    var charData    = unpack(response);
    var binData     = new Uint8Array(charData);
    var data        = pako.inflate(binData);
    var strData     = String.fromCharCode.apply(null, new Uint16Array(data));
    console.log(strData);
});

错误:Uncaught incorrect header check

即使把回应放在其他地方,也是一样的:

  • new Uint8Array(response);
  • pako.inflate(response);

Imaya的zlibhttps://github.com/imaya/zlib.js

代码语言:javascript
运行
复制
$.get("file_here", function(response){
    var inflate = new Zlib.Inflate(response);
    var output = inflate.decompress();
    console.log(output);
});

错误:Uncaught Error: unsupported compression method inflate.js:60

仍然使用Imaya的zlib,并结合这个堆栈溢出问题:在javascript中解压缩gzip和zlib字符串

代码语言:javascript
运行
复制
$.get("file_here", function(response){
    var response = response.split('').map(function(e) {
        return e.charCodeAt(0);
    });
    var inflate = new Zlib.Inflate(response);
    var output = inflate.decompress();
    console.log(output);
});

错误:Uncaught Error: invalid fcheck flag:29 inflate.js:65

dankogai的js-deflatehttps://github.com/dankogai/js-deflate

代码语言:javascript
运行
复制
console.log(RawDeflate.inflate(response));

输出:空

augustl的js-通货膨胀https://github.com/augustl/js-inflate

代码语言:javascript
运行
复制
console.log(JSInflate.inflate(response));

输出:空

zlib-browserifyhttps://github.com/brianloveswords/zlib-browserify

错误:ReferenceError: exports is not defined

这只是Imaya的zlib的包装器。我想这是requireJS?我甚至不知道该怎么用它。它甚至可以在不安装jQuery/JS的情况下使用吗?上面提到的应用程序是可下载的Chrome扩展,只有HTML导入JS文件。

2014年9月16日更新

问题似乎在于JavaScript unpack( )函数。当我使用PHP:http://pastebin.com/uDWvK94B生成的http://pastebin.com/uDWvK94B时,JavaScript解压缩函数可以工作。

PHP解压缩,工作:

代码语言:javascript
运行
复制
$unpacked = unpack("C*", $raw);

有关我使用的JavaScript unpack( )代码(它不起作用),请参见Pako部分下面的文章顶部。

因此,新的问题是,为什么JavaScript生成的ByteArray值与PHP生成的值不同。

  • 这真的是unpack( )函数的问题吗?
  • 或者是当JS获取文件时,编码或任何更改--这样字节就会被弄乱?
  • 最后,您建议的解决方案是什么?

2014年9月20日更新

有更多的研究和一些答案给出线索

  • Sebastian S打开了一个想法,即问题在于检索数据的方式,它与文本编码有关
  • user3995789提供了一个示例,说明即使没有unpack( )函数,它也能工作,尽管在Chrome扩展的上下文之外
  • 艾萨克提供了Chrome扩展上下文中的示例,但仍然不起作用

在此基础上,我进一步研究了所有的线索,这使我得出了一个理论,即所有这些背后的原因是Chrome无法通过其request.getContent功能获得“原始”数据。看这里用于上述功能的Chrome文档。

到目前为止,我已经把这个问题提交给Chrome,请看这里

2015年3月24日更新

虽然这个问题还没有完全解决,但我认为对我最有用的答案是@Sebastian S,他提出,我接收或接收数据的“方式”是错误的,而错误的转换是原因,这与问题一样近。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-09-16 14:31:52

在我看来,您真正应该问的问题是:如何检索压缩的数据?一旦它变成了UTF-16字符串,麻烦就开始了。我甚至不确定,从原始字节数据到javascript字符串的转换是否是无损的。

当您编写一些关于php的文章时,我假设您正在与某种后端通信。如果这是正确的,则有使用本机方法处理二进制数据的选项。也许这能帮到你:数据

票数 0
EN

Stack Overflow用户

发布于 2014-09-16 15:13:39

Jquery以utf8格式读取,您必须读取原始文件,此函数才能工作。

代码语言:javascript
运行
复制
function readTextFile(file)
{
    var rawFile = new XMLHttpRequest();
    rawFile.open('GET', file, true);  
    rawFile.responseType = 'arraybuffer';
    rawFile.onload = function (response)
    {
      var words = new Uint8Array(rawFile.response);
       console.log(words[1]);
      console.log(pako.ungzip(words));

    };
    rawFile.send();
}

有关更多信息,请参见此回答

票数 2
EN

Stack Overflow用户

发布于 2014-09-16 15:51:49

我知道,您希望在从网络日志中读取响应体时,在chrome扩展中使用zlib解压缩。

您需要首先检索将被解压缩的base64。您可以在使用getContent方法时实现这一点。

代码语言:javascript
运行
复制
function zlibDecompress(base64Content){
    // var base64Content        = base64Content.split(',')[1]; // Not sure if need to keep it

    // Decode base64 (convert ascii to binary)
    var strData     = atob(base64Content);

    // Convert binary string to character-number array
    var charData    = strData.split('').map(function(x){return x.charCodeAt(0);});

    // Turn number array into byte-array
    var binData     = new Uint8Array(charData);

    // Pako inflate
    var data        = pako.inflate(binData, { to: 'string' });

    return data;

}

chrome.devtools.network.onRequestFinished.addListener(
    function(request) {
        request.getContent(
            function(content, encoding){
                if(encoding == 'base64'){
                    var output = zlibDecompress(content);
                }
            }
        );
    }
);

网络#类型-请求

使用XMLHttpRequest:

代码语言:javascript
运行
复制
<script type="text/javascript" src="pako.js"></script>
<script type="text/javascript">

function zlibDecompress(url){
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'blob';

    xhr.onload = function(oEvent) {
        // Base64 encode
        var reader = new window.FileReader();
        reader.readAsDataURL(xhr.response); 
        reader.onloadend = function() {
            base64data      = reader.result;  
            var base64      = base64data.split(',')[1];

            // Decode base64 (convert ascii to binary)
            var strData     = atob(base64);

            // Convert binary string to character-number array
            var charData    = strData.split('').map(function(x){return x.charCodeAt(0);});

            // Turn number array into byte-array
            var binData     = new Uint8Array(charData);

            // Pako inflate
            var data        = pako.inflate(binData, { to: 'string' });

            console.log(data);
        }
    };

    xhr.send();
}
zlibDecompress('fileurl');
</script>

如果您想使用带有铬扩展的XMLHttpRequest

代码语言:javascript
运行
复制
{
  "name": "My extension",
  ...
  "permissions": [
    "http://www.domain.com/", // The domain that hold the file
    "http://*/" // Or every domain
  ],
  ...
}

https://developer.chrome.com/extensions/xhr

(如果你有任何问题,请随便问;)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25681498

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档