wake-up-neo.com

Dekomprimieren Sie gzip und zlib in Javascript

Ich möchte komprimierte Layer-Daten aus einer TMX-Datei erhalten. Wer kennt Bibliotheken zum Dekomprimieren von gzip- und zlib-Strings in Javascript? Ich versuche zlib aber es funktioniert nicht bei mir. Beispiel: Layer-Daten in der TMX-Datei sind:

  <data encoding="base64" compression="zlib">
       eJztwTEBAAAAwqD1T20JT6AAAHgaCWAAAQ==
  </data>

Mein Javascript Code ist

var base64Data = "eJztwTEBAAAAwqD1T20JT6AAAHgaCWAAAQ==";
var compressData = atob(base64Data);
var inflate = new Zlib.Inflate(compressData);
var output = inflate.decompress();

Es wird mit der Meldung "Nicht unterstützte Komprimierungsmethode" ausgeführt. Aber ich versuche mit dem Online-Tool zu dekomprimieren, wie http://i-tools.org/gzip , es gibt die richtige Zeichenfolge zurück.

21
Toan Nguyen

Ich kann mein Problem mit zlib lösen. Ich behebe meinen Code wie folgt

var base64Data = "eJztwTEBAAAAwqD1T20JT6AAAHgaCWAAAQ==";
var compressData = atob(base64Data);
var compressData = compressData.split('').map(function(e) {
    return e.charCodeAt(0);
});
var inflate = new Zlib.Inflate(compressData);
var output = inflate.decompress();
9
Toan Nguyen

Pako ist ein voller und moderner Zlib Port.

Hier ist ein sehr einfaches Beispiel und Sie können von dort aus arbeiten.

Holen Sie sich pako.js und Sie können byteArray wie folgt dekomprimieren:

<html>
<head>
  <title>Gunzipping binary gzipped string</title>
  <script type="text/javascript" src="pako.js"></script>
  <script type="text/javascript">

    // Get datastream as Array, for example:
    var charData    = [31,139,8,0,0,0,0,0,0,3,5,193,219,13,0,16,16,4,192,86,214,151,102,52,33,110,35,66,108,226,60,218,55,147,164,238,24,173,19,143,241,18,85,27,58,203,57,46,29,25,198,34,163,193,247,106,179,134,15,50,167,173,148,48,0,0,0];

    // Turn number array into byte-array
    var binData     = new Uint8Array(charData);

    // Pako magic
    var data        = pako.inflate(binData);

    // Convert gunzipped byteArray back to ascii string:
    var strData     = String.fromCharCode.apply(null, new Uint16Array(data));

    // Output to console
    console.log(strData);

  </script>
</head>
<body>
    Open up the developer console.
</body>
</html>

Laufendes Beispiel: http://jsfiddle.net/9yH7M/

Alternativ können Sie das Array vor dem Senden mit base64 codieren, da das Array beim Senden als JSON oder XML viel Aufwand verursacht. Dekodiere ebenfalls:

// Get some base64 encoded binary data from the server. Imagine we got this:
var b64Data     = 'H4sIAAAAAAAAAwXB2w0AEBAEwFbWl2Y0IW4jQmziPNo3k6TuGK0Tj/ESVRs6yzkuHRnGIqPB92qzhg8yp62UMAAAAA==';

// Decode base64 (convert ascii to binary)
var strData     = atob(b64Data);

// 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 magic
var data        = pako.inflate(binData);

// Convert gunzipped byteArray back to ascii string:
var strData     = String.fromCharCode.apply(null, new Uint16Array(data));

// Output to console
console.log(strData);

Laufendes Beispiel: http://jsfiddle.net/9yH7M/1/

Weiterführende Informationen finden Sie in der pako API-Dokumentation .

26
Redsandro

Für alle, die Ruby on Rails verwenden und komprimierte, codierte Daten an den Browser senden und anschließend über JavaScript im Browser dekomprimieren möchten, habe ich die beiden oben genannten hervorragenden Antworten in der folgenden Lösung kombiniert der Rails-Servercode in meinem Anwendungs-Controller, der einen String komprimiert und codiert, bevor er über eine @ -Variable an den Browser gesendet wird in eine . html.erb Datei:

require 'zlib'
require 'base64'

    def compressor (some_string)
        Base64.encode64(Zlib::Deflate.deflate(some_string))
    end

Hier ist die Javascript-Funktion, die pako.min.js verwendet:

function uncompress(input_field){
    base64data = document.getElementById(input_field).innerText;
    compressData = atob(base64data);
    compressData = compressData.split('').map(function(e) {
        return e.charCodeAt(0);
    });
    binData = new Uint8Array(compressData);
    data = pako.inflate(binData);
    return String.fromCharCode.apply(null, new Uint16Array(data));
}

Hier ist ein Javascript-Aufruf für diese Dekomprimierungsfunktion, mit der Daten, die in einem versteckten HTML-Feld gespeichert sind, dekomprimiert und dekomprimiert werden sollen:

my_answer = uncompress('my_hidden_field');

Hier ist der Eintrag in der Datei Rails application.js , um pako aufzurufen. min.js im Verzeichnis /vendor/assets/javascripts :

//= require pako.min

Und ich habe die pako.min.js Datei von hier bekommen:

https://github.com/nodeca/pako/tree/master/dist

Alles funktioniert auf jeden Fall bei mir! :-)

4
Andy Duncan