Как вы можете закодировать строку в Base64 в JavaScript?

У меня есть сценарий PHP, который может кодировать изображение PNG в строку Base64.

Я бы хотел сделать то же самое с помощью JavaScript. Я знаю, как открывать файлы, но не знаю, как их кодировать. Я не привык работать с двоичными данными.

вот другой плагин jquery для кодирования / декодирования base64

zahid9i 14.03.2012 22:04

Вот лучший способ base64_encode и base64_decode с использованием javascript. См. Ссылки ниже. phpjs.org/functions/base64_encode:358phpjs.org/functions/base64_decode:357

gautamlakum 28.03.2011 17:39

Проверить microjs: microjs.com/#base64

Vinod Srivastav 01.03.2016 17:16
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
921
4
1 328 964
27
Перейти к ответу Данный вопрос помечен как решенный

Ответы 27

Отсюда:

/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/
var Base64 = {

// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ = ",

// public method for encoding
encode : function (input) {
    var output = "";
    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
    var i = 0;

    input = Base64._utf8_encode(input);

    while (i < input.length) {

        chr1 = input.charCodeAt(i++);
        chr2 = input.charCodeAt(i++);
        chr3 = input.charCodeAt(i++);

        enc1 = chr1 >> 2;
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
        enc4 = chr3 & 63;

        if (isNaN(chr2)) {
            enc3 = enc4 = 64;
        } else if (isNaN(chr3)) {
            enc4 = 64;
        }

        output = output +
        this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
        this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

    }

    return output;
},

// public method for decoding
decode : function (input) {
    var output = "";
    var chr1, chr2, chr3;
    var enc1, enc2, enc3, enc4;
    var i = 0;

    input = input.replace(/[^A-Za-z0-9\+/\=]/g, "");

    while (i < input.length) {

        enc1 = this._keyStr.indexOf(input.charAt(i++));
        enc2 = this._keyStr.indexOf(input.charAt(i++));
        enc3 = this._keyStr.indexOf(input.charAt(i++));
        enc4 = this._keyStr.indexOf(input.charAt(i++));

        chr1 = (enc1 << 2) | (enc2 >> 4);
        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
        chr3 = ((enc3 & 3) << 6) | enc4;

        output = output + String.fromCharCode(chr1);

        if (enc3 != 64) {
            output = output + String.fromCharCode(chr2);
        }
        if (enc4 != 64) {
            output = output + String.fromCharCode(chr3);
        }

    }

    output = Base64._utf8_decode(output);

    return output;

},

// private method for UTF-8 encoding
_utf8_encode : function (string) {
    string = string.replace(/\r\n/g,"\n");
    var utftext = "";

    for (var n = 0; n < string.length; n++) {

        var c = string.charCodeAt(n);

        if (c < 128) {
            utftext += String.fromCharCode(c);
        }
        else if ((c > 127) && (c < 2048)) {
            utftext += String.fromCharCode((c >> 6) | 192);
            utftext += String.fromCharCode((c & 63) | 128);
        }
        else {
            utftext += String.fromCharCode((c >> 12) | 224);
            utftext += String.fromCharCode(((c >> 6) & 63) | 128);
            utftext += String.fromCharCode((c & 63) | 128);
        }

    }

    return utftext;
},

// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
    var string = "";
    var i = 0;
    var c = c1 = c2 = 0;

    while ( i < utftext.length ) {

        c = utftext.charCodeAt(i);

        if (c < 128) {
            string += String.fromCharCode(c);
            i++;
        }
        else if ((c > 191) && (c < 224)) {
            c2 = utftext.charCodeAt(i+1);
            string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
            i += 2;
        }
        else {
            c2 = utftext.charCodeAt(i+1);
            c3 = utftext.charCodeAt(i+2);
            string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
            i += 3;
        }

    }

    return string;
}

}

Кроме того, поиск по "кодировка javascript base64" открывает множество других вариантов, указанное выше было первым.

Это также полезно, когда кодировка base64 нестандартна; в моем случае не использовался символ «/» и знак «?» Вместо этого использовался символ, то есть даже в Chrome atob () не собирался декодировать входящие строки base64.

Chris Moschini 17.12.2011 16:43

Будьте осторожны с этим кодом - он пытается интерпретировать вашу строку как строку в кодировке UTF-8. У нас был случай, когда у нас была двоичная строка (т.е. каждый символ в строке должен интерпретироваться как байт), и этот код действительно испортил данные. Прочти источник, Люк.

Daniel Yankowsky 12.11.2012 22:27

Если вы используете код из webtoolkito info, не забывайте об авторских правах: / ** * * Кодирование / декодирование Base64 * webtoolkit.info * ** /

Maciej Łopaciński 13.12.2012 15:36

Все, что необходимо для обеспечения безопасности большинства двоичных кодировок / декодирований, - это удалить сомнительный оператор string = string.replace(/\r\n/g,"\n"); в методе кодирования utf8.

Marius 04.01.2013 21:59

Я бы использовал описанный выше метод с небольшим объемом данных. Для больших файлов лучше рассмотреть многостраничный POST, когда файл передается как двоичный.

Sunny Milenov 06.05.2013 19:45

@Marius: Мне интересно, почему они вообще включили string = string.replace(/\r\n/g,"\n");, лол. Это похоже на «о, давайте закодируем эту строку, но сначала почему бы нам просто случайно не нормализовать все разрывы строк без всякой уважительной причины». Это должно быть исключено из класса при любых обстоятельствах.

Triynko 07.08.2013 02:40

Я знаю, что Base64 предназначен для других целей и имеет накладные расходы 33%. Можно ли оптимизировать это для Интернета? Итак, когда у вас есть изображение со 100 байтами, оно сохраняется в строковой форме как 100 байтов вместо примерно 133 байтов?

employee-0 18.08.2013 02:04

@Triynko, когда люди слепо внедряют решения отсюда, даже немного не проверяя, то они, вероятно, получают то, что заслуживают. (не совсем, я не против помогать людям, но я могу только надеяться, что они хотя бы прочитают эти комментарии!)

Marius 09.09.2013 16:55

Я не гуру javascript, но этот код, похоже, содержит ошибку: если chr2 равно NaN, его значение по-прежнему используется в операторе enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);. В моем браузере это работает нормально, NaN>>4 равен 0, но я не знаю, все ли браузеры это делают (также NaN/16 равно NaN).

Jan 16.12.2013 19:41

@Triynko: Сегодня я обнаружил, что на меня повлияла та строчка, которая превращала "\ r \ n" в "\ n". Мне определенно потребовалось время, чтобы заподозрить, что функция кодирования base 64 искажает мои строки!

Johnny Kauffman 18.03.2015 17:49
input.charCodeAt(i++) всегда возвращает 65535 для символов от 128 (10000000) -255 (11111111) в IE9!
Sen Jacob 18.06.2015 06:00

