В 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

не стесняйтесь спросить, если у вас есть какие-либо вопросы ;)