为什么FileSaver saveAs不会的工作与JSZip?

0

的问题

第一时间发布,这是整个代码(大多数它的我在网上找到和调整了一些事情要成为我的目的),但是更具体地说,我的错误是朝着结束在那里我得到的。

未捕获的类型错误:未能执行'createObjectURL'on'URL:过载决议失败。

当我简单地使用saveAs(img_url,"img。png"),选择保存到笔记本电脑的出现。 但是我得到的错误我上面提到的当试图使用"内容"。 我filesaver和jszip在脚本,我只是似乎无法找到任何方式来修正这个错误,其后停止执行任何东西更多。 对不起混乱的代码,将非常有帮助。

主要部分是朝底,其余的是没有只是以防有人可能会想看到的。 有url blob然后将画布的发电机,我只是不知道为什么它不会保存。

!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");
    });
  }();
blob filesaver.js javascript jszip
2021-11-21 21:48:48
1

最好的答案

1

zip.gzip.generateAsync() 返回一个 承诺. 这一承诺将解决与Blob,一些时间较晚,但它是一个承诺,不Blob。
所以你需要等待解决这一承诺的访问所产生的Blob。

你可以标志着你作为功能 async 然后再用 await 关键字:

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

或者包裹saveAs部分在回调通过的承诺的 .then():

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

现在,无论你选择什么,你的拉链文件将实际上是空的。 添加内容,它只是在回的 setTimeout,意味着,这些内容将加入后,才你有没有创建的拉链文件,该文件是太晚。
所以除去 setTimeout( 部分这似乎无用和执行其回调的内容。

2021-11-21 23:32:28

我不得不使用的目添加一个延迟的时候视地看到这一改变通过随机的颜色上的HTML网页。 我会尝试的是,虽然怎么来的邮政编将是空的? 但我们认为,由于我的初始化zip尽快按钮被点击,则在环路的我加入文件压缩文件夹?
absolutenoob

哇,这一工作,我非常感谢你。 如果你可以,你可以解释为什么具体地说这是问题吗?
absolutenoob

这个问题造成"未捕获的类型错误:未能执行'createObjectURL'on'URL:过载决议失败了。"那是你传递一个承诺对象,而不是一个Blob。 对于空拉链那是因为 setTimeout(fn) 会延迟 fn 一段时间后(即使超时 0). 所以当这个回调 fn 是所谓的,下面将已经执行。 而且,由于在该行以下做最后确定的邮政编文件,这个压缩文件是在创建之前加入任何文件,i。e这是空的。
Kaiido

哦,所以目(fn)推动fn执行去? 有趣的,那么我怎么会让一个循环,具有延迟之间每次迭代,但也不能推迟的话结束了吗?
absolutenoob

使用的承诺,你可以看看 stackoverflow.com/questions/14220321/...
Kaiido

其他语言

此页面有其他语言版本

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................