Заставить все сообщество использовать линейную сложность вместо постоянной (при декодировании) - довольно неортодоксальная вещь;)

Géza Török 12.09.2015 12:58

добавьте .toString () для замены в функции _utf8_encode, потому что если передана строка json, она вызовет исключение

user889030 26.03.2020 10:18

Не работает с юникодом. Сделайте: Base64.encode ("?"), а затем расшифруйте его здесь: base64decode.org

Nathan B 14.03.2021 18:39
Ответ принят как подходящий

Вы можете использовать btoa() и atob() для преобразования в кодировку base64 и обратно.

Похоже, что в комментариях есть некоторая путаница относительно того, что эти функции принимают / возвращают, поэтому ...

  • btoa() принимает «строку», где каждый символ представляет 8-битный байт - если вы передаете строку, содержащую символы, которые не могут быть представлены в 8-битном формате, это, вероятно, сломается. Это не проблема. если вы на самом деле обрабатываете строку как байтовый массив, но если вы пытаетесь сделать что-то еще, вам придется сначала ее закодировать.

  • atob() возвращает «строку», в которой каждый символ представляет 8-битный байт, то есть его значение будет между 0 и 0xff. Это означает, что нет означает, что это ASCII - предположительно, если вы вообще используете эту функцию, вы ожидаете работать с двоичными данными, а не с текстом.

Смотрите также:


Большинство комментариев здесь устарели. Вероятно, вы можете использовать и btoa(), и atob(), если только вы не поддерживаете действительно устаревшие браузеры.

Проверить здесь:

Обратите внимание, что это также работает для браузеров webkit, таких как Safari.

Daniel Von Fange 02.09.2010 13:59

Обратите внимание на особое внимание к строкам Unicode: developer.mozilla.org/En/DOM/Window.btoa#Unicode_Strings btoa и atob правильно работают только для строк на основе ASCII. Как американец, вы, вероятно, не заметите разницы ... но при первом использовании символа с диакритическими знаками ваш код сломается.

Dan Esparza 08.11.2011 20:23

вы должны использовать btoa(unescape(encodeURIComponent(str)))), если str - UFT8

SET 15.05.2013 11:49

Если эти функции поддерживают только строки ascii, их вообще не следует использовать. Период. Вы кодируете 64 байтовые массивы, а не символьные массивы (т.е. строки). Строки - это массивы логических символов, а не массивы байтов. Массивы символов необходимо сначала преобразовать в массивы байтов, выбрав кодировку символов (UTF8, UTF16 или UTF32), чтобы преобразовать каждый символ в последовательности из одного или нескольких байтов (для схем кодирования с переменной длиной, таких как UTF8 или UFT16) или последовательностей. фиксированной длины (в схемах кодирования постоянной длины, таких как UTF32). Как только у вас есть байтовый массив, закодируйте его в base64.

Triynko 07.08.2013 00:55

Смотрите мою редакцию, @Triynko. Они не предназначены для использования для обработки текст, период.

Shog9 07.08.2013 01:19

Хорошо, меня сбило с толку комментарий Дэна о том, что btoa и atob правильно работают только для строк ASCII. Эти функции на самом деле вообще не предназначены для работы с фактическими символьными строками, а скорее с байтовыми массивами, которые хранятся в строках, так что для каждого символа в строке вызов charCodeAt (i) всегда будет возвращать значение между 0 и 255. Я видел это раньше в классе JavaScript Base64, который сначала кодировал бы строку utf8 в другую строку (точно так, как описано, где каждый «символ» фактически представляет значение байта), а затем кодирует это значение в базе 64.

Triynko 07.08.2013 02:32

Таким образом, еще более эффективным методом было бы использовать что-то вроде этого (webtoolkit.info/javascript-base64.html) и просто кодировать через: var encoded = btoa(Base64._utf8_encode(input)) и декодировать с помощью var decoded = Base64._utf8_decode(atob(encoded)). Мне кажется, что выполнение кодировки utf8 гораздо менее подвержено ошибкам, чем передача ввода через unescape(encodeURIComponent(str)). Кроме того, строку string = string.replace(/\r\n/g,"\n"); следует удалить из функции _utf8_encode, поскольку такая нормализация разрыва строки не имеет отношения к базовой функции кодирования utf8.

Triynko 07.08.2013 02:42

Вот полифилл github.com/davidchambers/Base64.js, лучше использовать собственные функции и полифил, а не включать библиотеку, которая представляет новый API.

Benjamin Gruenbaum 18.03.2014 05:58

И обратное к base64-декодированию строки UTF8, закодированной методом SET: decodeURIComponent (escape (window.atob (b64)));

Stefan Steiger 28.10.2014 11:49

Для того, кто предложил это редактирование: действительно не могу достаточно подчеркнуть, что вы не должны передавать произвольные строки в btoa(). Да, этот пример подойдет ... Но он вводит в заблуждение; широкие символы (допустимые в строковом литерале) могут вызвать проблемы.

Shog9 12.11.2015 02:41

Для лучшего запоминания названий функций: btoa() - это бб>efore каfter, atob() - аfter к бб>efore

Dmitry Davydov 10.04.2016 07:19

Javascript - такой пьяный язык. atob, по-видимому, означает «буквенно-цифровой код в base64», поэтому конечно фактически делает наоборот.

user1228 14.07.2016 22:41

двоичный, @Will. Буква b означает «двоичный». Как те отрывочные телеконференции.

Shog9 14.07.2016 23:19

да, но ... Он используется для преобразования строк в base64 ... любой непьющий кодер назвал бы его toBase64, поддерживал бы юникод, а потом вышел бы выпить.

user1228 14.07.2016 23:31

Итак, вот где люди продолжают путаться здесь, @Will - абсолютно необходимо использовать нет для преобразования строк во что-либо или из чего-либо, если только они не являются строками Base64 (a.k.a, alt.binaries -> "b"). Как видите, кодеры были не пьяны, а извращенцы.

Shog9 14.07.2016 23:40

Он произносится как b to a и a to b, где b означает двоичный файл, а знак ASCII.

Captain Hypertext 03.02.2017 22:03

Ввод / вывод "a" должен быть допустимым ASCII, так как это обычное намерение Base64 @Captain. Ни при каких обстоятельствах не предполагайте, что вывод «b» действителен в любой кодировке текста, и не отправляйте текст, который не умещается в 8-битном формате, в функцию, ожидающую «b».

Shog9 03.02.2017 22:08

@ Shog9 Как jpp предложенный, я хотел бы представить вашему вниманию свой мета вопрос и соответствующий редактировать ответа Санни Миленова. Я надеюсь, что такое обращение к вам приемлемо.

