| Opera | Firefox | Safari | Chrome | Internet Explorer |
|---|---|---|---|---|
| Yes | Yes | Yes | Yes | Yes |
| Tested with the latest version | Tested with 3.0 / 3.6 / latest version | Tested with the latest version | Tested with the latest version | Tested with IE 6 / 7 / 8 / 9 |
While JSZip should work everywhere, the tricky part is to give the zip file to the user.
| 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?) |
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...
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'
});
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.
When doing an ajax call to get the binary data, the browser will try to interpret the binary as text, corrupting it. The solution is to set the mimetype to 'text/plain; charset=x-user-defined'. This solution works well in all browsers but IE. If you need IE support, please see what is done in the file test/index.html.
load() for more details and this for the limitations.data (String/binary) the content of the zip file to load.options (Object) options to pass to the load() method..
new JSZip(zipDataFromXHR, {base64:false});
// same as
var zip = new JSZip();
zip.load(zipDataFromXHR, {base64:false});
name (String) the name of the file.null otherwise. The file has the following structure :
name the absolute path of the filedata the data contained in the fileoptions the options of the file. The available options are :
base64, boolean, cf file(name, data [,options])binary, boolean, cf file(name, data [,options])dir, boolean, true if this is a directorydate, date, cf file(name, data [,options])asText(), string, the content as an utf8 string (utf8 encoded if necessary).asBinary(), string, the content as binary (utf8 decoded if necessary).
var zip = new JSZip();
zip.file("file.txt", "content");
zip.file("file.txt").name // "file.txt"
zip.file("file.txt").data // "content"
zip.file("file.txt").options.dir // false
// utf8 example
var zip = new JSZip(zipFromAjaxWithUTF8);
zip.file("amount.txt").data // "â¬15"
zip.file("amount.txt").asText() // "€15"
regex (RegExp) the regex to use.
var zip = new JSZip();
zip.file("file1.txt", "content");
zip.file("file2.txt", "content");
zip.file(/file/); // array of size 2
// example with a relative path :
var folder = zip.folder("sub");
folder
.file("file3.txt", "content") // relative path from folder : file3.txt
.file("file4.txt", "content"); // relative path from folder : file4.txt
folder.file(/file/); // array of size 2
folder.file(/^file/); // array of size 2, the relative paths start with file
// arrays contain objects in the form:
// {name: "file2.txt", data: "content", dir: false}
name (String) the name of the file.data (binary) the content of the file.options (Object) the options :
base64 (boolean) set to true if the data
is base64 encoded. For example image data from a <canvas> element.
Plain text and HTML do not need this option.binary (boolean) defaults to true if the data
is base64 encoded, false otherwise. If set to false then
UTF-8 characters will be encoded.date (Date) use it to specify the last modification date.
If not set the current date is used.
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("folder/file.txt", "file in folder");
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/, folder/file.txt
name (String) the name of the directory.
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
regex (RegExp) the regex to use.
var zip = new JSZip();
zip.folder("home/Pierre/videos");
zip.folder("home/Pierre/photos");
zip.folder("home/Jean/videos");
zip.folder("home/Jean/photos");
zip.folder(/videos/); // array of size 2
zip.folder("home/Jean").folder(/^vid/); // array of 1
Delete a file or folder.
name (String) the name of the file/folder to delete.
var zip = new JSZip();
zip.add("Hello.txt", "Hello World\n");
zip.add("temp.txt", "nothing").remove("temp.txt");
// result : Hello.txt
zip.folder("css").add("style.css", "body {background: #FF0000}");
zip.remove("Hello.txt").remove("css");
//result : empty zip
options (Object) the options to generate the zip file :
base64 (boolean) false to get the result as a raw byte string.
Default : true, encode as base64.compression (String) the compression method to use. "STORE" (no compression) by default,
you can use "DEFLATE" (include the file jszip-deflate.js) or write your own.content = zip.generate(); location.href="data:application/zip;base64,"+content;
content = zip.generate({base64:false});
for (var c = 0; c < content.length; c++)
{
console.log(content.charCodeAt(c));
// do other things
}
data (binary) the zip fileoptions (Object) the options to load the zip file :
base64 (boolean) true if the data is base64 encoded, false for binary. Default : false.checkCRC32 (boolean) true if the read data should be checked against its CRC32. Default : false.var zip = new JSZip(); zip.load(zipDataFromXHR);
DEFLATE with jszip-deflate.js)predicate (function) the predicate to use : function (relativePath, file) {...} It takes 2 arguments : the relative path and the file.
relativePath (String) The filename and its path, reliatively to the current folder.file (Object) The file being tested. Like the result of file(name), the file has the form {name:"...", data:"...", options:{...}}.
var zip = new JSZip().folder("dir");
zip.file("readme.txt", "content");
zip.filter(function (relativePath, file){
// relativePath == "readme.txt"
// file = {name:"dir/readme.txt",data:"content",options:{...}}
return true/false;
});
The first limitation comes from the limited subset of supported zip features.
Classic zip files will work but encrypted zip, multi-volume, etc are not supported
and the load() method will throw an Error.
The second limitation comes from the browser (and the machine running the browser).
A compressed zip file of 10M is common and easily opened by desktop application,
but not in a browser. The processing of such a beast is likely to be painful :
the browser will eat hundreds of megabytes while using CPU like never.
If you use an old browser, things will be worse. For example, IE6 and IE7 are
quite slow to to execute the unit tests, and they completely freeze as soon as
they try to handle larger files.
Conclusion : reading small files is OK, reading others is not.
Third limitation : reading and generating a zip file won't give you back the same file. Some data are discarded (file metadata) and other are added (subfolders).
GPLv3 and/or MIT
add() options objectStuart Knightley, with contributions from: