Peter Robinson
Peter Robinson

Reputation: 383

Extract image file from zipfile in node.js and upload file to server

I want my users to select a zip file containing image files in the browser. I then examine the zip file and select which image files to send to a remote server (where they get processed, etc). This is working fine for loading up the zip file and identifying the files in it. I select the file by an

    <input type="file"> 

element; I read it in as a zip file using the excellent JSZip library:

    var zip = new JSZip();
    zip.loadAsync("file selected in browser")

I then identify the zip files in this file:

    for (var key in zip.files) {
      var myFile=zip.files[key]; }

Now, with JSZip, I can extract each compressed file:

    zip.files["key for this file"].async("base64").then(function (myImage) {
      //send this image to a remote server as if it were a file
    });

The problem is with the last step. I can't figure out the right combination of calls, parameters, etc, to get this uploaded correctly. It seems the obvious thing is to create a formData object and send it up from there, so:

    var fd = new FormData();                  
    fd.append("file", myImage);

and then post it up ajax:

    $.ajax({
        type: 'POST',
        url: url,
        enctype: 'multipart/form-data',
        contentType: false,
        dataType: false,
        processData: false,
        data: fd,
    }).done(function(data){
       //do something with returned data
    })

However, this is not working at the server end (though the same file sent to the same address from the form works fine). What am I missing? Or can I not do this with $.ajax (or the npm http module), and have to use something more low level, like the npm request module?

Help!

Upvotes: 0

Views: 1682

Answers (1)

Peter Robinson
Peter Robinson

Reputation: 383

OK, figured it out. Mostly by trial and (mostly) error, but here is what works. First, you have to extract the file from the zip file as a "blob", so:

zip.files["key for this file"].async("blob").then(function (myImage) {
  //send this image to a remote server as if it were a file
});

Then, when you have the blob, you have to embed it in ANOTHER blob, as follows:

var blob = new Blob([myImage], { type: "image/jpeg"});

You then make a new FormData object, and add our new file blob to it:

var fd = new FormData();
fd.append('file', blob, 'myFile.jpg');  

And then you call $.ajax (if you are using jquery), so:

$.ajax({
  type: 'POST',
  url: url,
  enctype: 'multipart/form-data',
  contentType: false,
  dataType: false,
  processData: false,
  data: fd,
})
 .done (function(data){
   //do something with the success
})

And that works perfectly. Frankly, it seems really odd to stick a blob inside a blob, but it works, so there.

Upvotes: 1

Related Questions