T S 17.07.2018 19:46

Я постараюсь найти время, чтобы взглянуть на это, @TS, но имейте в виду, что многие ответы здесь делают дополнительные вещи, потому что, в отличие от исходного вопроса, они пытаются передать Unicode струны через системы, которые не не поддерживает Unicode ... И использует кодировку Base64 как часть этого процесса. Хотя это, безусловно, понятно, иногда возникают некоторые противоречивые (и ... плохо определенные) требования.

Shog9 18.07.2018 02:11

Код Санни великолепен, за исключением того, что он ломается в IE7 из-за ссылок на «this». Исправлено заменой таких ссылок на "Base64":

var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ = ",

// public method for encoding
encode : function (input) {
    var output = "";
    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
    var i = 0;

    input = Base64._utf8_encode(input);

    while (i < input.length) {

        chr1 = input.charCodeAt(i++);
        chr2 = input.charCodeAt(i++);
        chr3 = input.charCodeAt(i++);

        enc1 = chr1 >> 2;
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
        enc4 = chr3 & 63;

        if (isNaN(chr2)) {
            enc3 = enc4 = 64;
        } else if (isNaN(chr3)) {
            enc4 = 64;
        }

        output = output +
        Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
        Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);

    }

    return output;
},

// public method for decoding
decode : function (input) {
    var output = "";
    var chr1, chr2, chr3;
    var enc1, enc2, enc3, enc4;
    var i = 0;

    input = input.replace(/[^A-Za-z0-9\+/\=]/g, "");

    while (i < input.length) {

        enc1 = Base64._keyStr.indexOf(input.charAt(i++));
        enc2 = Base64._keyStr.indexOf(input.charAt(i++));
        enc3 = Base64._keyStr.indexOf(input.charAt(i++));
        enc4 = Base64._keyStr.indexOf(input.charAt(i++));

        chr1 = (enc1 << 2) | (enc2 >> 4);
        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
        chr3 = ((enc3 & 3) << 6) | enc4;

        output = output + String.fromCharCode(chr1);

        if (enc3 != 64) {
            output = output + String.fromCharCode(chr2);
        }
        if (enc4 != 64) {
            output = output + String.fromCharCode(chr3);
        }

    }

    output = Base64._utf8_decode(output);

    return output;

},

// private method for UTF-8 encoding
_utf8_encode : function (string) {
    string = string.replace(/\r\n/g,"\n");
    var utftext = "";

    for (var n = 0; n < string.length; n++) {

        var c = string.charCodeAt(n);

        if (c < 128) {
            utftext += String.fromCharCode(c);
        }
        else if ((c > 127) && (c < 2048)) {
            utftext += String.fromCharCode((c >> 6) | 192);
            utftext += String.fromCharCode((c & 63) | 128);
        }
        else {
            utftext += String.fromCharCode((c >> 12) | 224);
            utftext += String.fromCharCode(((c >> 6) & 63) | 128);
            utftext += String.fromCharCode((c & 63) | 128);
        }

    }

    return utftext;
},

// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
    var string = "";
    var i = 0;
    var c = c1 = c2 = 0;

    while ( i < utftext.length ) {

        c = utftext.charCodeAt(i);

        if (c < 128) {
            string += String.fromCharCode(c);
            i++;
        }
        else if ((c > 191) && (c < 224)) {
            c2 = utftext.charCodeAt(i+1);
            string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
            i += 2;
        }
        else {
            c2 = utftext.charCodeAt(i+1);
            c3 = utftext.charCodeAt(i+2);
            string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
            i += 3;
        }

    }
    return string;
}
}

о, моя беда, я получал ввод из URL-адреса браузера; где | конвертируется в% 7C; следовательно, кодировка тоже неправильная.

Kanagavelu Sugumar 11.09.2013 12:03

Я знаю, что это действительно устарело, но я видел, что эта функция использовалась более чем в одном месте, строка ключа на самом деле состоит из 65 символов, а не 64. Строка не является стандартной спецификацией, я не уверен, что это имеет значение, но просто интересно если это так?

Jonathan Wagner 17.06.2015 07:17

"использовать строго"; это то, что ломает «this» и другие элементы типа, такие как «with», и, судя по тому, что я прочитал, «eval» подвергается критике. Все неуместные идеи о злоупотреблениях. Лично я не понимаю, почему JavaScript должен идти по пути своего продвижения, он никогда не задумывался как программа, сильно связанная и усложненная, чем она есть. Если вы хотите, чтобы вас связали, создайте компилятор для javascript.

Mark Giblin 10.10.2015 15:30

Я пытаюсь использовать эту функцию и получаю сообщение об ошибке: Причина: org.mozilla.javascript.EcmaError: TypeError: Не удается найти замену функции в объекте teste teste teste Я пытаюсь закодировать .txt с помощью «teste teste teste». Кто-нибудь знает, почему эта ошибка?

PRVS 04.11.2015 12:19

@JonathanWagner - для нормальной кодировки используется 64 символа. 65-й ​​символ используется в качестве дополнения к ним, входная строка не имеет количества символов, делящихся на 3.

Kickstart 05.09.2017 16:58

В обеих реализациях _utf8_decode есть пара ошибок. c1 и c2 назначаются как глобальные переменные из-за неправильного использования оператора var, а c3 не инициализируется и не объявляется вообще.

Это работает, но эти переменные перезапишут любые существующие переменные с тем же именем вне этой функции.

Вот версия, которая этого не сделает:

// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
    var string = "";
    var i = 0;
    var c = 0, c1 = 0, c2 = 0;

    while ( i < utftext.length ) {

        c = utftext.charCodeAt(i);

        if (c < 128) {
            string += String.fromCharCode(c);
            i++;
        }
        else if ((c > 191) && (c < 224)) {
            c1 = utftext.charCodeAt(i+1);
            string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
            i += 2;
        }
        else {
            c1 = utftext.charCodeAt(i+1);
            c2 = utftext.charCodeAt(i+2);
            string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
            i += 3;
        }

    }
    return string;
}

@Daan У меня не было достаточно репутации, чтобы редактировать ответы, когда я писал этот ответ ... в 2011 году.

robbles 10.12.2013 21:42

IE7? Я думаю, нам следует перестать тратить время на написание кода для этого, люди не перестанут использовать эту старую технологию, если мы, разработчики, их не заставим!

Rami Dabain 07.06.2014 19:01

@RonanDejhero не работает в IE7? Я не помню, тестировал ли я в этом конкретном браузере.

robbles 09.06.2014 02:47

Я имел в виду, что если он не работает в IE7, никого не волнует !. я не тестировал и тестировать не буду :)

Rami Dabain 09.06.2014 15:02

Чтобы сделать строковый URL-адрес в кодировке Base64 дружественным, в JavaScript вы можете сделать что-то вроде этого:

