Impossible d'exécuter 'atob' sur 'Fenêtre'

J'essaie d'enregistrer mon fichier HTML dans Chrome lorsque l'utilisateur appuie sur les ctrl + s , mais Chrome est bloqué.

(Je souhaite télécharger uniquement le code source de mon fichier HTML)

J'ai lu que cela se produit parce que mon fichier est supérieur à 1,99M ..

Dans la première tentative (avant que je sache le crash de Chrome):

 function download(filename, text) { var pom = document.createElement('a'); pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); pom.setAttribute('download', filename); pom.click(); } download('test.html', "<html>" + document.getElementsByTagName('html')[0].innerHTML + "</html>"); 

La deuxième tentative, après avoir lu sur le crash, j'ai utilisé blob :

 function dataURItoBlob(dataURI) { var byteString = atob(dataURI.split(',')[1]); var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0] var ab = new ArrayBuffer(byteString.length); var ia = new Uint8Array(ab); for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } var bb = new BlobBuilder(); bb.append(ab); return bb.getBlob(mimeString); } function download(dataURI) { var blob = dataURItoBlob(dataURI); var url = window.URL.createObjectURL(blob); window.location.assign(url); } download("<html>" + document.getElementsByTagName('html')[0].innerHTML + "</html>") 

Ici, j'ai eu l'erreur: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.

Je ne sais pas, mais j'ai lu que j'ai besoin d'encoder ma chaîne à base64: Comment pouvez-vous coder une chaîne vers Base64 en JavaScript?

Il y a une réponse de 148 votes. Je le collez dans mon code et je ne sais pas comment continuer.

Où dois-je l'appeler et comment? Puis-je mettre un nom sur mon fichier enregistré?

Je pense que je dois faire quelque chose comme:

 download(_utf8_decode("<html>" + document.getElementsByTagName('html')[0].innerHTML + "</html>")) 

BlobBuilder est obsolète, utilisez le constructeur Blob place:

 URL.createObjectURL(new Blob([/*whatever content*/] , {type:'text/plain'})); 

Cela renvoie une URL blob que vous pouvez utiliser dans le href une ancre. Vous pouvez également modifier l'attribut de download un ancre pour manipuler le nom du fichier:

 <a href="/*assign url here*/" id="link" download="whatever.txt">download me</a> 

Fiddled . Si je me souviens bien, il existe des restrictions arbitraires sur les téléchargements fiables non-utilisateurs; Donc, nous allons rester avec un clic de lien qui est considéré comme suffisamment initié par l'utilisateur 🙂

Mise à jour: il est en fait assez trivial de sauvegarder le document html actuel. Chaque fois que notre lien interactif est cliqué, nous allons mettre à jour son href avec un blob pertinent. Après l'exécution de l'événement déclenché par un clic, c'est l'URL de téléchargement qui sera téléchargée!

 $('#link').on('click', function(e){ this.href = URL.createObjectURL( new Blob([document.documentElement.outerHTML] , {type:'text/html'}) ); }); 

Frotter à nouveau .

Ici, j'ai eu l'erreur: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.

Parce que vous n'avez pas passé une chaîne codée base64. Regardez vos fonctions: à la fois download et dataURItoBlob s'attendre à une URI de données pour une raison quelconque; Cependant, vous transmetz une chaîne de balisage html simple à download dans votre exemple.

Non seulement HTML est invalide comme base64, vous appelez .split(',')[1] sur celui-ci qui produira undefined – et "undefined" n'est pas une chaîne codée base64 valide non plus.

Je ne sais pas, mais j'ai lu que je dois coder ma chaîne sur la base64

Cela n'a pas beaucoup de sens pour moi. Vous voulez l'encoder en quelque sorte, seulement pour le décoder alors?

Que dois-je appeler et comment?

Changez l'interface de votre fonction de download vers l'endroit où elle a reçu le filename du filename et les arguments du text .

Notez que BlobBuilder ne prend pas uniquement en charge l'ajout de chaînes entières (de sorte que vous n'avez pas besoin de créer ces objets ArrayBuffer ), mais est également obsolète en faveur du constructeur Blob .

Puis-je mettre un nom sur mon fichier enregistré?

Oui. N'utilisez pas le constructeur Blob , mais le constructeur File .

 function download(filename, text) { try { var file = new File([text], filename, {type:"text/plain"}); } catch(e) { // when File constructor is not supported file = new Blob([text], {type:"text/plain"}); } var url = window.URL.createObjectURL(file); … } download('test.html', "<html>" + document.documentElement.innerHTML + "</html>"); 

Voir le nom de fichier blob JavaScript sans lien sur ce qu'il faut faire avec cette URL d'objet, il suffit de définir l'emplacement actuel.

Voici une violoncelle mise à jour où l'entrée de l'utilisateur est enregistrée automatiquement dans le stockage local. Chaque fois que le violon est relancé ou la page est actualisée, l'état précédent est restauré. De cette façon, vous n'avez pas besoin d'inciter les utilisateurs à économiser, il enregistre simplement sur son propre.

http://jsfiddle.net/tZPg4/9397/

Le dépassement de pile nécessite d'inclure un code avec un lien jsFiddle, alors ignorez l'extrait:

 localStorage.setItem(...)