7

I am trying to create a zip file using jsZip . The contents of the zip file are images from the web. I have created the following code. But when i run it all am getting is an empty zip file of 22kb.

<html>
<body>
  <script type="text/javascript" src="jszip.js"></script>
  <script type="text/javascript" src="FileSaver.js"></script>
  <script type="text/javascript" src="jszip-utils.min.js"></script>
  <script>
    var imgLinks = ["url1", "url2", "url3"];

    function create_zip() {
      var zip = new JSZip();
      for (var i = 0; i < imgLinks.length; i++) {
        JSZipUtils.getBinaryContent(imgLinks[i], function(err, data) {
          if (err) {
            alert("Problem happened when download img: " + imgLink[i]);
            console.erro("Problem happened when download img: " + imgLink[i]);
            deferred.resolve(zip); // ignore this error: just logging
            // deferred.reject(zip); // or we may fail the download
          } else {
            zip.file("picture" + i + ".jpg", data, {
              binary: true
            });
            deferred.resolve(zip);
          }
        });
      }
      var content = zip.generate({
        type: "blob"
      });
      saveAs(content, "downloadImages.zip");
    }
  </script>
  <br/>
  <br/>
  <center>
    Click the button to generate a ZIP file
    <br/>
    <input id="button" type="button" onclick="create_zip()" value="Create Zip" />
  </center>
</body>
</html>

(url1 , url2 and url3 replaced by image urls i want to download).

Why am i getting these empty zip files?

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
Sreeraj T A
  • 142
  • 1
  • 1
  • 9
  • do you have the fixed version of this? – Nick Garver Sep 28 '16 at 01:11
  • I just used a CORS proxy . " http://www.corsproxy.com/mangacow.co/wp-content/manga/29/172/0002.jpg" .. instead of the direct url i appended it to the free CORS proxy URL, and that solved the problem. – Sreeraj T A Sep 30 '16 at 13:09

1 Answers1

7

JSZipUtils.getBinaryContent is asynchronous : the content will be added after the call to zip.generate(). You should wait for all images before generating the zip file.

Edit :

If the files you are loading are on a different server, this server need to send additional HTTP headers, like Access-Control-Allow-Origin: server-hosting-the-page.com. The Firefox or Chrome debug console will show an error in that case. The js library can't detect a CORS issue (see here) and will trigger a success with an empty content.

Community
  • 1
  • 1
David Duponchel
  • 3,959
  • 3
  • 28
  • 36
  • So how do i check if the images have completed loading, before generating the zip? – Sreeraj T A Jan 03 '15 at 05:05
  • 2
    If you are using deferred objects, you can look at [this example](http://stuk.github.io/jszip/documentation/examples/downloader.html) and the function `deferredAddZip` [here](https://github.com/Stuk/jszip/blob/v2.4.0/documentation/examples/downloader.js#L41). It uses the jQuery Deferred objects but it should be easy the modify. – David Duponchel Jan 03 '15 at 09:57
  • Than you for your replies. Tried the code and now the zip varies in size with number of files supplied and all the images are present inside the zip file, but all the images are of 0 byte and on opening in image viewer nothing is shown... Any ideas?? – Sreeraj T A Jan 03 '15 at 14:34
  • 1
    My first idea : check that you wait for the resolution of all the deferred objects before generating the zip (`$.when.apply($, deferreds)` line 75). Other than that, you can use a debugger (or console.log) to check what contains `data` (it should be an ArrayBuffer on a recent browser). If you still can't find the issue, I'll need a working code sample :) – David Duponchel Jan 03 '15 at 14:53
  • I tried that same demo code u gave and replaced the file urls with urls to some jpeg files , but the files inside the zip are 0 byte ones, and the zip file varies in size with number of images.. – Sreeraj T A Jan 03 '15 at 15:02
  • It looks like a [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) issue. When doing cross site ajax requests, the browser expects the remote file to be served with some headers (Access-Control-Allow-Origin for example). Are you trying to images hosted on a different server than your page ? – David Duponchel Jan 03 '15 at 15:10
  • Then you need to update the server to add HTTP headers (or using the curent server as proxy to download the files), see the update on my answer. – David Duponchel Jan 03 '15 at 15:27
  • So there is no other way around to do this without using the current server as a proxy ?? I was trying to keep everything on the client side , thereby reducing the time required to generate the zip. Currently i am using PHP to do this , the image files are downloaded from the external source to my server , creating a zip in the server and then returning it to the user to download. But it takes too much time as the user have to wait until the images are downloaded to my server from the external source and added to the zip. – Sreeraj T A Jan 03 '15 at 15:54
  • Regardless of the library used, a browser won't allow a cross-site ajax request if the remote server doesn't explicitly allow it. The easiest way is to update the remote server to add some headers. If that's not possible, you will need to find a work-around (using the current server as proxy is the first I though of, you may find other ones). – David Duponchel Jan 03 '15 at 16:06
  • 1
    Thank you Very much for all your answers :) – Sreeraj T A Jan 03 '15 at 16:22
  • 1
    http://gogol.6te.net/index.html , thats the demo script i am using and have succesfully found a workaround by using a CORS proxy . Its working fine in firefox, but when used in google chrome i get a "Failed-no file" error. – Sreeraj T A Jan 04 '15 at 10:22
  • It works for me on Firefox / Chromium (linux) and Firefox / Google Chrome (windows), I don't get any error. – David Duponchel Jan 04 '15 at 10:46
  • http://s14.postimg.org/tm6ykt3g1/chrome_prob.png , this is the sceenshot , My chrome is up to date . OS :windows , checked it on android too and worked fine on both chrome and firefox for android. And btw are you one of the devs of jszip? – Sreeraj T A Jan 04 '15 at 11:11
  • I see 2 errors in your screenshot (the red cross on the right with a "2"), you should check the Console tab. And yes, I'm one of the devs :) – David Duponchel Jan 04 '15 at 11:50