我正在尝试解压缩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中执行此操作。
我唯一的问题是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,结合此Stack Overflow问题: Decompress gzip and zlib string in 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-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文件。
似乎问题出在 JavaScript unpack( )
函数上。当我使用PHP生成的ByteArray:http://pastebin.com/uDWvK94B时,JavaScript解压缩功能可以正常工作。
PHP解包有效:
$unpacked = unpack("C*", $raw);
对于我使用的JavaScript unpack( )
代码,该代码不起作用,请参阅 Pako 部分下的帖子顶部。
所以新问题是,为什么JavaScript会生成与PHP生成的值不同的ByteArray值。
unpack( )
函数确实存在问题吗?有更多的研究和一些答案在这里给出了潜在客户
unpack( )
功能,它也可以使用,但不在Chrome扩展程序的上下文中有了这个,我研究了进一步结合所有线索,这引出了一个理论,这背后的原因是Chrome无法通过其request.getContent
函数获得“原始”数据。 See here用于上述功能的Chrome文档。
截至目前,我已将问题发送给Chrome,see here。
虽然问题没有完全解决,但我认为对我来说最有用的答案来自@Sebastian S,他提出“我采取或接收数据的方式”是错误的,转换错误是原因,就像问题一样。
答案 0 :(得分:2)
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();
}
有关详细信息,请参阅此answer。
答案 1 :(得分:1)
我知道你想在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);
}
}
);
}
);
https://developer.chrome.com/extensions/devtools_network#type-Request
使用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>
如果您想使用带有chrome扩展名的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
随时问你是否有任何问题;)
答案 2 :(得分:0)
在我看来,您应该问的问题是: 如何检索压缩数据?一旦它成为UTF-16字符串,麻烦就开始了。如果从原始字节数据到javascript字符串的转换是无损的,我甚至不确定。
当你写一些关于php的东西时,我假设你正在与某种后端进行通信。如果这是真的,可以使用本机方法处理二进制数据。也许这可以帮到你:https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data