// if this is your Base64 encoded string
var str = 'VGhpcyBpcyBhbiBhd2Vzb21lIHNjcmlwdA=='; 

// make URL friendly:
str = str.replace(/\+/g, '-').replace(///g, '_').replace(/\=+$/, '');

// reverse to original encoding
str = (str + '===').slice(0, str.length + (str.length % 4));
str = str.replace(/-/g, '+').replace(/_/g, '/');

См. Также эту скрипку: http://jsfiddle.net/magikMaker/7bjaT/

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

Pablo Fernandez 28.10.2011 20:22

encodeURIComponent изменит длину строк в кодировке base64, а замена '-' и '_' на '+' и '/' является стандартной практикой при использовании base64 в URL-адресах (например, docs.python.org/library/base64.html#base64.urlsafe_b64encode‌). Не нужно расстраиваться.

natevw 22.12.2011 21:29

Вы можете использовать btoa (до base-64) и atob (от base-64).

Для IE 9 и ниже попробуйте плагин jquery-base64:

$.base64.encode("this is a test");
$.base64.decode("dGhpcyBpcyBhIHRlc3Q = ");

Почему все должно быть плагином jQuery: c это всего лишь основная функциональность JavaScript, не имеющая ничего общего с DOM или jQuery

EaterOfCode 29.04.2013 15:04

Это не основная функциональность, иначе было бы не так много разных ответов с высокими оценками (включая самодельный код tl; dr). Итак, imho, на самом деле это хороший вариант использования jQuery (один лайнер, ожидается, что он будет работать даже в Android WebView) - даже больше, если он уже является зависимостью.

Risadinha 26.08.2013 21:04

Я ушел и сдался. Подмножество jQuery следует формализовать и ввести в стандарт JS как «.net». Это некрасиво, но потребность огромна, и она пришла, чтобы управлять экосистемой.

Lodewijk 14.06.2014 20:52

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

sffc 25.06.2014 11:23
w3schools.com/jsref/met_win_btoa.asp указывает на поддержку btoa для Chrome, IE10 +, Firefox, Safari, Opera
OzBob 22.07.2015 05:11

Это «глобальное пространство имен», и использование фреймворков для выполнения небольших программ, идея пакета и JQuery написаны на JavaScript, ЭТО НЕ ЯВЛЯЕТСЯ JavaScript. Прочтите об atob () и btoa (), потому что вы обнаружите, что они не согласованы между типами браузеров.

Mark Giblin 10.10.2015 15:32

@Risadinha - за исключением того, что его функциональность не зависит от чего-либо jQuery и не расширяет его ... буквально единственные ссылки на jQuery в его коде прикрепляют его к объекту jQuery ... так какой смысл прикреплять его к jQuery и, следовательно, требовать jQuery использовать? Просто сделайте его собственным 1 вкладышем base64.encode(...) и base64.decode(...) ... прикреплять его к jQuery, когда он не имеет никакой специфической функциональности jQuery, не имеет абсолютно никакого смысла ...

Jimbo Jonny 12.03.2016 08:28

jQuery не запрашивался. Не верный ответ на простой старый вопрос JS.

metaColin 11.02.2017 01:20

Я добавил +1 к ответу Санни, но я хотел внести несколько изменений, которые я внес в свой собственный проект, на случай, если кто-то сочтет это полезным. По сути, я только что немного очистил исходный код, чтобы JSLint не жаловался так сильно, и я сделал методы, отмеченные как частные в комментариях, на самом деле частными. Я также добавил два метода, которые мне понадобились в моем собственном проекте, а именно decodeToHex и encodeFromHex.

Код:

var Base64 = (function() {
    "use strict";

    var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ = ";

    var _utf8_encode = function (string) {

        var utftext = "", c, n;

        string = string.replace(/\r\n/g,"\n");

        for (n = 0; n < string.length; n++) {

            c = string.charCodeAt(n);

            if (c < 128) {

                utftext += String.fromCharCode(c);

            } else if ((c > 127) && (c < 2048)) {

                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);

            } else {

                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);

            }

        }

        return utftext;
    };

    var _utf8_decode = function (utftext) {
        var string = "", i = 0, c = 0, c1 = 0, c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {

                string += String.fromCharCode(c);
                i++;

            } else if ((c > 191) && (c < 224)) {

                c1 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
                i += 2;

            } else {

                c1 = utftext.charCodeAt(i+1);
                c2 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
                i += 3;

            }

        }

        return string;
    };

    var _hexEncode = function(input) {
        var output = '', i;

        for(i = 0; i < input.length; i++) {
            output += input.charCodeAt(i).toString(16);
        }

        return output;
    };

    var _hexDecode = function(input) {
        var output = '', i;

        if (input.length % 2 > 0) {
            input = '0' + input;
        }

        for(i = 0; i < input.length; i = i + 2) {
            output += String.fromCharCode(parseInt(input.charAt(i) + input.charAt(i + 1), 16));
        }

        return output;
    };

    var encode = function (input) {
        var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;

        input = _utf8_encode(input);

        while (i < input.length) {

            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);

            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;

            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }

            output += _keyStr.charAt(enc1);
            output += _keyStr.charAt(enc2);
            output += _keyStr.charAt(enc3);
            output += _keyStr.charAt(enc4);

        }

        return output;
    };

    var decode = function (input) {
        var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;

        input = input.replace(/[^A-Za-z0-9\+/\=]/g, "");

        while (i < input.length) {

            enc1 = _keyStr.indexOf(input.charAt(i++));
            enc2 = _keyStr.indexOf(input.charAt(i++));
            enc3 = _keyStr.indexOf(input.charAt(i++));
            enc4 = _keyStr.indexOf(input.charAt(i++));

            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;

            output += String.fromCharCode(chr1);

            if (enc3 !== 64) {
                output += String.fromCharCode(chr2);
            }
            if (enc4 !== 64) {
                output += String.fromCharCode(chr3);
            }

        }

        return _utf8_decode(output);
    };

    var decodeToHex = function(input) {
        return _hexEncode(decode(input));
    };

    var encodeFromHex = function(input) {
        return encode(_hexDecode(input));
    };

    return {
        'encode': encode,
        'decode': decode,
        'decodeToHex': decodeToHex,
        'encodeFromHex': encodeFromHex
    };
}());

Сначала я думал, что развертывание выходной конкатенации в отдельные операторы будет более оптимальным, но после того, как я подумал об этом на секунду, этот должен будет более неэффективным, поскольку строки Javascript неизменны, и при работе это вызовет 4 копии потенциально огромных больших двоичных объектов с большими двоичными файлами данных. Более безопасный вариант - сначала объединить 4 символа вместе, а затем построить новую строку. Хотел бы я знать наверняка о лучшем методе построения струн, который был бы эффективен на всех платформах. (даже IE6)

