Pourquoi FileSaver saveAs ne fonctionne pas avec un JSZip?

0

La question

Premier temps à poster, c'est l'ensemble du code (la majorité de ce que j'ai trouvé en ligne et modifié certaines choses pour servir mon but), mais, plus précisément, mon erreur est vers la fin où je reçois.

Uncaught TypeError: Échec de l'exécution de 'createObjectURL' sur 'URL': résolution de Surcharge a échoué.

Lorsque j'utilise simplement saveAs(img_url, "img.png"), la possibilité de sauvegarder à l'ordinateur portable s'affiche. Mais je reçois le message d'erreur je l'ai mentionné ci-dessus lors de l'utilisation de "contenu". J'ai filesaver et jszip dans le script, je n'arrive pas à trouver de toute façon de corriger l'erreur, puis qui s'arrête l'exécution de quelque chose de plus. Désolé pour le code désordre, vraiment heureux d'aider.

La partie principale est vers le bas, le reste est là juste au cas où quelqu'un voudrait voir. Theres l'url à goutte puis le canevas générateur, je ne sais pas pourquoi il ne sera pas sauvegardé.

!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

La meilleure réponse

1

zip.gzip.generateAsync() renvoie une Promesse. Cette Promesse va résoudre avec un Blob, quelques temps plus tard, mais c'est une Promesse, pas une Goutte.
Si vous avez besoin d'attendre la résolution de cette Promesse pour accéder à l'généré Blob.

Vous pouvez soit la marque de votre fonction en tant que async et puis utiliser le await mot-clé:

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

Ou enveloppez la saveAs partie dans un callback passé à la Promesse de .then():

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

Maintenant, tout ce que vous choisissez, votre fichier zip sera effectivement vide. Vous ajoutez du contenu uniquement dans le rappel de setTimeout, ce qui signifie que ce contenu sera ajouté seulement après que vous avez créer le fichier zip, ce qui est trop tard.
Donc, supprimer le setTimeout( la partie qui semble inutile et l'exécution de son rappel du contenu directement.

2021-11-21 23:32:28

J'avais utilisé le setTimeout pour ajouter un délai lors de l'observer visuellement c'changement grâce à des couleurs aléatoires sur la page HTML. Je vais essayer, bien que comment se fait le zip seraient vides? Mais je suppose que depuis que j'ai initialiser le zip dès que le bouton est cliqué, puis à l'intérieur de la boucle, je suis en ajoutant des fichiers zip le dossier?
absolutenoob

Wow, cela a fonctionné, merci beaucoup. Si vous pouviez, vous pourriez peut-être expliquer pourquoi précisément qui était la question?
absolutenoob

Le problème causant l' "Uncaught TypeError: Échec de l'exécution de 'createObjectURL' sur 'URL': résolution de Surcharge a échoué.", c'est que vous avez passé une Promesse objet au lieu d'une Goutte. Pour le vide zip c'est parce que setTimeout(fn) retarder fn quelques temps plus tard (même si le délai d'attente est 0). Alors, quand ce rappel à l' fn est appelé, les lignes ci-dessous ont déjà été exécutés. Et puisque dans les lignes ci-dessous vous n'finaliser le fichier zip, le fichier zip est créé avant d'ajouter n'importe quel fichier, je l'.e elle est vide.
Kaiido

oh, si setTimeout(fn) pousse fn pour exécuter dernier? C'est intéressant, alors comment pourrais-je faire une boucle a un délai entre chaque itération, mais aussi de ne pas reporter les appels à la fin?
absolutenoob

Utiliser des Promesses, vous pouvez jeter un oeil à stackoverflow.com/questions/14220321/...
Kaiido

Dans d'autres langues

Cette page est dans d'autres langues

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