Conversion image links to base64 and adding them to zip file using JSZip

谁说我不能喝 提交于 2019-12-06 10:25:18

The problem is that the zipping process starts before the image(s) has loaded. The process of adding the files to the zip archive must start from inside the onload handler.

However, there are several things to consider here as well:

  • If you want to add images as-is to the archive there is no need to go via canvas
  • Converting to and from Data-URIs are very expensive and memory costly. JSZip uses pako_delate internally which works much better with typed array views (Uint8Array)

I would propose the following approach instead:

  • Create zip object at beginning of app (or before starting loading files)
  • Load each file using XMLHttpRequests and request content as ArrayBuffer. This will allow you to load any kind of file directly to binary format which will increase performance and resources.
  • Add files as they come
  • When all URLs are passed call the generateAsync() method and you should be done.

Example

This is not a production-ready example and isn't intended to be, but it will show the main steps. Adjust to your scenario, add error handling and sanity checks where appropriate.

// create archive before loading process begin
var zip = new JSZip();

// image list to add:
var images = [
      "//i.imgur.com/qDFCWVnb.jpg",
      "//i.imgur.com/VBvzEq1b.jpg",
      "//i.imgur.com/ZWtUEuLb.jpg"
    ],
    index = 0;  // for loader

// function to load a single image as arraybuffer using XMLHttpRequests
// it will assume cross-origin usage is allowed
function loadAsArrayBuffer(url, callback) {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", url);
  xhr.responseType = "arraybuffer";
  xhr.onerror = function() {/* handle errors*/};
  xhr.onload = function() {
    if (xhr.status === 200) {callback(xhr.response, url)}
    else {/* handle errors*/}
  };
  xhr.send();
}

// loading process. Here it will load one and one image.
// You can modify it to load several at once but some browsers put
// a cap on how many XHR connections can be open at the same time..
(function load() {
  if (index < images.length) {
    loadAsArrayBuffer(images[index++], function(buffer, url) {
      var filename = getFilename(url);
      zip.file(filename, buffer); // image has loaded, add it to archive
      load();                     // load next image
    })
  }
  else {                          // done! present archive somehow
    zip.generateAsync({type:"blob"}).then(function(content) {
      // save out
      lnk.href = (URL || webkitURL).createObjectURL(content);
      lnk.innerHTML = "Right-click + Save as to download zip file";
      lnk.download = "DemoZip.zip";
    });
  }
})();

// Just for this demo! keep separate array with filename or
// modify to allow for "filename-less" uris.
function getFilename(url) {
  return url.substr(url.lastIndexOf("/") + 1)
}
<script src="https://raw.githubusercontent.com/Stuk/jszip/master/dist/jszip.min.js"></script>
Loading external lib + images... hold on...
<br><a id=lnk></a>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!