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

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

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


person username    schedule 29.10.2008    source источник
comment
Вот лучший способ base64_encode и base64_decode с использованием javascript. См. Ссылки ниже. phpjs.org/functions/base64_encode:358 phpjs.org/functions/base64_decode:357   -  person gautamlakum    schedule 28.03.2011
comment
вот другой плагин jquery для кодирования / декодирования base64   -  person zahid9i    schedule 14.03.2012
comment
Проверьте microjs: microjs.com/#base64   -  person Vinod Srivastav    schedule 01.03.2016
comment
Упоминается в мета-вопросе Практически идентичные ответы - единственное отличие: исправление ошибок.   -  person Peter Mortensen    schedule 16.07.2018


Ответы (28)


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

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

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

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

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


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

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

person Shog9    schedule 29.10.2008
comment
Обратите внимание, что это также работает для браузеров webkit, таких как Safari. - person Daniel Von Fange; 02.09.2010
comment
Обратите внимание на особое внимание к строкам Unicode: developer.mozilla.org/En/DOM /Window.btoa#Unicode_Strings btoa и atob правильно работают только для строк на основе ASCII. Как американец, вы, вероятно, не заметите разницы ... но при первом использовании символа с диакритическими знаками ваш код сломается. - person Dan Esparza; 08.11.2011
comment
вы должны использовать btoa(unescape(encodeURIComponent(str)))), если str - UFT8 - person SET; 15.05.2013
comment
Если эти функции поддерживают только строки ascii, их вообще не следует использовать. Период. Вы кодируете 64 байтовые массивы, а не символьные массивы (т.е. строки). Строки - это массивы логических символов, а не массивы байтов. Массивы символов необходимо сначала преобразовать в массивы байтов, выбрав кодировку символов (UTF8, UTF16 или UTF32), чтобы преобразовать каждый символ в последовательности из одного или нескольких байтов (для схем кодирования переменной длины, таких как UTF8 или UFT16) или последовательностей. фиксированной длины (в схемах кодирования постоянной длины, таких как UTF32). Как только у вас есть байтовый массив, закодируйте его в base64. - person Triynko; 07.08.2013
comment
Смотрите мою редакцию, @Triynko. Они не предназначены для обработки текста, точка. - person Shog9; 07.08.2013
comment
Хорошо, меня сбило с толку комментарий Дэна о том, что btoa и atob правильно работают только для строк ASCII. Эти функции, по сути, вообще не предназначены для работы с фактическими символьными строками, а скорее с байтовыми массивами, которые хранятся в строках, так что для каждого символа в строке вызов charCodeAt (i) всегда будет возвращать значение между 0 и 255. Я видел это раньше в классе JavaScript Base64, который сначала кодировал бы строку utf8 в другую строку (точно так, как описано, где каждый символ фактически представляет значение байта), а затем кодирует это значение base 64. - person Triynko; 07.08.2013
comment
Поэтому еще более эффективным методом было бы использование чего-то вроде этого (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. - person Triynko; 07.08.2013
comment
Вот полифилл github.com/davidchambers/Base64.js, лучше всего использовать собственные функции и polyfill, а не включать библиотеку, которая представляет новый API. - person Benjamin Gruenbaum; 18.03.2014
comment
И обратное к base64-декодированию строки UTF8, закодированной методом SET: decodeURIComponent (escape (window.atob (b64))); - person Stefan Steiger; 28.10.2014
comment
Для того, кто предложил это изменение: действительно не могу подчеркнуть, что вы не должны передавать произвольные строки в btoa(). Да, этот пример подойдет ... Но он вводит в заблуждение; широкие символы (допустимые в строковом литерале) могут вызвать проблемы. - person Shog9; 12.11.2015
comment
Для лучшего запоминания названий функций: btoa() равно b до до a fter, atob() is a fter < от b> до b до - person Dmitry Davydov; 10.04.2016
comment
Javascript - такой пьяный язык. atob означает буквенно-цифровое преобразование в base64, поэтому конечно на самом деле происходит наоборот. - person ; 14.07.2016
comment
двоичный, @Will. Буква b означает двоичный. Как те отрывочные телеконференции. - person Shog9; 14.07.2016
comment
да, но все же ... Он используется для преобразования строк в base64 ... любой непьяный кодировщик назвал бы его toBase64, поддержал бы unicode и затем пошел бы выпить. - person ; 14.07.2016
comment
Итак, вот где люди продолжают путаться здесь, @Will - его абсолютно не следует не использовать для преобразования строк во что-либо или из чего-либо, если только они не строки Base64 (также известные как alt.binaries - ›b ). Как видите, кодеры были не пьяны, а извращенцы. - person Shog9; 14.07.2016
comment
Он произносится как b to a и a to b, b означает двоичный код, а знак ASCII. - person Captain Hypertext; 03.02.2017
comment
Ввод / вывод должен быть допустимым ASCII, так как это обычное намерение Base64 @Captain. Ни при каких обстоятельствах не предполагайте, что вывод b действителен в любой текстовой кодировке, и не отправляйте текст, который не умещается в 8-битном формате, в функцию, ожидающую b. - person Shog9; 03.02.2017
comment
@ Shog9 Как указано в jpp < / a>, я хотел бы задать свой мета-вопрос и соответствующее редактирование ответа Санни Миленова вашему вниманию. Я надеюсь, что такой контакт с вами приемлем. - person T S; 17.07.2018
comment
Я постараюсь найти время, чтобы взглянуть на это, @TS, но имейте в виду, что многие ответы здесь делают дополнительные вещи, потому что, в отличие от исходного вопроса, они пытаются передать строки Unicode < / i> через системы, не поддерживающие Unicode ... И используя кодировку Base64 как часть этого процесса. Хотя это, безусловно, понятно, иногда возникают некоторые противоречивые (и ... плохо определенные) требования. - person Shog9; 18.07.2018
comment
Не уверен, почему это принятый или популярный ответ - он ничего не делает для спецификации Base64 OP. Вместо этого вы говорите OP вообще не использовать Base64. Есть и другие лучшие ответы, которые напрямую касаются положения Base64 вопроса OP. - person tpartee; 14.05.2021
comment
Конечно, @tpartee: ввод / вывод atob / btoa - это base64. Вот что означает «а» в этих сокращениях. Это достаточно просто, и я не думаю, что слишком много людей больше сбиваются с пути - их, кажется, бросает другая сторона: буква «b». Поскольку изначально в JavaScript не было байтовых массивов, эти функции определены таким образом, что двоичный ввод должен содержаться в строках, но, и я постоянно подчеркиваю это, они НЕ должны передаваться произвольными строками. Они не для этого и не этого ожидают. - person Shog9; 14.05.2021

Отсюда:

/**
*
*  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" открывает множество других вариантов. , это было первым.

person Sunny Milenov    schedule 29.10.2008
comment
Это также полезно, когда кодировка base64 нестандартна; в моем случае символ / не использовался, а знак? Вместо этого использовался символ, то есть даже в Chrome atob () не собирался декодировать входящие строки base64. - person Chris Moschini; 17.12.2011
comment
Будьте осторожны с этим кодом - он пытается интерпретировать вашу строку как строку в кодировке UTF-8. У нас был случай, когда у нас была двоичная строка (т.е. каждый символ в строке должен интерпретироваться как байт), и этот код действительно повредил данные. Прочти источник, Люк. - person Daniel Yankowsky; 12.11.2012
comment
Если вы используете код из webtoolkito info, не забывайте об авторских правах: / ** * * Кодирование / декодирование Base64 * webtoolkit.info * ** / - person Maciej Łopaciński; 13.12.2012
comment
Все, что необходимо для обеспечения безопасности большинства двоичных кодировок / декодирований, - это удалить сомнительный оператор string = string.replace(/\r\n/g,"\n"); в методе кодирования utf8. - person Marius; 04.01.2013
comment
Я бы использовал описанный выше метод с небольшим объемом данных. Для больших файлов лучше рассмотреть многостраничный POST, когда файл передается как двоичный. - person Sunny Milenov; 06.05.2013
comment
@Marius: Мне интересно, зачем они вообще включили string = string.replace(/\r\n/g,"\n");, лол. Это как о, давайте закодируем эту строку, но сначала почему бы нам просто случайно не нормализовать все разрывы строк без всякой уважительной причины. Это должно быть исключено из класса при любых обстоятельствах. - person Triynko; 07.08.2013
comment
Я знаю, что Base64 был предназначен для других целей и имеет накладные расходы 33%. Можно ли оптимизировать это для Интернета? Итак, когда у вас есть изображение со 100 байтами, оно сохраняется в строковой форме как 100 байтов вместо примерно 133 байтов? - person employee-0; 18.08.2013
comment
@Triynko, когда люди слепо внедряют решения отсюда, даже немного не проверяя, то они, вероятно, получают то, что заслуживают. (не совсем, я не против помогать людям, но я могу только надеяться, что они хотя бы прочитают эти комментарии!) - person Marius; 09.09.2013
comment
Я не гуру javascript, но этот код, похоже, содержит ошибку: если chr2 равно NaN, его значение все еще используется в операторе enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);. В моем браузере это работает нормально, NaN>>4 равно 0, но я не знаю, все ли браузеры это делают (также NaN/16 равно NaN). - person Jan; 16.12.2013
comment
@Triynko: Сегодня я обнаружил, что на меня повлияла та строчка, которая затирала \ r \ n в \ n. Мне определенно потребовалось время, чтобы заподозрить, что функция кодирования base 64 искажает мои строки! - person Johnny Kauffman; 18.03.2015
comment
input.charCodeAt(i++) всегда возвращает 65535 для символов от 128 (10000000) -255 (11111111) в IE9! - person Sen Jacob; 18.06.2015
comment
Заставить все сообщество использовать линейную сложность вместо постоянной (при декодировании) - довольно неортодоксальная вещь;) - person Géza Török; 12.09.2015
comment
добавьте .toString () для замены в функции _utf8_encode, потому что, если передается строка json, она вызовет исключение - person user889030; 26.03.2020
comment
Не работает с юникодом. Сделайте: Base64.encode (????), а затем расшифруйте его здесь: base64decode.org - person Nathan B; 14.03.2021
comment
совместимы по символам юникода :) - person milad shafiei; 01.06.2021

Internet Explorer 10+

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

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

// Decode the String
var decodedString = atob(encodedString);
console.log(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.log(encodedString); // Outputs: "SGVsbG8gV29ybGQh"

// Decode the String
var decodedString = Base64.decode(encodedString);
console.log(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=');
}]);
person davidcondrey    schedule 22.10.2014
comment
Этот ответ основан на исходном коде и НЕ включает обновления этого кода, опубликованные в других ответах здесь. - person Eugene Ryabtsev; 27.11.2014
comment
Предлагаемое решение NodeJS устарело. - person Vladimir Nul; 23.09.2019
comment
new Buffer() устарел, используйте вместо него Buffer.from() - person Ivan Rubinson; 06.08.2020

Код Санни великолепен, за исключением того, что он ломается в 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;
}
}
person user850789    schedule 18.07.2011
comment
о, моя беда, я получал ввод из URL-адреса браузера; где | конвертируется в% 7C; следовательно, кодировка тоже неправильная. - person Kanagavelu Sugumar; 11.09.2013
comment
Я знаю, что это действительно устарело, но я видел, что эта функция использовалась более чем в одном месте, строка ключа на самом деле состоит из 65 символов, а не 64. Строка не является стандартной спецификацией, я не уверен, что это имеет значение, но просто интересно если это так? - person Jonathan Wagner; 17.06.2015
comment
используйте строгий; это то, что ломает «this» и другие элементы типа, такие как «with», и, судя по тому, что я прочитал, «eval» подвергается критике. Все неуместные идеи о злоупотреблениях. Лично я не понимаю, почему JavaScript должен идти по пути своего продвижения, он никогда не задумывался как программа, сильно связанная и усложненная, чем она есть. Если вы хотите быть привязанными, создайте компилятор для javascript. - person Mark Giblin; 10.10.2015
comment
Я пытаюсь использовать эту функцию и получаю сообщение об ошибке: Причина: org.mozilla.javascript.EcmaError: TypeError: Не удается найти замену функции в объекте teste teste teste Я пытаюсь кодировать .txt с помощью teste teste teste. Кто-нибудь знает, почему эта ошибка? - person PRVS; 04.11.2015
comment
@JonathanWagner - для нормальной кодировки используется 64 символа. 65-й ​​символ используется в качестве дополнения к ним, входная строка не имеет количества символов, делящихся на 3. - person Kickstart; 05.09.2017

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

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

$.base64.encode("this is a test");
$.base64.decode("dGhpcyBpcyBhIHRlc3Q=");
person Vitalii Fedorenko    schedule 27.12.2011
comment
Почему все должно быть плагином jQuery: c это всего лишь основная функциональность JavaScript, не имеющая ничего общего с DOM или jQuery - person EaterOfCode; 29.04.2013
comment
Это не основная функциональность, иначе было бы не так много разных ответов с высокими оценками (включая самодельный код tl; dr). Итак, imho, на самом деле это хороший вариант использования jQuery (один лайнер, ожидается, что он будет работать даже в Android WebView) - даже больше, если он уже является зависимостью. - person Risadinha; 26.08.2013
comment
Я ушел и сдался. Подмножество jQuery должно быть формализовано и введено в стандарт JS как .net. Это некрасиво, но потребность огромна, и она пришла, чтобы управлять экосистемой. - person Lodewijk; 14.06.2014
comment
Мне нравится устанавливать такие фрагменты кода в jQuery главным образом потому, что они будут существовать в контролируемом пространстве имен. Если вы не используете AMD, CommonJS или аналогичный шаблон проектирования, ваше глобальное пространство имен может легко запутаться из-за кучи случайных функций. - person sffc; 25.06.2014
comment
w3schools.com/jsref/met_win_btoa.asp указывает на поддержку btoa для Chrome, IE10 +, Firefox. , сафари, опера - person OzBob; 22.07.2015
comment
Этот бизнес с глобальным пространством имен и использование фреймворков для выполнения небольших программ, идея пакета и JQuery написаны на JavaScript, ЭТО НЕ ЯВЛЯЕТСЯ JavaScript. Прочтите об atob () и btoa (), потому что вы обнаружите, что они не согласованы между типами браузеров. - person Mark Giblin; 10.10.2015
comment
@Risadinha - за исключением того, что его функциональность не зависит от чего-либо jQuery и не расширяет его ... буквально единственные ссылки на jQuery в его коде прикрепляют его к объекту jQuery ... так какой смысл прикреплять его к jQuery и, следовательно, требовать jQuery использовать? Просто сделайте его собственным 1 лайнером base64.encode(...) и base64.decode(...) ... прикреплять его к jQuery, когда у него нет специфических функций jQuery, не имеет абсолютно никакого смысла ... - person Jimbo Jonny; 12.03.2016
comment
jQuery не запрашивался. Не верный ответ на простой старый вопрос JS. - person metaColin; 11.02.2017

Из комментариев (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>

person crashwap    schedule 23.08.2017
comment
Подтверждаю, что это поддерживает символы UTF-8? - person Crashalot; 03.02.2018
comment
@Crashalot Я понимаю, что это на два года слишком поздно, но да, это так. Когда я набираю это, я также просто понимаю, что вы предоставили правку, которая, возможно, заставила UTF8 работать. - person tycrek; 05.04.2020
comment
Для всех, кто здесь ищет хорошее решение для использования с Node.js, я могу подтвердить, что это работает. Для декодирования в Node я использовал: Buffer.from(b64data, 'base64').toString(); - person tycrek; 05.04.2020
comment
Может кто-нибудь объяснить, что unescape и escape делают в этом снятом решении? - person Sammi; 16.09.2020

В обеих реализациях _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;
}
person robbles    schedule 26.07.2011
comment
@Daan У меня не было достаточно репутации, чтобы редактировать ответы, когда я писал этот ответ ... в 2011 году. - person robbles; 10.12.2013
comment
IE7? Я думаю, нам следует перестать тратить время на написание кода для этого, люди не перестанут использовать эту старую технологию, если мы, разработчики, их не заставим! - person Rami Dabain; 07.06.2014
comment
@RonanDejhero не работает в IE7? Я не помню, тестировал ли я в этом конкретном браузере. - person robbles; 09.06.2014
comment
Я имел в виду, что если он не работает в IE7, никого не волнует !. я не тестировал и тестировать не буду :) - person Rami Dabain; 09.06.2014

Я добавил +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
    };
}());
person Joe Dyndale    schedule 20.08.2012
comment
Сначала я думал, что развертывание выходной конкатенации в отдельные операторы будет более оптимальным, но после того, как я подумал об этом на секунду, этот должен быть более неэффективным, поскольку строки Javascript неизменяемы, и это вызовет 4 копии потенциально огромных больших двоичных объектов данных при работе с большими двоичными файлами данных. Более безопасный вариант - сначала объединить 4 символа вместе, а затем построить новую строку. Хотел бы я знать наверняка о лучшем методе построения струн, который был бы эффективен на всех платформах. (даже IE6) - person Marius; 04.01.2013
comment
Я не рассматривал производительность при очистке первоначально опубликованного кода. Я просто сделал его более читабельным и сделал методы, отмеченные как частные в комментариях в оригинале, на самом деле частными, используя шаблон модуля раскрытия. Я уверен, что его можно оптимизировать и с точки зрения производительности. Не совсем уверен, когда здесь начнется сборка мусора, а хеширование больших файлов с помощью Javascript не очень распространено (или, скорее всего, не является оптимальным решением в любом случае). - person Joe Dyndale; 07.01.2013
comment
Забавно, как здесь живет этот код. На этой странице уже есть 3 разные версии. - person gregn3; 07.03.2014

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

Непосредственно из 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?), Это должно быть хорошим решением.

person John    schedule 03.11.2016
comment
Это из MDN? - person 1.21 gigawatts; 13.06.2020
comment

Чтобы новые браузеры кодировали 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')
};
person Rix    schedule 09.11.2018
comment
не хорошо. ошибочный. - person mmm; 31.12.2020

Чтобы сделать строковый 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/

person magikMaker    schedule 21.08.2011
comment
Я бы смиренно предположил, что использование encodeURIComponent может привести к превосходному результату с меньшими затратами усилий со стороны разработчика. - person Pablo Fernandez; 28.10.2011
comment
encodeURIComponent изменит длину строк в кодировке base64, а замена '-' и '_' на '+' и '/' является стандартной практикой при использовании base64 в URL-адресах (например, docs.python.org/library/base64.html#base64.urlsafe_b64encode). Не нужно расстраиваться. - person natevw; 22.12.2011

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

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

var encodedData = window.btoa(stringToEncode);

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

var decodedData = window.atob(encodedData);

person Kathir    schedule 04.02.2013
comment
Прямая ссылка на раздел Unicode: developer.mozilla.org / en-US / docs / Web / API / - person TomTasche; 25.01.2020

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

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

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

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

utf8.encode(/* String */);
utf8.decode(/* String */);
person Nijikokun    schedule 19.03.2013

