`

Create, read and edit .zip files with Javascript

 
阅读更多

JSZip


Create, read and edit .zip files with Javascript

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
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 / 10

While JSZip should work everywhere, the tricky part is to give the zip file to the user.

Browser support for data URI scheme with zip

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?)

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 (and working in every browsers) 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'
});

Other solution-ish: Blob URL

With some recent browsers come a new way to download Blobs (a zip file for example) : blob urls. The download attribute on <a> allows you to give the name of the file. Blob urls start to be widely supported but this attribute is currently only supported in Chrome and Firefox (>= 20). See the example.

var blob = zip.generate({type:"blob"});
myLink.href = window.URL.createObjectURL(blob);
myLink.download = "myFile.zip";

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.

Reading a zip file from an ajax call

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.

An other solution is to use a modern browser (supporting xhr2) : setting xhr.type = 'arraybuffer'; will do the trick, JSZip supports ArrayBuffers. Please see the example.

Reading a local zip file (File API)

JSZip supports (if available in the browser) the File API : reading a local zip file is simple : new JSZip(readerEvent.target.result);. Please see the complete example for more details.

Documentation

new JSZip()

Description :
The default constructor.
Returns :
A new JSZip.

new JSZip(data [,options])

Description :
Create a new JSZip file and load an existing zip file. See the documentation of load() for more details and this for the limitations.
Parameters :
data (same types as load()) the content of the zip file to load.
options (Object) options to pass to the load() method..
Returns :
A new JSZip.
new JSZip(zipDataFromXHR, {base64:false});
// same as
var zip = new JSZip();
zip.load(zipDataFromXHR, {base64:false});

file(name)

Description :
Get a file with the specified name.
Parameters :
name (String) the name of the file.
Returns :
The file if any, null otherwise. The file has the following structure :
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"
zip.file("amount.txt").asArrayBuffer() // an ArrayBuffer containing €15
zip.file("amount.txt").asUint8Array() // an Uint8Array containing €15

file(regex)

Description :
Search a file in the current folder and subfolders with a regular expression. The regex is tested against the relative filename.
Parameters :
regex (RegExp) the regex to use.
Returns :
An array of matching files (an empty array if none matched).
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}

file(name, data [,options])

Description :
Add a file to the zip file.
Parameters :
name (String) the name of the file.
data (String/ArrayBuffer/Uint8Array) 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. If the data is an ArrayBuffer or an Uint8Array, this will be set to true.
  • date (Date) use it to specify the last modification date. If not set the current date is used.
  • optimizedBinaryString (boolean), default false. Set it to true if (and only if) the input has already been prepared with a 0xFF mask.
Returns :
A JSZip object, for chaining.
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

folder(name)

Description :
Add a directory to the zip file.
Parameters :
name (String) the name of the directory.
Returns :
a new JSZip (for chaining), with the new folder as root.
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

folder(regex)

Description :
Search a subdirectory.
Search a subdirectory in the current directory with a regular expression. The regex is tested against the relative path.
Parameters :
regex (RegExp) the regex to use.
Returns :
An array of matching folders (an empty array if none matched).
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

remove(name)

Delete a file or folder.

Description :
Delete a file or folder (recursively).
Parameters :
name (String) the name of the file/folder to delete.
Returns :
The current JSZip object.
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

generate(options)

Description :
Generates the complete zip file.
Parameters :
options (Object) the options to generate the zip file :
  • base64 (boolean) deprecated, use "type" instead. 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.
  • type (String) the type of zip to return. The possible values are :
    • base64 (default) : the result will be a string, the binary in a base64 form.
    • string : the result will be a string in "binary" form, 1 byte per char.
    • uint8array : the result will be a Uint8Array containing the zip. This requires a compatible browser.
    • arraybuffer : the result will be a ArrayBuffer containing the zip. This requires a compatible browser.
    • blob : the result will be a Blob containing the zip. This requires a compatible browser.
Returns :
The generated zip file.
HTML5 note : when using type = "uint8array", "arraybuffer" or "blob", be sure to check if the browser supports it (you can use JSZip.support). This method will throw an exception otherwise.
content = zip.generate();
location.href="data:application/zip;base64,"+content;
content = zip.generate({type:"string"});
for (var c = 0; c < content.length; c++) {
    console.log(content.charCodeAt(c));
    // do other things
}

load(data, options)

Description :
Read an existing zip and merge the data in the current JSZip object. The implementation is in jszip-load.js, don't forget to include it. This technique has some limitations, see below.
Parameters :
data (String/ArrayBuffer/Uint8Array) the zip file
options (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.
Returns :
The current JSZip object.
var zip = new JSZip();
zip.load(zipDataFromXHR);
Zip features supported by this method
  • Compression (DEFLATE with jszip-deflate.js)
  • zip with data descriptor
  • ZIP64
  • UTF8 in file name, UTF8 in file content
Zip features not (yet) supported
  • password protected zip
  • multi-volume zip

filter(predicate)

Description :
Filter nested files/folders with the specified function.
Parameters :
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:{...}}.
  • Return true if the file should be included, false otherwise.
Returns :
An array of matching elements.
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;
});

JSZip.support

If the browser supports them, JSZip can take advantage of some new features : ArrayBuffer, Blob, Uint8Array. To know if JSZip can use them, you can check the JSZip.support object. It contains the following properties :

  • arraybuffer : true if JSZip can read and generate ArrayBuffer, false otherwise.
  • uint8array : true if JSZip can read and generate Uint8Array, false otherwise.
  • blob : true if JSZip can read and generate Blob, false otherwise.

Loading zip files, limitations

All the features of zip files are not supported. Classic zip files will work but encrypted zip, multi-volume, etc are not supported and the load() method will throw an Error.

ZIP64 files can be loaded, but only if the zip file is not "too big". ZIP64 uses 64bits integers but Javascript represents all numbers as 64-bit double precision IEEE 754 floating point numbers (see section 8.5). So, we have 53bits for integers and bitwise operations treat everything as 32bits. So if all the 64bits integers can fit into 32 bits integers, everything will be fine. If it's not the case, you will have other problems anyway (see next limitation).

An other 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.

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).

Changelog

1.0.1 2013-03-04

  • Fixed an issue when generating a compressed zip file with empty files or folders, see #33.
  • With bad data (null or undefined), asText/asBinary/asUint8Array/asArrayBuffer methods now return an empty string, see #36.

1.0.0 2013-02-14

First release after a long period without version.

分享到:
评论

相关推荐

    FXRuby.Create.Lean.and.Mean.GUIs.with.Ruby

    FXRuby.Create.Lean.and.Mean.GUIs.with.Ruby

    Android application to create and edit Pdf files.zip

    "Android application to create and edit Pdf files.zip"是一个开源项目,其核心是PDFCreator-master,这个项目提供了一套完整的解决方案,帮助开发者实现PDF文件的生成与编辑功能。 PDF(Portable Document ...

    FXRuby.Create.Lean.and.Mean.GUIs.with.Ruby.rar

    FXRuby.Create.Lean.and.Mean.GUIs.with.Ruby.rar

    java生成.zip包,解压缩.zip

    在这个例子中,`createZip`方法接受一个`.zip`文件路径和一个文件名列表,然后将这些文件添加到`.zip`包中。 接下来是解压缩`.zip`文件的过程,这通常使用`ZipInputStream`完成。这个类可以从`.zip`文件中读取条目...

    The Definitive Guide to AdonisJs_Building Node.js App with JavaScript-2018

    We’ll design a shopping cart in React and we’ll package static files with a custom build chain. Finally, we’ll learn how to deploy the application to a virtual server, and install custom domains ...

    create_ap-master.zip

    为了配置树莓派无线热点(做无线路由器),利用该项目来开启树莓派无线网咯适配器的AP功能。

    59--[Create a Pong Game].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码

    59--[Create a Pong Game].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码59--[Create a Pong Game].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码59--[Create a Pong Game].zip源码scratch2.0 ...

    create_ap.zip

    利用树莓派搭建路由器,实现网络数据的转发,由于搭建环境及步骤复杂,所以将其步骤及环境用代码及脚本封装,很大程度上简化工作量以及提高成功率

    sketch-batch-create-symbols, 用于将选定图层转换为单个符号的插件插件.zip

    sketch-batch-create-symbols, 用于将选定图层转换为单个符号的插件插件 概述在草图中,当你有一些需要转换为符号的图层时,必须一个选择它们并使用'转换为符号'函数。 多个选择将合并为一个符号。这里插入将为当前...

    Server Side development with Node.js and Koa.js

    This book is the ideal introduction for JavaScript developers who want to create scalable server side applications using Node.js and Koa.js. The book shows you how Koa can be used to start projects ...

    Create ZIP Files in JavaScript

    在JavaScript中创建ZIP文件是一项常见的任务,特别是在前端开发中,可能需要将一组文件或数据打包成ZIP格式供用户下载。本文将深入探讨如何利用JavaScript实现这一功能,主要基于`jszip.js`库来讲解。 首先,`jszip...

    python批量创建文件夹.zip

    首先,我们需要导入所需的模块: python复制代码运行import osimport shutil 接下来,我们定义一个函数来创建文件夹并将其添加到.zip文件中: python复制代码运行def create_and_zip_folders(folder_names, zip_name...

    zip4j--Java操作zip压缩文件接口

    Read/Write password protected Zip files (读写有密码保护的Zip文件) Supports AES 128/256 Encryption (支持AES 128/256算法加密) Supports Standard Zip Encryption (支持标准Zip算法加密) Supports Zip...

    Flask and Jquary.zip

    本资源包"Flask and Jquary.zip"提供了一个基于Python Flask和jQuery AJAX实现CRUD(创建、读取、更新、删除)操作的完整示例,旨在帮助开发者理解这两者如何协同工作,提升Web应用的用户体验。 **Flask框架简介** ...

    zip4j-1.3.2.zip

    Create, Add, Extract, Update, Remove files from a Zip file 针对ZIP压缩文件创建、添加、抽出、更新和移除文件 Read/Write password protected Zip files (读写有密码保护的Zip文件) Supports AES 128/256 ...

    Programming Excel With Vba And .net.chm

    Read and Write Files Section 3.7. Check Results Section 3.8. Find Truth Section 3.9. Compare Bits Section 3.10. Run Other Applications Section 3.11. Control the Compiler Section 3.12. Not...

    Data Visualization with Python and JavaScript.azw3

    Learn how to turn raw data into rich, interactive web visualizations with the powerful combination of Python and JavaScript. With this hands-on guide, author Kyran Dale teaches you how build a basic ...

Global site tag (gtag.js) - Google Analytics