javascriptlzmaxz

Read xz file on client side


I have large json files on the server, which I compressed with xz. I thought I'd be a good idea to request them as such, i.e. compressed, and decompress them in javascript on the client side. I'm trying to use the LZMA-JS library, but I haven't been able to get it to work.

Here's the relevant HTML snippet:

<script src="jquery-3.3.1.min.js"></script>
<script src="lzma-d-min.js"></script>
<script src="main.js"></script>

And here's the relevant part of main.js:

$.ajax({
  type: 'POST',
  processData: false,
  contentType: false,
  url: file_name+'.json.xz',
  beforeSend: function() { element.prop("disabled", true); },
  success: function(xz) {
    // http://cdn.jwebsocket.org/lzma-js/1.3.7/demos/simple_demo.html
    console.log(xz); // 1
    LZMA.decompress(xz,
      function on_finish(result, error) {
        console.log(result); // 2
        console.log(error); // 3
        data = JSON.parse(result);
      },
      function on_progress(percent) { }
    );
    element.prop("disabled", false);
  }
});

The first console.log prints the file content correctly, at least judging by the magic numbers �7zXZ. The second prints null, and the third prints this:

Error: corrupted input
    at y (lzma-d-min.js:1)
    at L (lzma-d-min.js:1)
    at t (lzma-d-min.js:1)

Am I not using the library correctly? I can decompress the files in question without problems using xz on Linux, or lzma in python3, or boost::iostreams::lzma_decompressor in C++. I couldn't find a different javascript library to try.

I'm open to suggestions using a different compression format.


Solution

  • You're mixing up formats.

    XZ is an archive format. LZMA is the underlying stream compressor. LZMA-JS can only uncompress an LZMA stream, not an XZ archive.

    Use the lzma command-line tool to create a raw LZMA stream.