Dlaczego сохранители plików nie będą działać z JSZip?

0

Pytanie

Przy pierwszym składaniu to cały kod (większą jego część znalazłem w Internecie i coś zmienił, aby osiągnąć swój cel), ale bardziej konkretnie, mój błąd bliżej końca, gdzie dostaję.

Неперехваченная błąd typu: Nie udało się wykonać "createObjectURL" na "URL": Nie udało się rozwiązać przeciążenie.

Kiedy ja po prostu używam SaveAs(img_url, "img.png"), pojawia się możliwość zapisania w laptopie. Ale pojawia się błąd, o którym wspomniałem wyżej, podczas próby użycia "treści". U mnie w skrypcie jest файлосберегатель i jszip, ja po prostu nie mogę znaleźć sposób, aby naprawić błąd, który następnie przerywa wykonanie czegoś jeszcze. Przepraszam za chaotyczny kod, byłbym bardzo wdzięczny za pomoc.

Główna część znajduje się na dole, reszta jest tam, po prostu na wypadek, gdyby ktoś chciał zobaczyć. Jest adres URL dla dużego obiektu binarnego, a następnie generator płótna, ja po prostu nie wiem, dlaczego on się nie utrzyma.

!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

Najlepsza odpowiedź

1

zip.gzip.generateAsync() zwraca Obietnica. To jest Obietnica zostanie rozwiązany za pomocą Dużego obiektu binarnego, kilka razy później, ale to jest Obietnica, a nie dużego obiektu binarnego.
Więc trzeba czekać na pozwolenia tej obietnicy, aby uzyskać dostęp do сгенерированному dużej двоичному obiektu.

Możesz albo oznaczyć swoją funkcję jak async a następnie użyj await słowo kluczowe:

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

Lub owinąć część zapisu w oddzwanianie, przekazany Obietnicy .then():

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

Teraz, cokolwiek wybierzesz, twój plik zip faktycznie będzie puste. Można dodać do niego zawartość tylko przy odwrotnym połączeniu setTimeoutto oznacza, że ta zawartość zostanie dodana dopiero po utworzeniu plik zip, a to za późno.
Więc usunąć setTimeout( część, która wydaje się bezużyteczne, i wykonuje zawartość oddzwonienia bezpośrednio.

2021-11-21 23:32:28

Użyłem setTimeout, aby dodać opóźnienie, gdy wizualnie widziałem, jak zmienia się za pomocą przypadkowych kolorów na stronie HTML. Spróbuję to zrobić, chociaż dlaczego piorun będzie pusty? Ale ja bym zasugerował, że skoro ja инициализирую zip, jak tylko wciśnięty jest przycisk, a następnie w cyklu dodaję pliki do folderu zip?
absolutenoob

Wow, udało się, dziękuję bardzo. Jeśli można, nie można wyjaśnić, dlaczego właśnie w tym był problem?
absolutenoob

Problem powodujący "Nieprzechwycony błąd typu: Nie udało się wykonać "createObjectURL" na "URL": Nie udało się rozwiązać przeciążenie". było to, że przekazali obiekt obietnice zamiast dużego obiektu binarnego. Pusty zamek to dlatego, że setTimeout(fn) będzie opóźniać fn w jakiś czas później (nawet jeśli czas oczekiwania 0). Dlatego, kiedy ten oddzwanianie fn wywoływana, wiersze poniżej już są spełnione. A ponieważ w wierszach poniżej należy ukończyć pracę z zip-plik, to plik zip jest tworzony do tego, jak dodaje się do niego jakiś plik, to jest on pusty.
Kaiido

o, to znaczy, setTimeout(fn) popycha fn do wykonania ostatni? Zastanawiam się wtedy jak bym zrobił pętlę for, która ma opóźnienie między każdej iteracji, ale też nie stanowi połączenia do końca?
absolutenoob

Użyj obietnice, można spojrzeć na stackoverflow.com/questions/14220321/...
Kaiido

W innych językach

Ta strona jest w innych językach

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