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