using zip.js to read a zip file via xmlhttp/ajax call on Node.js

2.3k views Asked by At

I am trying to :

  1. Send a zip file via xmlhttp to the client
  2. then read the file using zip.js and render its contents

I successfully receive the binary of the file i.e. the success callback is called but I get and error when I try to do getEntries. I think the error is with the way of sending stream , please help.

Error msg :

Error in reading zip file

My client side code (using angular) :

$http.get(window.location.origin + '/book/'+bookName,{responseType:"Blob"}).
success(function (data , error) {
    var a = new Uint8Array(data);
        //var dataView = new DataView(data);
        //var blob = new Blob(dataView.buffer);
    zip.useWebWorkers = true;
    zip.workerScriptsPath = '/js/app/';

    zip.createReader(new zip.BlobReader(data), function(reader) {

      // get all entries from the zip
      reader.getEntries(function(entries) {   //HERE I GET THE ERROR
        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
              var a = 0;
            });

          }, function(current, total) {
            // onprogress callback
            var a = 0;
          });
        }
      });
    },
     function(error) {
      // onerror callback
        var a = 0;
    });


})
.error( function (data , error) {
    var a = 0;

});

My Server side code on Node:

router.get('/book/:bookName',function (req , res ) {


console.log('Inside book reading block : ' + req.params.bookName);
req.params.bookName += '.zip';

var filePath = path.join(__dirname,'/../\\public\\books\\' ,req.params.bookName );
var stat = fileSystem.statSync(filePath);

res.writeHead(200, {
    //'Content-Type': 'application/zip',
    'Content-Type': 'blob',
    'Content-Length': stat.size
});

var readStream = fileSystem.createReadStream(filePath);
// replace all the event handlers with a simple call to readStream.pipe()
readStream.pipe(res);   
});
1

There are 1 answers

1
Sandeep On

It is probable that you might have already found a solution. I faced the same problem today and this is how I solved it in plain javascript:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'assets/object/sample.zip', true);
xhr.responseType = 'arraybuffer';

xhr.onload = function(e) {
    // response is unsigned 8 bit integer
    var responseArray = new Uint8Array(this.response);
    var blobData = new Blob([responseArray], {
        type: 'application/zip'
    });
    zip.createReader(new zip.BlobReader(blobData), function(zipReader) {
        zipReader.getEntries(displayEntries);
    }, onerror);
};

xhr.send();

The problem I see in your code is that you are changing the value to Uint8Array and assigning it to var a, but still use the raw data in blobreader. Also the blob reader required blob and not an array. So you should have converted var a into blob and then used it for reading.