JavaScript TextEncoder: Base64 для Unicode и UTF-8
btoa ожидает строку из байтов Latin-1 и падает на кириллице. TextEncoder сначала преобразует Unicode в UTF-8 bytes; затем эти байты можно передать в Base64-кодировщик. ??????????? ?????? ? ??????? ???????? ???????? ?????????? ????? ??????????.
Рабочий пример
function toBase64Utf8(value) {
const bytes = new TextEncoder().encode(value);
let binary = '';
for (const byte of bytes) binary += String.fromCharCode(byte);
return btoa(binary);
}
const encoded = toBase64Utf8('??????');
console.log(new TextDecoder().decode(Uint8Array.from(atob(encoded), c => c.charCodeAt(0)))); // ??????Пример обратного преобразования показывает, что содержимое декодируется как UTF-8, а не как набор Unicode-кодовых точек.
Частый вопрос
Почему нельзя просто вызвать btoa('Привет')?
btoa трактует каждый символ строки как однобайтовое значение и не принимает символы вне Latin-1. Сначала нужна явная кодировка UTF-8.