我正在尝试解压缩zlib压缩的XML,例如以下内容:https://drive.google.com/file/d/0B52P0MZLTdw8ZzQwQzVpZGZVZWc
上传到在线解压缩服务(如http://i-tools.org/gzip)可行。
在PHP中,我使用以下代码并且它可以正常工作,我会得到XML字符串:
$raw = file_get_contents("file_here");
$uncompressed = zlib_decode($raw);
然而,我想在JavaScript中完成这个任务。
- 该应用程序是客户端Chrome扩展程序,使用 chrome.devtools.network 从网络日志中读取数据
- 读取二进制响应。示例请参见上面的Google Drive链接
- JS需要将响应解压缩为原始XML,然后解析成对象
我唯一遇到的问题是zlib解压缩部分。
最新更新,解压缩库可以工作但解包不行,请跳转到底部的9月16日更新。
我已经尝试了几个JavaScript库,但仍无法使其正常工作:
Pako: https://github.com/nodeca/pako
unpack()
代码: https://codereview.stackexchange.com/questions/3569/pack-and-unpack-bytes-to-strings
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);
});
错误: 未捕获的不正确的头部检查
即使将响应放在其他位置也是一样:
new Uint8Array(response);
pako.inflate(response);
Imaya的zlib: https://github.com/imaya/zlib.js
$.get("file_here", function(response){
var inflate = new Zlib.Inflate(response);
var output = inflate.decompress();
console.log(output);
});
错误: Uncaught Error: 不支持的压缩方法
inflate.js:60
仍在使用Imaya's zlib,结合此Stack Overflow问题: 在JavaScript中解压缩gzip和zlib字符串
$.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-deflate: https://github.com/dankogai/js-deflate
console.log(RawDeflate.inflate(response));
输出: 空
augustl的js-inflate:https://github.com/augustl/js-inflate
console.log(JSInflate.inflate(response));
输出:空
zlib-browserify: https://github.com/brianloveswords/zlib-browserify
错误:ReferenceError: exports is not defined
这只是Imaya的zlib的包装器。我认为这是requireJS
?我甚至不确定如何使用它。它是否可以在没有安装任何东西的情况下仅使用jQuery/JS?所提到的应用程序是可下载的Chrome扩展,只需通过HTML导入JS文件即可。
2014年9月16日更新
问题似乎出现在JavaScript unpack( )
函数上。当我使用PHP生成的ByteArray:http://pastebin.com/uDWvK94B时,JavaScript解压缩函数就能正常工作。
可工作的PHP解包代码:
$unpacked = unpack("C*", $raw);
对于我使用的JavaScript unpack( )
代码,它无法正常工作,请参见本文顶部的Pako部分。
因此,新问题是,为什么JavaScript生成的ByteArray值与PHP生成的值不同。
- 这真的是
unpack( )
函数的问题吗? - 还是JS获取文件时出现了某些编码或其他变化,导致字节混乱?
- 最后,您建议采取什么措施来解决这个问题?
更新于2014年9月20日
通过更多的研究和一些答案提供线索:
- Sebastian S 提出了一个观点,认为问题在于检索数据的方式,与文本编码有关
- user3995789 提供了一个示例,即使没有
unpack( )
函数,也可以正常工作,但不能用于Chrome扩展的情况下 - Isaac 在Chrome扩展程序的上下文中提供了示例,但仍然无法正常工作
通过整合所有线索,我得出了一个理论,即这背后的原因是Chrome无法通过其request.getContent
函数获取“原始”数据。 请参见此处,以查看Chrome对该函数的文档。
目前,我已经将这个问题提交给了Chrome,请参见此处。
更新于2015年3月24日
虽然问题没有完全解决,但我认为最有用的答案来自@Sebastian S,他提出了“取或接收数据的方式”有问题,并且错误的转换是问题的原因,这与问题非常接近。
chrome.devtools.network.onRequestFinished
的 devtools,稍后会执行request.getContent(function(response){
,其中response
是我需要解压缩的响应内容。 - dragonjet