Uncompress a file with JavaScript

2.3k Views Asked by At

I need to load a json file into a Javascript container. On the user's browser, the json file is loaded into the Javascript library which processes the data. However, this file is getting quite large (10MB) but if I compress it I can get it down to 100KB.

I therefore want to compress the file on the server, download it using ajax, uncompress it and load it into my javascript container.

Generating the zip file is easy. What I'm struggling with is downloading the file and uncompressing it. I found a library called zip.js. I've followed their example, but I just can't get it to work. I think the way I'm loading the file is incorrect.

This is what I currently have:

var file_data = $.ajax({
            url: "/path/to/file.zip",
            async: false
         }).responseText;

zip.createReader(new zip.TextReader(file_data), function(reader) {
  // get all entries from the zip
  reader.getEntries(function(entries) {
    if (entries.length) {
      // get first entry content as text
      entries[0].getData(new zip.TextWriter(), function(text) {
        // text contains the entry data as a String
        console.log(text);
        // close the zip reader
        reader.close(function() {
          // onclose callback
        });

      }, function(current, total) {
        // onprogress callback
      });
    }
  });
}, function(error) {
  // onerror callback
  console.log(error);
});

The error I get is:

File format is not recognized.

I also tried the BlobReader without success and the HttpReader class is not working for me, I get

zip.HttpReader is not a constructor

1

There are 1 best solutions below

0
On BEST ANSWER

This is where you are doing wrong

var file_data = $.ajax({
    url: "/path/to/file.zip",
    async: false
}).responseText;
  • first of all async is bad practice and deprecated don't use it
  • second: jQuery's ajax don't handle binary so well. it always wants to treat everything as string which will cuz the binary to be parsed and transformed by the browser
    you don't want that. Your zip data will be corrupted

you should retrive the raw binary as is using either xhr.responseType = 'blob'

or using the new fetch api

fetch('file.zip').then(res => res.blob()).then(unzipBlob)

So forget jQuery...

If you want a synchronous feeling then you should use async/await + promises this is however only available in Blink (chrome/opera) you could also use babel

async function downlaod() {
   let res = await fetch(file)
   let file_data = await res.blob()

   // and so on...
}