JSZip

repository·main·Indexed 27 days ago

https://github.com/stuk/jszip

A lightweight JavaScript library for creating, reading, and editing .zip files. JSZip allows developers to programmatically build zip archives, manage folder structures, and export content as blobs, base64 strings, Node.js buffers, and other formats. Version 3.10.1.

Tokens
13.8K
Snippets
45
Records
78
Agent score
94%

What's inside jszip

  1. Download a ZIP file in the browser using Blob URL / FileSaver

    main

    For modern browsers, the most efficient way to provide a ZIP file to a user is to generate the ZIP as a blob and use the saveAs function from FileSaver.js. This utilizes the native saveAs API in Chrome/IE10+ or a Blob URL in Firefox.

    zip.generateAsync({type:"blob"})
    .then(function (blob) {
        saveAs(blob, "hello.zip");
    });
  2. Migrate from JSZip 1.x to 2.x

    main

    Significant changes occurred in the transition from 1.x to 2.x:

    • Renaming: JSZipBase64 was renamed to JSZip.base64.
    • Data Access: The .data attribute was removed. Use getters like .asText() or .asBinary() instead.
    • Compression/Decompression: Use the compressInputType and uncompressInputType attributes to specify input types.
    // before
    zip.file("test.txt").data;
    zip.files["test.txt"].data;
    zip.file("image.png").data;
    zip.files["image.png"].data;
    
    // after
    zip.file("test.txt").asText();
    zip.files["test.txt"].asText();
    zip.file("image.png").asBinary();
    zip.files["image.png"].asBinary();
  3. Use streamFiles to reduce memory usage

    main

    By default, options.streamFiles is false. JSZip holds the processed file in memory to ensure the CRC32 and size are placed correctly at the start of the entry, making the zip compatible with all programs.

    If you set options.streamFiles: true, JSZip will stream the files and use data descriptors at the end of the entry. This uses significantly less memory but may result in zip files that some programs cannot read.

    zip.generateAsync({
        type: 'uint8array',
        streamFiles: true
    });
  4. Read a remote ZIP file in Node.js

    main

    When downloading a ZIP file in Node.js to use with JSZip, it is critical to ensure the data is treated as binary.

    • If using the built-in http module: Do not set an encoding on the response, or set it to null. Collect chunks into an array and use Buffer.concat(data) to create a single Buffer.
    • If using the request library: Set encoding: null in the request options to ensure the body is returned as a Buffer.
    // Example using the 'request' library
    "use strict";
    
    var request = require('request');
    var JSZip = require("jszip");
    
    request({
      method : "GET",
      url : "http://localhost/.../file.zip",
      encoding: null // <- this one is important!
    }, function (error, response, body) {
      if(error ||  response.statusCode !== 200) {
        // handle error
        return;
      }
      JSZip.loadAsync(body).then(function (zip) {
        return zip.file("content.txt").async("string");
      }).then(function (text) {
        console.log(text);
      });
    });
  5. Add files to a ZIP in Node.js

    main

    You can add files to a JSZip instance in Node.js using several methods:

    1. Using a Buffer: Pass the file data directly to zip.file(name, data).
    2. Using a Promise: Pass a promise that resolves to the file data to zip.file(name, promise).
    3. Using a Stream: Pass a readable stream directly to zip.file(name, stream).
    // read a file and add it to a zip
    fs.readFile("picture.png", function(err, data) {
        if (err) throw err;
        var zip = new JSZip();
        zip.file("picture.png", data);
    });
    
    // or using a promise
    var contentPromise = new JSZip.external.Promise(function (resolve, reject) {
        fs.readFile("picture.png", function(err, data) {
            if (err) {
                reject(err);
            } else {
                resolve(data);
            }
        });
    });
    zip.file("picture.png", contentPromise);
    
    // read a file as a stream and add it to a zip
    var stream = fs.createReadStream("picture.png");
    zip.file("picture.png", stream);
  6. Read a ZIP file in the browser via AJAX

    main

    To load a ZIP file from a remote URL in the browser, it is recommended to use JSZipUtils.getBinaryContent from the jszip-utils library. This handles the complexities of binary data retrieval across different browsers.

    If you are implementing a custom solution using XMLHttpRequest:

    • For modern browsers (Firefox/Chrome/Opera), set the mime type: xhr.overrideMimeType("text/plain; charset=x-user-defined");.
    • For browsers supporting XHR2, set the responseType to "arraybuffer" to receive an ArrayBuffer directly.
    JSZipUtils.getBinaryContent('path/to/content.zip', function(err, data) {
        if(err) {
            throw err; // or handle err
        }
    
        JSZip.loadAsync(data).then(function () {
            // ...
        });
    });
  7. Download a ZIP file in the browser using Downloadify

    main

    If you use Downloadify (which uses a Flash SWF), you can pass a ZIP file by generating it as base64 and setting the dataType option to 'base64'.

    zip = new JSZip();
    zip.file("Hello.", "hello.txt");
    
    zip.generateAsync({type:"base64"}).then(function (base64) {
        Downloadify.create('downloadify',{
        ...
        data: function(){
            return base64;
        },
        ...
        dataType: 'base64'
        });
    });
  8. Write a ZIP file to disk in Node.js using Streams

    main

    In a Node.js environment, you can use generateNodeStream with {type: 'nodebuffer', streamFiles: true} to create a readable stream. This stream can be piped directly into a filesystem writable stream (e.g., fs.createWriteStream).

    var fs = require("fs");
    var JSZip = require("jszip");
    
    var zip = new JSZip();
    // zip.file("file", content);
    // ... and other manipulations
    
    zip
    .generateNodeStream({type:'nodebuffer',streamFiles:true})
    .pipe(fs.createWriteStream('out.zip'))
    .on('finish', function () {
        // JSZip generates a readable stream with a "end" event,
        // but is piped here in a writable stream which emits a "finish" event.
        console.log("out.zip written.");
    });
  9. Migrate from JSZip 2.2.2 to 2.3.0

    main

    In version 2.3.0, several attributes were moved from ZipObject#options directly onto the ZipObject itself.

    Changes:

    • zip.file("name").options.date $\rightarrow$ zip.file("name").date
    • zip.file("name").options.dir $\rightarrow$ zip.file("name").dir
    • zip.file("name").options.base64 and zip.file("name").options.binary are deprecated.

    Also Deprecated:

    • JSZip.base64
    • JSZip.prototype.crc32
    • JSZip.prototype.utf8decode and JSZip.prototype.utf8encode
    • JSZip.utils
    // deprecated
    zip.file("test.txt").options.date
    zip.file("test.txt").options.dir
    // new API
    zip.file("test.txt").date
    zip.file("test.txt").dir
  10. Download a ZIP file in the browser using Data URI

    main

    In older browsers that support data URI, you can generate the ZIP as a base64 string and assign it to location.href.

    Warning: This method has inconsistent filename support across browsers (e.g., Firefox may append .part extensions, and Safari may name the file Unknown).

    zip.generateAsync({type:"base64"}).then(function (base64) {
        location.href="data:application/zip;base64," + base64;
    });
  11. Handle performance and memory issues in JSZip

    main

    JSZip holds the full result in memory when using async() and generateAsync(). To avoid browser crashes or memory exhaustion with large files, follow these best practices:

    • Use Typed Arrays: Always prefer Uint8Array, ArrayBuffer, or Blob over strings.
      • When generating a zip, use type: "uint8array" (or blob, arraybuffer, nodebuffer).
      • When loading files via AJAX/XHR, request an ArrayBuffer instead of a string.
    • Avoid Older Browsers: Do not use Internet Explorer 9 or below, as they lack typed array support and will suffer significant performance penalties during compression.
    • Stream Large Files: If the result is too large for memory and you cannot use nodeStream or generateNodeStream, use the underlying StreamHelper to process data chunk by chunk, utilizing pause() and resume() to manage backpressure.