简体   繁体   English

为什么 FileSaver saveAs 不能与 JSZip 一起使用?

[英]Why FileSaver saveAs won't work with a JSZip?

First time posting, this is the whole code (majority of it I found online and tweaked some things to serve my purpose), but more specifically, my error is towards the end where I get.第一次发布,这是整个代码(我在网上找到了大部分代码并调整了一些东西以达到我的目的),但更具体地说,我的错误接近我得到的最后。

Uncaught TypeError: Failed to execute 'createObjectURL' on 'URL': Overload resolution failed.未捕获的类型错误:无法在“URL”上执行“createObjectURL”:重载解析失败。

When I simply use saveAs(img_url, "img.png"), the option to save to laptop pops up.当我简单地使用 saveAs(img_url, "img.png") 时,会弹出保存到笔记本电脑的选项。 But I get the error I mentioned above when trying to use "content".但是我在尝试使用“内容”时遇到了上面提到的错误。 I have filesaver and jszip in the script, I just can't seem to find any way to fix the error, which then stops executing anything more.我在脚本中有文件保护程序和 jszip,我似乎找不到任何方法来修复错误,然后停止执行更多操作。 Sorry for messy code, would really appreciate help.抱歉代码混乱,非常感谢帮助。

Main part is towards the bottom, the rest is there just incase someone might want to see.主要部分在底部,rest 在那里,以防有人想看。 Theres the url to blob then the canvas generator, I just don't know why it won't save.有 url 到 blob 然后是 canvas 发生器,我只是不知道为什么它不会保存。

!function() {
    function dataURLtoBlob(dataURL, type) {
      var binary = atob(dataURL.split(',')[1]),
          length = binary.length,
          binaryArray = new Uint8Array(length);
      for (var i = 0; i < length; i++) {
        binaryArray[i] = binary.charCodeAt(i);
      }
      return new Blob([binaryArray], {type: type});
    }

    var SolidImage = function() {
      var canvas = document.createElement('canvas'),
          ctx = canvas.getContext('2d');
      this.img = new Image();
      this.make = function(color) {
        canvas.width = 500;
        canvas.height = 500;
        
        ctx.fillStyle = color;
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = "#FFFFFF";
        ctx.textAlign = "center";
        ctx.font = "bold 50px Courier New";
        ctx.fillText(color.substring(3), 250, 250);
        var dataURL = canvas.toDataURL('image/png')
        this.img.src = dataURL;
        if (this.blobURL) URL.revokeObjectURL(this.blobURL);
        this.blob = dataURLtoBlob(dataURL, 'image/png');
        this.blobURL = URL.createObjectURL(this.blob);
      }
    };
    
    var solidImage = new SolidImage(),
        button = document.getElementById('make'),
        result = document.getElementById('result'),
        link = document.createElement('a');
    
    link.setAttribute('target', '_blank');
    result.appendChild(solidImage.img);
    result.insertAdjacentHTML('beforeend', 'Save this image or<br>');
    result.appendChild(link);
    solidImage.img.width = 600;
  
    
    button.addEventListener('click', function(){
        var zip = new JSZip();
        console.log("after zip");
        //var img = zip.folder("rdm_imgs");
        //////////////////////////////////
        for (var i = 0; i < 1; i++) {
            setTimeout(function() {
        var rgb_r = Math.floor(Math.random() * (256+1)),
            rgb_g = Math.floor(Math.random() * (256+1)),
            rgb_b = Math.floor(Math.random() * (256+1)),
            random_color = "rgb(" + rgb_r + ", " + rgb_b + ", " + rgb_g + ")";
      var filename = random_color.replace(/\s/g, "") + '.png';
      solidImage.make(random_color);
      link.innerHTML = 'Download content ' + filename;
      var img_url = solidImage.blob;
      //console.log(img_url.replace(/^data:image\/(png|jpg);base64,/, ""));
      console.log(img_url);
      //link.setAttribute('href', img_url);
      //link.setAttribute('download', filename);
      result.className = 'generated';

      zip.file(filename, img_url);
            },i * 500)}
        console.log("after loop");
        var content = zip.generateAsync({type:"blob"});
        console.log("after zip generate");
        saveAs(content, "imgs.zip");
        console.log("after saveAs");
        //link.innerHTML = 'Download Contents.zip';
        //var img_url = solidImage.blobURL;
        //link.setAttribute('href', content);
        //link.setAttribute('download', "content.zip");
    });
  }();

zip.gzip.generateAsync() returns a Promise . zip.gzip.generateAsync()返回Promise This Promise will resolve with a Blob, some times later, but it's a Promise, not a Blob.这个 Promise 将在一段时间后用 Blob 解析,但它是 Promise,而不是 Blob。
So you need to await the resolution of this Promise to access the generated Blob.所以需要等待这个 Promise 的解析才能访问生成的 Blob。

You can either mark your function as async and then use the await keyword:您可以将 function 标记为async ,然后使用await关键字:

button.addEventListener('click', async function(){
  // ...
  var content = await zip.generateAsync({type:"blob"});

Or wrap the saveAs part in a callback passed to the Promise's .then() :或者将 saveAs 部分包装在传递给 Promise 的.then()的回调中:

zip.generateAsync({type:"blob"}).then(function(content) {
  console.log("after zip generate");
  saveAs(content, "imgs.zip");
})

Now, whatever you choose, your zip file will actually be empty.现在,无论您选择什么,您的 zip 文件实际上都是空的。 You add content to it only in the callback of setTimeout , meaning that this content will be added only after you did create the zip file, which is too late.您仅在setTimeout的回调中添加内容,这意味着只有在您创建 zip 文件后才会添加此内容,这为时已晚。
So remove the setTimeout( part which seems useless and execute its callback's content directly.所以删除setTimeout(似乎没用的部分并直接执行其回调的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM