В JavaScript Zlib Для Распаковки
я пытаюсь распаковать 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.
- приложение является клиентским Chrome расширение, которое использует chrome.инструменты разработчика.сеть который считывает из сетевых журналов
- считывает двоичные ответы. Пример в Google Drive link вверху
- JS необходимо распаковать этот ответ на его исходный XML и затем проанализировать в object
единственная проблема, которую я имею, это часть распаковки zlib.
по состоянию на последнее обновление библиотеки декомпрессии работают, но распаковка не работает. Перейдите к обновлению 16 сентября в самом низу.
я уже пробовал несколько библиотек JavaScript и до сих пор не могу заставить его работать:
Пако: 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);
Имая это с 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
все еще используя zlib Imaya, в сочетании с этим вопросом переполнения стека: распаковать строку 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
js-сдувание данкогая: https://github.com/dankogai/js-deflate
console.log(RawDeflate.inflate(response));
выход: empty
augustl's js-inflate: https://github.com/augustl/js-inflate
Output: пустой
zlib-browserify: https://github.com/brianloveswords/zlib-browserify
ошибка: ReferenceError: exports is not defined
это просто обертка для zlib Имайи. Я думаю, это requireJS
? Я даже не знаю, как им пользоваться. Может ли это быть? используется без установки чего-либо и просто jQuery/JS? Приложение, как упоминалось, загружаемое расширение Chrome только с HTML импорта JS-файлов.
обновление 16 сентября 2014
кажется, проблема в JavaScript . Когда я использую ByteArray, сгенерированный PHP:http://pastebin.com/uDWvK94B, функции декомпрессии JavaScript работают.
PHP распаковывает это работает:
$unpacked = unpack("C*", $raw);
для JavaScript unpack( )
код, который я использую, который не работает, см. Верхнюю часть сообщения в разделе Пако.
Итак, новый вопрос: почему JavaScript генерирует другие значения ByteArray, чем тот, который генерируется PHP.
- это действительно проблема с
3 ответов
на мой взгляд вопрос вы должны задавать это: Как вы получать сжатые данные? Как только он становится строкой UTF-16, начинаются проблемы. Я даже не уверен, что преобразование из необработанных байтовых данных в строки javascript без потерь.
поскольку вы написали что-то о php, я предполагаю, что вы общаетесь с каким-то бэкэндом. Если это правда, есть опции для обработки двоичных данных с помощью собственных средств. Может быть, это поможет тебе.: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data
в jQuery-говорится в utf8
формат, вы должны прочитать raw-файл, эта функция будет работать.
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();
}
более подробно ответ.
Я понял, что вы хотите использовать декомпрессию zlib внутри расширения chrome при чтении тел ответов из сетевого журнала.
сначала вам нужно получить 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>
если вы хотите использовать XMLHttpRequest с расширение chrome
{
"name": "My extension",
...
"permissions": [
"http://www.domain.com/", // The domain that hold the file
"http://*/" // Or every domain
],
...
}
https://developer.chrome.com/extensions/xhr
не стесняйтесь спросить, если у вас есть какие-либо вопросы ;)