Marius 04.01.2013 22:19

Я не рассматривал производительность при очистке первоначально опубликованного кода. Я просто сделал его более читабельным и сделал методы, отмеченные как частные в комментариях в оригинале, на самом деле частными, используя шаблон модуля раскрытия. Я уверен, что его можно оптимизировать и с точки зрения производительности. Не совсем уверен, когда здесь начнется сборка мусора, а хеширование больших файлов с помощью Javascript не очень распространено (или, скорее всего, не является оптимальным решением в любом случае).

Joe Dyndale 07.01.2013 15:39

Забавно, как здесь живет этот код. На этой странице уже есть 3 разные версии.

gregn3 07.03.2014 16:37

если вам нужно закодировать объект изображения HTML, вы можете написать простую функцию, например:

function getBase64Image(img) {  
  var canvas = document.createElement("canvas");  
  canvas.width = img.width;  
  canvas.height = img.height;  
  var ctx = canvas.getContext("2d");  
  ctx.drawImage(img, 0, 0);  
  var dataURL = canvas.toDataURL("image/png");  
  // escape data:image prefix
  return dataURL.replace(/^data:image/(png|jpg);base64,/, "");  
  // or just return dataURL
  // return dataURL
}  

Чтобы получить base64 изображения по идентификатору:

function getBase64ImageById(id){  
  return getBase64Image(document.getElementById(id));  
} 

узнать больше здесь

Ага, и var img = new Image (); img.src = "../images/myPic.png";

pdschuller 10.12.2013 22:01

Обратите внимание, что это не подходит для необработанных строк Unicode! См. Раздел Unicode здесь.

Синтаксис для кодирования

var encodedData = window.btoa(stringToEncode);

Синтаксис для декодирования

var decodedData = window.atob(encodedData);

Прямая ссылка на раздел юникода: developer.mozilla.org/en-US/docs/Web/API/…

TomTasche 25.01.2020 13:17

Я вручную переписал эти методы кодирования и декодирования, за исключением шестнадцатеричного, в модульный формат для кросс-платформенной / браузерной совместимости, а также с реальной частной областью видимости, и использует btoa и atob, если они существуют, скорее из-за скорости чем использовать собственную кодировку:

https://gist.github.com/Nijikokun/5192472

Использование:

base64.encode(/* String */);
base64.decode(/* String */);

utf8.encode(/* String */);
utf8.decode(/* String */);

В моем проекте мне все еще нужно поддерживать IE7 и работать с большими входными данными для кодирования.

На основе кода, предложенного Джо Диндейлом и предложенного в комментарии Мариуса, можно улучшить производительность с IE7, построив результат с помощью массива вместо строки.

Вот пример кодирования:

var encode = function (input) {
    var output = [], chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;

    input = _utf8_encode(input);

    while (i < input.length) {

        chr1 = input.charCodeAt(i++);
        chr2 = input.charCodeAt(i++);
        chr3 = input.charCodeAt(i++);

        enc1 = chr1 >> 2;
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
        enc4 = chr3 & 63;

        if (isNaN(chr2)) {
            enc3 = enc4 = 64;
        } else if (isNaN(chr3)) {
            enc4 = 64;
        }

        output.push(_keyStr.charAt(enc1));
        output.push(_keyStr.charAt(enc2));
        output.push(_keyStr.charAt(enc3));
        output.push(_keyStr.charAt(enc4));

    }

    return output.join("");
};

Что ж, если вы используете додзё, это дает нам прямой способ кодирования или декодирования в base64.

Попробуй это:-

Чтобы закодировать массив байтов с помощью dojox.encoding.base64:

var str = dojox.encoding.base64.encode(myByteArray);

Чтобы декодировать строку в кодировке base64:

var bytes = dojox.encoding.base64.decode(str);

Я бы предпочел использовать методы кодирования / декодирования bas64 из CryptoJS, самой популярной библиотеки для стандартных и безопасных криптографических алгоритмов, реализованных на JavaScript с использованием лучших практик и шаблонов.

Внесение вклада в минифицированный полифилл для window.atob + window.btoa, который я сейчас использую.

