Proč FileSaver saveAs nebude fungovat s JSZip?

0

Otázka

Poprvé vysílání, toto je celý kód (většina z toho co jsem našel na internetu a vylepšil některé věci sloužit svému účelu), ale konkrétně, moje chyba je na konci, kde jsem si.

Uncaught TypeError: Nepodařilo se spustit 'createObjectURL' na 'URL': Přetížení rozlišení se nezdařilo.

Když jsem jednoduše pomocí saveAs(img_url, "img.png"), možnost uložit do notebooku objeví. Ale já jsem si chyby, které jsem zmínil výše, když se snaží použít "obsahu". Mám filesaver a jszip ve scénáři, já prostě nedokážu najít žádný způsob, jak opravit chyby, které pak zastaví provádění, nic víc. Omlouvám se za chaotický kód, bych opravdu ocenil pomoc.

Hlavní část je ke spodní části, zbytek je tam jen pro případ, že by někdo vidět. Tady je url na blob pak plátno generátor, jen nevím, proč to nezachrání.

!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

Nejlepší odpověď

1

zip.gzip.generateAsync() vrátí Slib. Tento Slib bude řešit s Blob, někdy později, ale je to Slib, není Blob.
Takže je třeba vyčkat na řešení tohoto Slíbit, že přístup generované Blob.

Můžete buď označit své funkce jako async a pak použít await klíčové slovo:

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

Nebo zabalit saveAs část zpětného volání předán Slib je .then():

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

Nyní, ať už si vyberete, váš zip soubor bude skutečně prázdný. Můžete přidat obsah, aby to pouze v zpětné volání setTimeout, což znamená, že tento obsah bude přidán pouze poté, co jste vytvořit soubor zip, což je příliš pozdě.
A tak odstranit setTimeout( část, která se zdá zbytečné a provést jeho zpětné volání je obsah přímo.

2021-11-21 23:32:28

Jsem použil setTimeout přidat zpoždění, když vizuálně vidět to změnit přes náhodné barvy na HTML stránce. Zkusím to, i když, jak přijít na zip by byla prázdná? Ale já bych předpokládat, že od té doby jsem inicializovat zip jakmile kliknete na tlačítko, pak ve smyčce jsem přidávání souborů do zip složky?
absolutenoob

Wow, to fungovalo, děkuji moc. Pokud můžeš, mohl bys vysvětlit, proč konkrétně to byl ten problém?
absolutenoob

Problém způsobuje "Uncaught TypeError: Nepodařilo se spustit 'createObjectURL' na 'URL': Přetížení rozlišení se nezdařilo.", bylo to, že jste složili Slib objekt místo Blob. Pro prázdné zip je to proto, setTimeout(fn) bude zpoždění fn o nějaký čas později (i když časový limit je 0). Takže když to zpětné volání fn říká, řádky níže vám již byly provedeny. A protože v řádcích níže můžete udělat, dokončit soubor zip, tento zip soubor je vytvořen dříve, než jste přidali soubor, jsem.e je prázdný.
Kaiido

aha, takže setTimeout(fn) tlačí fn vykonat poslední? Zajímavé, tak jak bych to mohl udělat pro smyčce, který má zpoždění mezi každé iteraci, ale také ne odložit volání do konce?
absolutenoob

Použití Sliby, můžete se podívat na stackoverflow.com/questions/14220321/...
Kaiido

V jiných jazycích

Tato stránka je v jiných jazycích

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