Не удалось выполнить '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>"))

7 ответов

Решение

BlobBuilder устарел, используйте Blob вместо конструктора:

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

Это возвращает URL-адрес BLOB-объекта, который затем можно использовать в привязке href, Вы также можете изменить якорь 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'})
  );
});

Снова поиграл.

Здесь я получил ошибку: 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>");

Посмотрите имя файла BLOB- объекта JavaScript без ссылки на то, что делать с этим URL-адресом объекта, просто установка текущего местоположения для него не работает.

вам не нужно передавать всю закодированную строку в метод atob, вам нужно разделить закодированную строку и передать требуемую строку в метод atob

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

atob(decodeURIComponent(dataToBeDecoded));

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

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

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

localStorage.setItem(...)

У меня та же ошибка, и исправление, которое я нашел, заключалось в том, что в message.usePublicVapidKey('PAIR KEY') я использовал ключ сервера, и ему нужен «парный ключ». Вы можете найти эту информацию в https://console.firebase.google.com/project/_/settings/cloudmessaging/.

Таким образом, значением этой функции является парный ключ в консоли, я был сбит с толку и вставил ключ сервера ‍♂️, что создало ошибку Uncaught DOMException: не удалось выполнить «atob» в «Window»:.

Используйте эту функцию Convert.ToBase64String()

      await JS.InvokeVoidAsync("downloadFromByteArray", 
Convert.ToBase64String(baosDest.ToArray()),FinalPdf, "application/pdf");
Другие вопросы по тегам