(function(){function t(t){this.message=t}var e = "undefined"!=typeof exports?exports:this,r = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ = ";t.prototype=Error(),t.prototype.name = "InvalidCharacterError",e.btoa||(e.btoa=function(e){for(var o,n,a=0,i=r,c = "";e.charAt(0|a)||(i = " = ",a%1);c+=i.charAt(63&o>>8-8*(a%1))){if (n=e.charCodeAt(a+=.75),n>255)throw new t("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");o=o<<8|n}return c}),e.atob||(e.atob=function(e){if (e=e.replace(/=+$/,""),1==e.length%4)throw new t("'atob' failed: The string to be decoded is not correctly encoded.");for(var o,n,a=0,i=0,c = "";n=e.charAt(i++);~n&&(o=a%4?64*o+n:n,a++%4)?c+=String.fromCharCode(255&o>>(6&-2*a)):0)n=r.indexOf(n);return c})})();

Вот версия @ user850789 для AngularJS Factory:

'use strict';

var ProjectNameBase64Factory = angular.module('project_name.factories.base64', []);

ProjectNameBase64Factory.factory('Base64', function () {
    var Base64 = {
        // private property
        _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ = ",

        // public method for encoding
        encode: function (input) {
            var output = "";
            var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
            var i = 0;

            input = Base64._utf8_encode(input);

            while (i < input.length) {

                chr1 = input.charCodeAt(i++);
                chr2 = input.charCodeAt(i++);
                chr3 = input.charCodeAt(i++);

                enc1 = chr1 >> 2;
                enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                enc4 = chr3 & 63;

                if (isNaN(chr2)) {
                    enc3 = enc4 = 64;
                } else if (isNaN(chr3)) {
                    enc4 = 64;
                }

                output = output +
                         Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
                         Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);

            }

            return output;
        },

        // public method for decoding
        decode: function (input) {
            var output = "";
            var chr1, chr2, chr3;
            var enc1, enc2, enc3, enc4;
            var i = 0;

            input = input.replace(/[^A-Za-z0-9\+/\=]/g, "");

            while (i < input.length) {

                enc1 = Base64._keyStr.indexOf(input.charAt(i++));
                enc2 = Base64._keyStr.indexOf(input.charAt(i++));
                enc3 = Base64._keyStr.indexOf(input.charAt(i++));
                enc4 = Base64._keyStr.indexOf(input.charAt(i++));

                chr1 = (enc1 << 2) | (enc2 >> 4);
                chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                chr3 = ((enc3 & 3) << 6) | enc4;

                output = output + String.fromCharCode(chr1);

                if (enc3 != 64) {
                    output = output + String.fromCharCode(chr2);
                }
                if (enc4 != 64) {
                    output = output + String.fromCharCode(chr3);
                }

            }

            output = Base64._utf8_decode(output);

            return output;

        },

        // private method for UTF-8 encoding
        _utf8_encode: function (string) {
            string = string.replace(/\r\n/g, "\n");
            var utftext = "";

            for (var n = 0; n < string.length; n++) {

                var c = string.charCodeAt(n);

                if (c < 128) {
                    utftext += String.fromCharCode(c);
                }
                else if ((c > 127) && (c < 2048)) {
                    utftext += String.fromCharCode((c >> 6) | 192);
                    utftext += String.fromCharCode((c & 63) | 128);
                }
                else {
                    utftext += String.fromCharCode((c >> 12) | 224);
                    utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                    utftext += String.fromCharCode((c & 63) | 128);
                }

            }

            return utftext;
        },

        // private method for UTF-8 decoding
        _utf8_decode: function (utftext) {
            var string = "";
            var i = 0;
            var c = 0, c2 = 0, c3 = 0;

            while (i < utftext.length) {

                c = utftext.charCodeAt(i);

                if (c < 128) {
                    string += String.fromCharCode(c);
                    i++;
                }
                else if ((c > 191) && (c < 224)) {
                    c2 = utftext.charCodeAt(i + 1);
                    string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                    i += 2;
                }
                else {
                    c2 = utftext.charCodeAt(i + 1);
                    c3 = utftext.charCodeAt(i + 2);
                    string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                    i += 3;
                }

            }
            return string;
        }
    };
    return Base64;
});

Мне нужна была кодировка строки UTF-8 как base64 для моего проекта. Большинство ответов здесь, похоже, неправильно обрабатывают суррогатные пары UTF-16 при преобразовании в UTF-8, поэтому для завершения я опубликую свое решение:

function strToUTF8Base64(str) {

    function decodeSurrogatePair(hi, lo) {
        var resultChar = 0x010000;
        resultChar += lo - 0xDC00;
        resultChar += (hi - 0xD800) << 10;
        return resultChar;
    }

    var bytes = [0, 0, 0];
    var byteIndex = 0;
    var result = [];

    function output(s) {
        result.push(s);
    }

    function emitBase64() {

        var digits =
                'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
                'abcdefghijklmnopqrstuvwxyz' +
                '0123456789+/';

        function toDigit(value) {
            return digits[value];
        }

        // --Byte 0--    --Byte 1--    --Byte 2--
        // 1111  1122    2222  3333    3344  4444

        var d1 = toDigit(bytes[0] >> 2);
        var d2 = toDigit(
            ((bytes[0] & 0x03) << 4) |
            (bytes[1] >> 4));
        var d3 = toDigit(
            ((bytes[1] & 0x0F) << 2) |
            (bytes[2] >> 6));
        var d4 = toDigit(
            bytes[2] & 0x3F);

        if (byteIndex === 1) {
            output(d1 + d2 + '==');
        }
        else if (byteIndex === 2) {
            output(d1 + d2 + d3 + '=');
        }
        else {
            output(d1 + d2 + d3 + d4);
        }
    }

    function emit(chr) {
        bytes[byteIndex++] = chr;
        if (byteIndex == 3) {
            emitBase64();
            bytes[0] = 0;
            bytes[1] = 0;
            bytes[2] = 0;
            byteIndex = 0;
        }
    }

    function emitLast() {
        if (byteIndex > 0) {
            emitBase64();
        }
    }

    // Converts the string to UTF8:

    var i, chr;
    var hi, lo;
    for (i = 0; i < str.length; i++) {
        chr = str.charCodeAt(i);

        // Test and decode surrogate pairs in the string
        if (chr >= 0xD800 && chr <= 0xDBFF) {
            hi = chr;
            lo = str.charCodeAt(i + 1);
            if (lo >= 0xDC00 && lo <= 0xDFFF) {
                chr = decodeSurrogatePair(hi, lo);
                i++;
            }
        }

        // Encode the character as UTF-8.
        if (chr < 0x80) {
            emit(chr);
        }
        else if (chr < 0x0800) {
            emit((chr >> 6) | 0xC0);
            emit(((chr >> 0) & 0x3F) | 0x80);
        }
        else if (chr < 0x10000) {
            emit((chr >> 12) | 0xE0);
            emit(((chr >>  6) & 0x3F) | 0x80);
            emit(((chr >>  0) & 0x3F) | 0x80);
        }
        else if (chr < 0x110000) {
            emit((chr >> 18) | 0xF0);
            emit(((chr >> 12) & 0x3F) | 0x80);
            emit(((chr >>  6) & 0x3F) | 0x80);
            emit(((chr >>  0) & 0x3F) | 0x80);
        }
    }

    emitLast();

    return result.join('');
}

Обратите внимание, что код не прошел тщательную проверку. Я протестировал некоторые входные данные, включая такие вещи, как strToUTF8Base64('衠衢蠩蠨'), и сравнил их с выходными данными онлайн-инструмента кодирования (https://www.base64encode.org/).

Internet Explorer 10+

// Define the string
var string = 'Hello World!';

// Encode the String
var encodedString = btoa(string);
console.info(encodedString); // Outputs: "SGVsbG8gV29ybGQh"

// Decode the String
var decodedString = atob(encodedString);
console.info(decodedString); // Outputs: "Hello World!"

Кроссбраузерность

// Create Base64 Object
var Base64 = {_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ = ",encode:function(e){var t = "";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if (isNaN(r)){u=a=64}else if (isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t = "";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if (u!=64){t=t+String.fromCharCode(r)}if (a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t = "";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if (r<128){t+=String.fromCharCode(r)}else if (r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t = "";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if (r<128){t+=String.fromCharCode(r);n++}else if (r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}

// Define the string
var string = 'Hello World!';

// Encode the String
var encodedString = Base64.encode(string);
console.info(encodedString); // Outputs: "SGVsbG8gV29ybGQh"

// Decode the String
var decodedString = Base64.decode(encodedString);
console.info(decodedString); // Outputs: "Hello World!"

jsFiddle


с Node.js

Вот как вы кодируете обычный текст в base64 в Node.js:

//Buffer() requires a number, array or string as the first parameter, and an optional encoding type as the second parameter. 
// Default is utf8, possible encoding types are ascii, utf8, ucs2, base64, binary, and hex
var b = new Buffer('JavaScript');
// If we don't use toString(), JavaScript assumes we want to convert the object to utf8.
// We can make it convert to other formats by passing the encoding type to toString().
var s = b.toString('base64');

А вот как вы декодируете строки в кодировке base64:

var b = new Buffer('SmF2YVNjcmlwdA==', 'base64')
var s = b.toString();

с Dojo.js

Чтобы закодировать массив байтов с помощью dojox.encoding.base64:

var str = dojox.encoding.base64.encode(myByteArray);

Чтобы декодировать строку в кодировке base64:

var bytes = dojox.encoding.base64.decode(str)

bower установить angular-base64

<script src = "bower_components/angular-base64/angular-base64.js"></script>

angular
    .module('myApp', ['base64'])
    .controller('myController', [

    '$base64', '$scope', 
    function($base64, $scope) {

        $scope.encoded = $base64.encode('a string');
        $scope.decoded = $base64.decode('YSBzdHJpbmc=');
}]);

Этот ответ основан на исходном коде и НЕ включает обновления этого кода, опубликованные в других ответах здесь.

Eugene Ryabtsev 27.11.2014 13:15

Предлагаемое решение NodeJS устарело.

Vladimir Nul 23.09.2019 14:32
new Buffer() устарел, используйте вместо него Buffer.from()
Ivan Rubinson 06.08.2020 11:07

Немного больше работы, но если вам нужно высокопроизводительное собственное решение, вы можете использовать некоторые функции HTML5.

Если вы можете поместить свои данные в Blob, то вы можете использовать функцию FileReader.readAsDataURL (), чтобы получить URL-адрес data://, и отрезать его переднюю часть, чтобы получить данные base64.

Возможно, вам придется выполнить дополнительную обработку, чтобы url-декодировать данные, поскольку я не уверен, экранируются ли символы + или нет для URL-адреса data://, но это должно быть довольно тривиально.

Этот вопрос и ответы на него указали мне правильное направление. Особенно с unicode atob и btoa нельзя использовать "vanilla", и в наши дни ВСЕ - unicode ..

Непосредственно из Mozilla, две приятные функции для этой цели (протестированы с помощью тегов unicode и html внутри)

function b64EncodeUnicode(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
        return String.fromCharCode('0x' + p1);
    }));
}

