21

I am receiving data as an "ZLIB" compressed inputstream.

Using Javascript/Ajax/JQuery, I need to uncompress it on the client side.

Is there a way to do so?

I already have this working in JAVA as below, but need to do this on Client Side.

url = new URL(getCodeBase(), dataSrcfile); 
URLConnection urlConn = url.openConnection();
urlConn.setUseCaches(false); 
InputStream in = urlConn.getInputStream();
InflaterInputStream inflate = new InflaterInputStream(in);
InputStreamReader inputStreamReader = new InputStreamReader(inflate);
InputStreamReader inputStreamReader = new InputStreamReader(in);
BufferedReader bufReader = new BufferedReader(inputStreamReader);
// Read until no more '#'
int i = 0;
int nHidden = 0;
String line1;
do //------------------------Parsing Starts Here
{
    line1 = bufReader.readLine();
.............
...... so on
desertnaut
  • 57,590
  • 26
  • 140
  • 166
Rajeev Raina
  • 239
  • 1
  • 3
  • 8
  • 1
    Why? Just use HTTP compression, the browser will handle that transparently. – Quentin Dec 22 '10 at 08:20
  • 2
    What if the server side already exists and cannot be changed? I agree that it would be better to do the compression at the HTTP level. But you're not always given a choice. – Codo Dec 22 '10 at 08:40
  • Did you try compiling the zlib C code to javascript? It seems like Emscripten could do this. – nside May 29 '11 at 17:04
  • Does this answer your question? [Decompress gzip and zlib string in javascript](https://stackoverflow.com/questions/14620769/decompress-gzip-and-zlib-string-in-javascript) – Vladimir Panteleev Feb 10 '20 at 02:24

9 Answers9

28

Pako is a full and modern Zlib port.

Here is a very simple example and you can work from there.

Get pako.js and you can decompress byteArray like so:

<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>

Running example: http://jsfiddle.net/9yH7M/

Alternatively you can base64 encode the array before you send it over as the Array takes up a lot of overhead when sending as JSON or XML. Decode likewise:

// 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);

Running example: http://jsfiddle.net/9yH7M/1/

To go more advanced, here is the pako API documentation.

Redsandro
  • 11,060
  • 13
  • 76
  • 106
  • Thanks for the constructive comment about why my working example is being downvoted. – Redsandro Aug 03 '14 at 17:05
  • 4
    To get a string from the uncompressed data, you can also just do as follow: `var strData = pako.inflate(binData, { to: 'string' });`. See options here: http://nodeca.github.io/pako/#inflate – Julien P Sep 21 '15 at 18:33
13

A more recent offering is https://github.com/imaya/zlib.js

I think it's much better than the alternatives.

user1009908
  • 1,390
  • 13
  • 22
  • 1
    I'd rather use library with english documentation, this one has readme in some asian language, looks japanese or chinese to me. – Tener Jun 10 '13 at 20:44
  • 8
    I fail to see how that matters. The API is clear if you're familiar with zlib. This library is very well-designed, fast, and easy to use. – user1009908 Jun 11 '13 at 22:07
  • 11
    The English documentation is available by clicking the link marked [English Documentation](https://github.com/imaya/zlib.js/blob/master/README.en.md). – dotancohen Nov 21 '13 at 08:20
  • I had a better experience with Pako.js than imaya/zlib.js – Saran Apr 09 '20 at 19:00
3

Try pako https://github.com/nodeca/pako , it's not just inflate/deflate, but exact zlib port to javascript, with almost all features and options supported. Also, it's the fastest implementation in modern browsers.

Vitaly
  • 3,340
  • 26
  • 21
  • 3
    Upvoted. Could you provide a client-side example (including which files are required)? All documentation is about using (server side) `node.js`. – Redsandro Mar 26 '14 at 02:28
  • There's a browser example here: https://github.com/nodeca/pako/blob/master/examples/browser.html – thameera May 29 '20 at 01:12
3

Our library JSXGraph contains the deflate, unzip and gunzip algorithm. Please, have a look at jsxcompressor (a spin-off from JSXGraph, see http://jsxgraph.uni-bayreuth.de/wp/download/) or at Utils.js in the source code.

2

Just as the first comments to your question suggest, I would suspect that you actually want the browser to handle the decompression. If I am mistaken, you might want to check out the JSXGraph library, it is supposed to contain pure JS implementations for deflate and unzip.

cg.
  • 3,648
  • 2
  • 26
  • 30
  • Thanks for the reply, but I am bit confused. I checked the JSXGraph, but it looks like a library to draw shapes like Arc, Circle etc. Do you please have a pure HTML and JavaScript (no PHP) example where a file (input sream) compressed with Zlib can be un-compressed. Please help – Rajeev Raina Dec 22 '10 at 10:14
1

The js-deflate project by dankogai may be what you are looking for. I haven't actually tried it, but the rawinflate.js code seems fairly minimal, and should be able to decompress DEFLATE/zlib:ed data.

marcus256
  • 231
  • 2
  • 6
1

Using Pako you can decode the compressed(gzib) response, short code for above answer

JSON.parse(Pako.inflate(Buffer.from(data, 'base64'), { to: 'string' }))

Buffer.from, Pako

Abdul Malik
  • 541
  • 4
  • 16
0

Browserify-zlib works perfectly for me, it uses pako and has the exact same api as zlib. After I struggled for days with compressing/decompressing zlib encoded payloads in client side with pako, I can say that browserify-zlib is really convenient.

tanktg
  • 1
  • 2
0

you should see zlib rfc.

the javascript inflate code I tested: inflate in Javascript

the java code I wrote:

    static public byte[] compress(byte[] input) {
    Deflater deflater = new Deflater();
    deflater.setInput(input, 0, input.length);
    deflater.finish();
    byte[] buff = new byte[input.length + 50];
    deflater.deflate(buff);

    int compressedSize = deflater.getTotalOut();

    if (deflater.getTotalIn() != input.length)
        return null;

    byte[] output = new byte[compressedSize - 6];

    System.arraycopy(buff, 2, output, 0, compressedSize - 6);// del head and
                                                                // foot byte
    return output;
}

The very Important thing is in deflate in Java you must cut the head 2 byte,foot 4 byte,to get the raw deflate.

desertnaut
  • 57,590
  • 26
  • 140
  • 166
summer
  • 47
  • 4