Skip to content
Advertisement

Failed to execute ‘atob’ on ‘Window’

I’m trying to save my HTML file in Chrome when the user presses ctrl + s keys but Chrome is crashed.

(I want to download just the source code of my HTML file)

I read that it happens because my file is bigger than 1.99M..

In the first attempt (before I knew about the crashing in 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>");

The second attempt, after I read about the crashing, I used 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>")

Here I got the error: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.

I don’t know, but I read that I need to encode my string to base64: How can you encode a string to Base64 in JavaScript?

There is an answer of 148 votes. I paste it in my code and don’t know how to continue.

Where should I call it and how? Can I put a name on my saved file?

I think that I need to do something like:

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

Advertisement

Answer

BlobBuilder is obsolete, use Blob constructor instead:

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

This returns a blob URL which you can then use in an anchor’s href. You can also modify an anchor’s download attribute to manipulate the file name:

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

Fiddled. If I recall correctly, there are arbitrary restrictions on trusted non-user initiated downloads; thus we’ll stick with a link clicking which is seen as sufficiently user-initiated 🙂

Update: it’s actually pretty trivial to save current document’s html! Whenever our interactive link is clicked, we’ll update its href with a relevant blob. After executing the click-bound event, that’s the download URL that will be navigated to!

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

Fiddled again.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement