无法在'Window'上执行'atob'

时间:2014-03-22 13:59:35

标签: javascript jquery html

当用户按下ctrl + s键但Chrome崩溃时,我正在尝试将我的HTML文件保存在Chrome中。

(我只想下载HTML文件的源代码)

我读到它发生是因为我的文件大于1.99M ..

在第一次尝试中(在我知道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>");

第二次尝试,在我读到崩溃之后,我使用了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>")

我收到错误:Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.

我不知道,但我读到我需要将我的字符串编码为base64:How can you encode a string to Base64 in JavaScript?

有148票的回答。我将其粘贴到我的代码中,不知道如何继续。

我应该在哪里打电话呢?我可以在保存的文件上添加名称吗?

我认为我需要做一些事情:

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

5 个答案:

答案 0 :(得分:18)

BlobBuilder已过时,请改用Blob constructor

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

这将返回一个blob网址,然后您可以在锚点href中使用该网址。您还可以修改锚点download属性来操作文件名:

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

Fiddled。如果我没记错的话,对可信的非用户发起的下载有任意限制;因此,我们将坚持使用链接点击,这被视为充分由用户启动:)

更新:保存当前文档的HTML实际上非常简单!每当点击我们的交互式链接时,我们都会使用相关的blob更新其href。执行点击装订事件后,将导航到下载URL!

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

Fiddled again

答案 1 :(得分:5)

  

我收到错误:Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.

因为您没有传递base64编码的字符串。查看您的功能:downloaddataURItoBlob由于某种原因确实需要数据URI ;但是,您在示例中将一个普通的html标记字符串传递给download

HTML不仅作为base64无效,您在其上调用.split(',')[1]将产生undefined - 并且"undefined"也不是有效的base64编码字符串。

  

我不知道,但我读到我需要将我的字符串编码为base64

这对我来说没什么意义。你想以某种方式对它进行编码,然后只对它进行解码吗?

  

我应该打电话以及如何打电话?

download功能的界面更改回收到filenametext参数的位置。

请注意,BlobBuilder不仅支持追加整个字符串(因此您不需要创建那些ArrayBuffer内容),而且还弃用了Blob constructor

  

我可以在保存的文件上添加姓名吗?

是。不要使用Blob构造函数,而是使用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>");

请参阅JavaScript blob filename without link如何处理该对象网址,只需将当前位置设置为该网址即可。

答案 2 :(得分:5)

不需要将整个编码后的字符串传递给atob方法,您需要将编码后的字符串拆分并将需要的字符串传递给atob方法

const token= "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJob3NzYW0iLCJUb2tlblR5cGUiOiJCZWFyZXIiLCJyb2xlIjoiQURNSU4iLCJpc0FkbWluIjp0cnVlLCJFbXBsb3llZUlkIjoxLCJleHAiOjE2MTI5NDA2NTksImlhdCI6MTYxMjkzNzA1OX0.8f0EeYbGyxt9hjggYW1vR5hMHFVXL4ZvjTA6XgCCAUnvacx_Dhbu1OGh8v5fCsCxXQnJ8iAIZDIgOAIeE55LUw"
console.log(atob(token.split(".")[1]));

答案 3 :(得分:2)

这是一个更新的小提琴,用户的输入自动保存在本地存储中。每次重新运行小提琴或刷新页面时,都会恢复之前的状态。 这样您就不需要提示用户保存,只需保存就可以了。

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

堆栈溢出需要我包含一些带有jsFiddle链接的代码,所以请忽略代码段:

localStorage.setItem(...)

答案 4 :(得分:-1)

我发现,如果要解码,则首先必须decodeURIComponent

atob(decodeURIComponent(merchantData));