если вам нужно закодировать объект изображения 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));  
} 

подробнее здесь

person Nedudi    schedule 12.01.2013
comment
Ага, и var img = new Image (); img.src = ../images/myPic.png; - person pdschuller; 10.12.2013

Внесение вклада с минифицированным полифилом для 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})})();
person Johan    schedule 20.11.2013

Мне нужна была кодировка строки 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/).

person Ricardo Machado    schedule 04.10.2014
comment
Это отличная работа! Но вместо return digits [value] он должен возвращать digits.substr (value, 1) в функции emitBase64 (). Beosis error / Спотыкается о эмодзи и многобайтовых символах. Но он часто кодирует то, что онлайн-декодеры не могут декодировать! Этот код без проблем выводил базовую кириллицу. - person Garric; 28.04.2021

Если вы используете Node.js, вы можете сделать это:

let a = Buffer.from('JavaScript').toString('base64');
console.log(a);

let b = Buffer.from(a, 'base64').toString();
console.log(b);
person qux    schedule 07.03.2021
comment
Это только для Node.js, а не для JavaScript в браузере. - person Crashalot; 26.06.2021
comment
Ты прав. Извините, я только что тестировал на Node.js. - person qux; 27.06.2021

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

person Dan Dascalescu    schedule 17.11.2013

