我正在尝试解压缩zlib‘’ed 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中这样做。
我唯一的问题是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);
});
错误:Uncaught incorrect header check
即使把回应放在其他地方,也是一样的:
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: unsupported compression method
inflate.js:60
仍然使用Imaya的zlib,并结合这个堆栈溢出问题:在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-通货膨胀: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:http://pastebin.com/uDWvK94B生成的http://pastebin.com/uDWvK94B时,JavaScript解压缩函数可以工作。
PHP解压缩,工作:
$unpacked = unpack("C*", $raw);
有关我使用的JavaScript unpack( )
代码(它不起作用),请参见Pako部分下面的文章顶部。
因此,新的问题是,为什么JavaScript生成的ByteArray值与PHP生成的值不同。
unpack( )
函数的问题吗?2014年9月20日更新
有更多的研究和一些答案给出线索
unpack( )
函数,它也能工作,尽管在Chrome扩展的上下文之外在此基础上,我进一步研究了所有的线索,这使我得出了一个理论,即所有这些背后的原因是Chrome无法通过其request.getContent
功能获得“原始”数据。看这里用于上述功能的Chrome文档。
到目前为止,我已经把这个问题提交给Chrome,请看这里。
2015年3月24日更新
虽然这个问题还没有完全解决,但我认为对我最有用的答案是@Sebastian S,他提出,我接收或接收数据的“方式”是错误的,而错误的转换是原因,这与问题一样近。
发布于 2014-09-16 14:31:52
在我看来,您真正应该问的问题是:如何检索压缩的数据?一旦它变成了UTF-16字符串,麻烦就开始了。我甚至不确定,从原始字节数据到javascript字符串的转换是否是无损的。
当您编写一些关于php的文章时,我假设您正在与某种后端通信。如果这是正确的,则有使用本机方法处理二进制数据的选项。也许这能帮到你:数据
发布于 2014-09-16 15:13:39
Jquery以utf8
格式读取,您必须读取原始文件,此函数才能工作。
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();
}
有关更多信息,请参见此回答。
发布于 2014-09-16 15:51:49
我知道,您希望在从网络日志中读取响应体时,在chrome扩展中使用zlib解压缩。
您需要首先检索将被解压缩的base64。您可以在使用getContent
方法时实现这一点。
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:
<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
{
"name": "My extension",
...
"permissions": [
"http://www.domain.com/", // The domain that hold the file
"http://*/" // Or every domain
],
...
}
https://developer.chrome.com/extensions/xhr
(如果你有任何问题,请随便问;)
https://stackoverflow.com/questions/25681498
复制相似问题