b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU = "
b64EncodeUnicode('\n'); // "Cg= = "



function b64DecodeUnicode(str) {
    return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''));
}

b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
b64DecodeUnicode('Cg=='); // "\n"

Эти функции будут выполнять молниеносную работу по сравнению с необработанным декодированием base64 с использованием пользовательской функции javascript, поскольку btoa и atob выполняются вне интерпретатора.

Если вы можете игнорировать старый IE и старые мобильные телефоны (например, iphone 3?), Это должно быть хорошим решением.

Это из MDN?

1.21 gigawatts 13.06.2020 02:56

Из комментариев (SET и Stefan Steiger) ниже принятого ответа, вот краткое изложение того, как кодировать / декодировать строку в / из base64 без необходимости в библиотеке.

str = "The quick brown fox jumps over the lazy dog";
b64 = btoa(unescape(encodeURIComponent(str)));
str = decodeURIComponent(escape(window.atob(b64)));

Демо

(использует библиотеку jQuery, но не для кодирования / декодирования)

str = "The quick brown fox jumps over the lazy dog";

$('input').val(str);

$('#btnConv').click(function(){
  var txt = $('input').val();
  var b64 = btoa(unescape(encodeURIComponent(txt)));
  $('input').val(b64);
  $('#btnDeConv').show();
});
$('#btnDeConv').click(function(){
  var b64 = $('input').val();
  var txt = decodeURIComponent(escape(window.atob(b64)));
  $('input').val(txt);
});
#btnDeConv{display:none;}
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type = "text" />
<button id = "btnConv">Convert</button>
<button id = "btnDeConv">DeConvert</button>

Подтверждаю, что это поддерживает символы UTF-8?

Crashalot 03.02.2018 12:09

@Crashalot Я понимаю, что это на два года слишком поздно, но да, это так. Когда я набираю это, я также просто понимаю, что вы предоставили правку, которая, возможно, заставила UTF8 работать.

tycrek 05.04.2020 20:34

Для всех, кто здесь ищет хорошее решение для использования с Node.js, я могу подтвердить, что это работает. Для декодирования в Node я использовал: Buffer.from(b64data, 'base64').toString();

tycrek 05.04.2020 20:35

Может кто-нибудь объяснить, что делают unescape и escape в этом снятом решении?

Sammi 16.09.2020 19:09

Вы можете использовать window.btoa и window.atob ...

const encoded = window.btoa('Alireza Dezfoolian'); // encode a string
const decoded = window.atob(encoded); // decode the string

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

