Не удалось выполнить 'atob' в 'Window'

Я пытаюсь сохранить свой HTML файл в Chrome, когда пользователь нажимает клавиши ctrl + s, но 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: Как вы можете закодировать строку Base64 в JavaScript?

Есть ответ на 148 голосов. Я вставляю его в свой код и не знаю, как продолжить.

Где я должен это назвать и как? Могу ли я поместить имя в сохраненный файл?

Я думаю, что мне нужно сделать что-то вроде:

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

Ответ 1

BlobBuilder устарел, вместо Blob конструктор:

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

Это возвращает URL-адрес blob, который затем можно использовать в якоре href. Вы также можете изменить атрибут anchor download для управления именем файла:

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

Спрятано. Если я правильно помню, существуют произвольные ограничения на доверенные загрузки, не связанные с пользователем; таким образом, мы будем придерживаться щелчка ссылки, который рассматривается как достаточно инициированный пользователем:)

Обновление: это действительно довольно тривиально, чтобы сохранить текущий html-документ! Всякий раз, когда нажимается наша интерактивная ссылка, мы обновляем ее href соответствующим блобом. После выполнения события, связанного с кликом, URL-адрес загрузки, на который будет осуществляться переход!

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

Спрятано снова.

Ответ 2

Здесь я получил ошибку: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.

Потому что вы не передали строку с кодировкой base64. Посмотрите на свои функции: как download, так и dataURItoBlob ожидать URI данных по какой-либо причине; вы, тем не менее, передаете обычную строку разметки html в download в вашем примере.

Не только HTML недействителен как base64, вы вызываете .split(',')[1] на нем, что даст undefined - и "undefined" также не допустимая строка с кодировкой base64.

Я не знаю, но я прочитал, что мне нужно закодировать мою строку на base64

Это не имеет большого значения для меня. Вы хотите каким-то образом закодировать его, только для его декодирования?

Как мне позвонить и как?

Измените интерфейс вашей функции download до тех пор, пока он не получит аргументы filename и text.

Обратите внимание, что BlobBuilder поддерживает не только добавление целых строк (так что вам не нужно создавать те ArrayBuffer вещи), но также устарел в пользу конструктора Blob.

Можно ли поместить имя в сохраненный файл?

Да. Не используйте конструктор 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 без ссылки о том, что делать с этим URL-адресом объекта, просто установка текущего местоположения на него не работает.

Ответ 3

здесь обновленная скрипка, в которой пользовательский ввод автоматически сохраняется в локальном хранилище. каждый раз, когда скрипта снова запускается или страница обновляется, предыдущее состояние восстанавливается. таким образом вам не нужно запрашивать пользователей для сохранения, он просто сохраняет его самостоятельно.

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

переполнение стека требует, чтобы я включил некоторый код с ссылкой jsFiddle, поэтому, пожалуйста, игнорируйте фрагмент:

localStorage.setItem(...)

Ответ 4

Я обнаружил, что сначала вы должны декодировать decodeURIComponent если вы декодируете, вот так:

atob(decodeURIComponent(dataToBeDecoded));