Вот версия @ 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;
});
person A T    schedule 25.05.2014

В моем проекте мне все еще нужно поддерживать 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("");
};
person Nico    schedule 24.07.2013

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

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

Однако вам может потребоваться дополнительная обработка для urldecode данных, поскольку я не уверен, экранируются ли символы + или нет для URL data://, но это должно быть довольно тривиально.

person Malvineous    schedule 21.07.2016

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

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

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

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

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

var bytes = dojox.encoding.base64.decode(str);
person Vikash Pandey    schedule 29.08.2013

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

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!"
person Alireza    schedule 15.10.2018

Вот LIVE DEMO построенных 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>
person jonathana    schedule 09.02.2019

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

btoa () не работает со смайликами

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

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

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

person Shivaji Mutkule    schedule 18.03.2020

Когда я использую

btoa("☸☹☺☻☼☾☿"))

Я получаю сообщение об ошибке InvalidCharacterError: кодируемая строка содержит символы вне диапазона Latin1.

Я нашел документацию

https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/btoa#unicode_strings

было предоставлено решение, как показано ниже

function toBinary(string) {
  const codeUnits = new Uint16Array(string.length);
  for (let i = 0; i < codeUnits.length; i++) {
    codeUnits[i] = string.charCodeAt(i);
  }
  return String.fromCharCode(...new Uint8Array(codeUnits.buffer));
}

function fromBinary(binary) {
  const bytes = new Uint8Array(binary.length);
  for (let i = 0; i < bytes.length; i++) {
    bytes[i] = binary.charCodeAt(i);
  }
  return String.fromCharCode(...new Uint16Array(bytes.buffer));
}

const myString = "☸☹☺☻☼☾☿"
// console.log(btoa(myString)) // Error InvalidCharacterError: The string to be encoded contains characters outside of the Latin1 range.
const converted = toBinary(myString)
const encoded = btoa(converted)
console.log(encoded)

const decoded = atob(encoded)
const original = fromBinary(decoded)
console.log(original);

person Carson    schedule 06.05.2021
comment
Я просто копирую и вставляю, чтобы помочь людям, которые не хотят переходить по ссылке ... - person Carson; 06.05.2021

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

person Vladimir Ignatyev    schedule 21.06.2020

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>

person Kamil Kiełczewski    schedule 27.07.2020