How?

Why?

  1. JavaScript today is capable of generating a lot of data. The easiest way to deliver multiple files to your users is in a zip file. Instead of wasting server resources and bandwidth you can get the client to do it for you.
  2. Because it's cool!

Where?

Download from Github

See also: the test suite


Tell me more!

Browser support

Opera Firefox Safari Chrome Internet Explorer
7.5+ 3.0+ Yes Yes No
Filename is "default.zip" Filename is random alphanumeric with ".part" extension Filename is "Unknown" (no extension) Filename is "download.zip" on OSX and Linux, and just "download" on Windows (issue #9) Only supports data URLs for some content. (May be able to use MHTML?)

Tests still need to be run on historical browsers to check which versions are supported.

Filename problems

The biggest issue with JSZip is that the filenames are very awkward, Firefox generates filenames such as a5sZQRsx.zip.part (see bugs 367231 and 532230), and Safari isn't much better with just Unknown. Sadly there is no pure Javascript solution to this. However...

Solution-ish: Downloadify

Downloadify uses a small Flash SWF to download files to a user's computer with a filename that you can choose. Doug Neiner has added the dataType option to allow you to pass a zip for downloading. Follow the Downloadify demo with the following changes:

zip = new JSZip();
zip.add("Hello.", "hello.txt");
Downloadify.create('downloadify',{
...
  data: function(){
    return zip.generate();
  },
...
  dataType: 'base64'
});

Usage with Google Gears

Franz Buchinger has written a brilliant tutorial on using JSZip with Google Gears (part 2). If you want to let your Gears users download several files at once I really recommend having a look at some of his examples.

Documentation

new JSZip([compressionMethod])

The constructor

compressionMethod, string. The compression method to use for the zip file.

Available methods :

var zip = new JSZip(); // same as new JSZip("STORE");
var zip = new JSZip("DEFLATE");

add(name, data [,options])

Add a file to the zip file. Supports chaining.

Options:

zip.add("Hello.txt", "Hello World\n");
zip.add("smile.gif", "R0lGODdhBQAFAIACAAAAAP/eACwAAAAABQAFAAACCIwPkWerClIBADs=", {base64: true});
zip.add("magic.txt", "U2VjcmV0IGNvZGU=", {base64: true, binary: false});
zip.add("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")});

zip.add("animals.txt", "dog,platypus\n").add("people.txt", "james,sebastian\n");

Result: Hello.txt, smile.gif, magic.txt, Xmas.txt, animals.txt, people.txt

folder(name)

Add a directory to the zip file. Supports chaining.

zip.folder("images");
zip.folder("css").add("style.css", "body {background: #FF0000}");
// or specify an absolute path (using forward slashes)
zip.add("css/font.css", "body {font-family: sans-serif}")

Result: images/, css/, css/style.css, css/font.css

find(needle)

Compare a string or regular expression against all of the filenames and returns an informational object for each that matches.

zip.add("Readme", "Hello World!\n");
zip.add("Readme.French", "Bonjour tout le monde!\n");
zip.add("Readme.Pirate", "Ahoy m'hearty!\n");

zip.find("Readme"); // only finds "Readme"
zip.find(/^Readme/); // Regular expression finds all three

Result: Array of matched file objects in the form: {name: "Readme", data: "Hello World!", dir: false}

remove(name)

Delete a file or folder.

zip.add("Hello.txt", "Hello World\n");
zip.add("temp.txt", "nothing").remove("temp.txt");

Result: Hello.txt

zip.add("Hello.txt", "Hello World\n");
zip.folder("css").add("style.css", "body {background: #FF0000}");
zip.remove("Hello.txt").remove("css");

Result: Empty zip.

generate(asBytes = false)

Generates the complete zip file. By default encoded as base64, pass true to get the raw byte string

content = zip.generate();
location.href="data:application/zip;base64,"+content;
content = zip.generate(true);
for (var c = 0; c < content.length; c++)
{
    console.log(content.charCodeAt(c));
    // do other things
}

Anything else?

License

GPLv3 and/or MIT

Todo

Who?

Stuart Knightley, with contributions from:

Thanks and comments