// ucs-2 string to base64 encoded ascii
function utoa(str) {
    return window.btoa(unescape(encodeURIComponent(str)));
}
// base64 encoded ascii to ucs-2 string
function atou(str) {
    return decodeURIComponent(escape(window.atob(str)));
}
// Usage:
utoa('✓ à la mode'); // 4pyTIMOgIGxhIG1vZGU=
atou('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"

utoa('I \u2661 Unicode!'); // SSDimaEgVW5pY29kZSE=
atou('SSDimaEgVW5pY29kZSE='); // "I ♡ Unicode!"

Чтобы новые браузеры кодировали Uint8Array в строку и декодировали строку в Uint8Array.

const base64 = {
    decode: s => Uint8Array.from(atob(s), c => c.charCodeAt(0)),
    encode: b => btoa(String.fromCharCode(...new Uint8Array(b)))
};

Для Node.js вы можете использовать следующее для кодирования строки, Buffer или Uint8Array в строку и декодирования из строки, Buffer или Uint8Array в Buffer.

const base64 = {
    decode: s => Buffer.from(s, 'base64'),
    encode: b => Buffer.from(b).toString('base64')
};

не хорошо. ошибочный.

mmm 31.12.2020 17:18

Вот ЖИВАЯ ДЕМО встроенных функций atob() и btoa() JS:

<!DOCTYPE html>
<html>
  <head>
    <style>
      textarea{
        width:30%;
        height:100px;
      }
    </style>
    <script>
      // encode string to base64
      function encode()
      {
        var txt = document.getElementById("txt1").value;
        var result = btoa(txt);
        document.getElementById("txt2").value = result;
      }
      // decode base64 back to original string
      function decode()
      {
        var txt = document.getElementById("txt3").value;
        var result = atob(txt);
        document.getElementById("txt4").value = result;
      }
    </script>
  </head>
  <body>
    <div>
      <textarea id = "txt1">Some text to decode
      </textarea>
    </div>
    <div>
      <input type = "button" id = "btnencode" value = "Encode" onClick = "encode()"/>
    </div>
    <div>
      <textarea id = "txt2">
      </textarea>
    </div>
    <br/>
    <div>
      <textarea id = "txt3">U29tZSB0ZXh0IHRvIGRlY29kZQ==
      </textarea>
    </div>
    <div>
      <input type = "button" id = "btndecode" value = "Decode" onClick = "decode()"/>
    </div>
    <div>
      <textarea id = "txt4">
      </textarea>
    </div>
  </body>
</html>

Использовать библиотеку js-base64 как

btoa() doesn't work with emojis

var str = "I was funny ?";
console.info("Original string:", str);

var encodedStr = Base64.encode(str)
console.info("Encoded string:", encodedStr);

var decodedStr = Base64.decode(encodedStr)
console.info("Decoded string:", decodedStr);
<script src = "https://cdn.jsdelivr.net/npm/[email protected]/base64.min.js"></script>

Вы можете использовать btoa () / atob () в браузере, но требуются некоторые улучшения, как описано здесь: https://base64tool.com/uncaught-domexception-btoa-on-window/ и https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/btoa для поддержки строк UTF!

JS без промежуточного этапа btoa (без библиотеки)

В заголовке вопроса вы пишете о преобразовании строк, но в вопросе вы говорите о двоичных данных (изображение), поэтому вот функция, которая выполняет правильное преобразование, начиная с двоичных данных изображения PNG (подробности и обратное преобразование здесь)

function bytesArrToBase64(arr) {
  const abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // base64 alphabet
  const bin = n => n.toString(2).padStart(8,0); // convert num to 8-bit binary string
  const l = arr.length
  let result = '';

  for(let i=0; i<=(l-1)/3; i++) {
    let c1 = i*3+1>=l; // case when " = " is on end
    let c2 = i*3+2>=l; // case when " = " is on end
    let chunk = bin(arr[3*i]) + bin(c1? 0:arr[3*i+1]) + bin(c2? 0:arr[3*i+2]);
    let r = chunk.match(/.{1,6}/g).map((x,j)=> j==3&&c2 ? '=' :(j==2&&c1 ? '=':abc[+('0b'+x)]));  
    result += r.join('');
  }

  return result;
}



// TEST

const pic = [ // PNG binary data
    0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
    0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,
    0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, 0x61, 0x00, 0x00, 0x00,
    0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
    0x01, 0x59, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f,
    0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65,
    0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22,
    0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74,
    0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d,
    0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e,
    0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64,
    0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a,
    0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
    0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31,
    0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64,
    0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23,
    0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64,
    0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
    0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d,
    0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
    0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66,
    0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73,
    0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74,
    0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20,
    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66,
    0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
    0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72,
    0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20,
    0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44,
    0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a,
    0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46,
    0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74,
    0x61, 0x3e, 0x0a, 0x4c, 0xc2, 0x27, 0x59, 0x00, 0x00, 0x00, 0xf9, 0x49,
    0x44, 0x41, 0x54, 0x38, 0x11, 0x95, 0x93, 0x3d, 0x0a, 0x02, 0x41, 0x0c,
    0x85, 0xb3, 0xb2, 0x85, 0xb7, 0x10, 0x6c, 0x04, 0x1b, 0x0b, 0x4b, 0x6f,
    0xe2, 0x76, 0x1e, 0xc1, 0xc2, 0x56, 0x6c, 0x2d, 0xbc, 0x85, 0xde, 0xc4,
    0xd2, 0x56, 0xb0, 0x11, 0xbc, 0x85, 0x85, 0xa0, 0xfb, 0x46, 0xbf, 0xd9,
    0x30, 0x33, 0x88, 0x06, 0x76, 0x93, 0x79, 0x93, 0xf7, 0x92, 0xf9, 0xab,
    0xcc, 0xec, 0xd9, 0x7e, 0x7f, 0xd9, 0x63, 0x33, 0x8e, 0xf9, 0x75, 0x8c,
    0x92, 0xe0, 0x34, 0xe8, 0x27, 0x88, 0xd9, 0xf4, 0x76, 0xcf, 0xb0, 0xaa,
    0x45, 0xb2, 0x0e, 0x4a, 0xe4, 0x94, 0x39, 0x59, 0x0c, 0x03, 0x54, 0x14,
    0x58, 0xce, 0xbb, 0xea, 0xdb, 0xd1, 0x3b, 0x71, 0x75, 0xb9, 0x9a, 0xe2,
    0x7a, 0x7d, 0x36, 0x3f, 0xdf, 0x4b, 0x95, 0x35, 0x09, 0x09, 0xef, 0x73,
    0xfc, 0xfa, 0x85, 0x67, 0x02, 0x3e, 0x59, 0x55, 0x31, 0x89, 0x31, 0x56,
    0x8c, 0x78, 0xb6, 0x04, 0xda, 0x23, 0x01, 0x01, 0xc8, 0x8c, 0xe5, 0x77,
    0x87, 0xbb, 0x65, 0x02, 0x24, 0xa4, 0xad, 0x82, 0xcb, 0x4b, 0x4c, 0x64,
    0x59, 0x14, 0xa0, 0x72, 0x40, 0x3f, 0xbf, 0xe6, 0x68, 0xb6, 0x9f, 0x75,
    0x08, 0x63, 0xc8, 0x9a, 0x09, 0x02, 0x25, 0x32, 0x34, 0x48, 0x7e, 0xcc,
    0x7d, 0x10, 0xaf, 0xa6, 0xd5, 0xd2, 0x1a, 0x3d, 0x89, 0x38, 0xf5, 0xf1,
    0x14, 0xb4, 0x69, 0x6a, 0x4d, 0x15, 0xf5, 0xc9, 0xf0, 0x5c, 0x1a, 0x61,
    0x8a, 0x75, 0xd1, 0xe8, 0x3a, 0x2c, 0x41, 0x5d, 0x70, 0x41, 0x20, 0x29,
    0xf9, 0x9b, 0xb1, 0x37, 0xc5, 0x4d, 0xfc, 0x45, 0x84, 0x7d, 0x08, 0x8f,
    0x89, 0x76, 0x54, 0xf1, 0x1b, 0x19, 0x92, 0xef, 0x2c, 0xbe, 0x46, 0x8e,
    0xa6, 0x49, 0x5e, 0x61, 0x89, 0xe4, 0x05, 0x5e, 0x4e, 0xa4, 0x5c, 0x10,
    0x6e, 0x9f, 0xfc, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44,
    0xae, 0x42, 0x60, 0x82
];

let b64pic = bytesArrToBase64(pic);
myPic.src = "data:image/png;base64,"+b64pic;
msg.innerHTML = "Base64 encoded pic data:<br>" + b64pic;
img { zoom: 10; image-rendering: pixelated; }
#msg { word-break: break-all; }
<img id = "myPic">
<code id = "msg"></code>
let a = Buffer.from('JavaScript').toString('base64');
console.info(a);

let b = Buffer.from(a, 'base64').toString();
console.info(b);

Другие вопросы по теме