[英]JavaScript Zlib Decompress
I'm trying to decompress zlib'ed XML such as the following: https://drive.google.com/file/d/0B52P0MZLTdw8ZzQwQzVpZGZVZWc 我正在尝试解压缩zlib的XML,如下所示: https ://drive.google.com/file/d/0B52P0MZLTdw8ZzQwQzVpZGZVZWc
Uploading to online decompress services works, such as: http://i-tools.org/gzip 上传到在线解压缩服务的工作,例如: http : //i-tools.org/gzip
In PHP, I'm using this code and works just fine, I get the XML string: 在PHP中,我使用此代码并且工作正常,我得到XML字符串:
$raw = file_get_contents("file_here");
$uncompressed = zlib_decode($raw);
However, I want to do this in JavaScript. 但是,我想在JavaScript中执行此操作。
The only problem I have is the zlib decompress part. 我唯一的问题是zlib解压缩部分。
As of Latest Update, the Decompression Libraries work but unpacking doesn't. 截至最新更新,解压缩库工作但解压缩不起作用。 Please skip to the Update Sept 16 at the bottom.
请跳至底部的更新9月16日。
I have already tried several JavaScript libraries and still cannot make it work: 我已经尝试了几个JavaScript库,仍然无法使其工作:
Pako : https://github.com/nodeca/pako Pako : https : //github.com/nodeca/pako
unpack()
code: https://codereview.stackexchange.com/questions/3569/pack-and-unpack-bytes-to-strings 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);
});
Error: Uncaught incorrect header check
错误:
Uncaught incorrect header check
It's the same even placing the response elsewhere: 将响应放在其他地方也是如此:
new Uint8Array(response);
pako.inflate(response);
Imaya's zlib : https://github.com/imaya/zlib.js 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);
});
Error: Uncaught Error: unsupported compression method
inflate.js:60
错误:
Uncaught Error: unsupported compression method
inflate.js:60
Still using Imaya's zlib, combining with this Stack Overflow question: Decompress gzip and zlib string in javascript 仍然使用Imaya的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);
});
Error: Uncaught Error: invalid fcheck flag:29
inflate.js:65
错误:
Uncaught Error: invalid fcheck flag:29
inflate.js:65
dankogai's js-deflate : https://github.com/dankogai/js-deflate dankogai的js-deflate : https : //github.com/dankogai/js-deflate
console.log(RawDeflate.inflate(response));
Output: 输出:
empty
空
augustl's js-inflate : https://github.com/augustl/js-inflate augustl的js-inflate : https : //github.com/augustl/js-inflate
console.log(JSInflate.inflate(response));
Output: 输出:
empty
空
zlib-browserify : https://github.com/brianloveswords/zlib-browserify zlib-browserify : https : //github.com/brianloveswords/zlib-browserify
Error: ReferenceError: exports is not defined
错误:
ReferenceError: exports is not defined
This is just a wrapper for Imaya's zlib. 这只是Imaya的zlib的包装器。 I think this is
requireJS
? 我认为这是
requireJS
? I'm not even sure how to use it. 我甚至不确定如何使用它。 Can it even be used without installing anything and just jQuery/JS?
它甚至可以在没有安装任何东西的情况下使用,只需jQuery / JS吗? The app as mentioned is downloadable Chrome extension with just HTML importing JS files.
提到的应用程序是可下载的Chrome扩展程序,只有HTML导入JS文件。
It seems the problem is with the JavaScript unpack( )
function. 看来问题出在JavaScript
unpack( )
函数上。 When I use the ByteArray generated by PHP: http://pastebin.com/uDWvK94B , the JavaScript decompression functions work. 当我使用PHP生成的ByteArray: http : //pastebin.com/uDWvK94B时 ,JavaScript解压缩功能起作用。
PHP unpacking that works: PHP拆包工作:
$unpacked = unpack("C*", $raw);
For the JavaScript unpack( )
code that I use, which doesn't work, see top of the post under Pako section. 对于我使用的JavaScript
unpack( )
代码,这不起作用,请参阅Pako部分下的帖子顶部。
So the new question is, why does JavaScript generate a different ByteArray values than the one generated by PHP. 所以新问题是,为什么JavaScript会生成与PHP生成的值不同的ByteArray值。
unpack( )
function? unpack( )
函数的问题吗? With more research and some of the answers here giving leads 随着更多的研究和一些答案在这里提供线索
unpack( )
function, though outside the context of Chrome extensions unpack( )
函数也可以使用它,但在Chrome扩展的上下文之外 With that I researched further combining all leads which lead me to a theory that the reason behind all this is that Chrome is unable to get "raw" data through its request.getContent
function. 有了这个,我研究了进一步结合所有线索,这引出了一个理论,这背后的原因是Chrome无法通过其
request.getContent
函数获得“原始”数据。 See here for the Chrome documentation for the said function. 请参阅此处了解所述功能的Chrome文档。
As of now, I have taken the issue to Chrome, see here . 截至目前,我已将问题提交给Chrome, 请参阅此处 。
Although the problem was not fully resolved, the answer which I think was the most useful to me was from @Sebastian S, who proposed that "the way" I was taking or receiving the data was at fault and a bad conversion was the cause, which is as near as the problem was. 虽然问题没有得到彻底解决,但我认为最有用的答案来自@Sebastian S,他提出“我采取或接收数据的方式”是错误的,导致转换不良,这跟问题差不多。
Jquery reads in utf8
format, you have to read the raw file, this function will work. 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();
}
I understood that you wanna use the zlib decompression inside a chrome extension while reading reponses bodies from the network log. 我知道你想在Chrome扩展中使用zlib解压缩,同时从网络日志中读取响应主体。
You need first to retrieve the base64 who will be decompressed. 您首先需要检索将被解压缩的base64。 You can achieve this while using the
getContent
method. 您可以在使用
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 https://developer.chrome.com/extensions/devtools_network#type-Request
Using XMLHttpRequest : 使用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>
If you wanna use XMLHttpRequest with chrome extension 如果你想使用带有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 https://developer.chrome.com/extensions/xhr
Feel free to ask if you have any questions ;) 如果您有任何问题,请随时询问;)
In my opinion the question you should really be asking is: How do you retrieve the compressed data? 在我看来,你应该问的问题是: 你如何检索压缩数据? As soon as it becomes an UTF-16 string, the trouble begins.
一旦它成为UTF-16字符串,麻烦就开始了。 I'm not even sure, if the conversion from raw byte data to javascript strings is lossless.
我甚至不确定,如果从原始字节数据到javascript字符串的转换是无损的。
As you wrote something about php, I assume you're communicating to some sort of backend. 当你写一些关于php的东西时,我假设你正在与某种后端进行通信。 If this is true, there are options to handle binary data with native means.
如果这是真的,可以使用本机方法处理二进制数据。 Maybe this can help you: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data
也许这可以帮到你: https : //developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.