如何在JavaScript中将字符串编码为Base64?

use*_*ame 745 javascript base64

我有一个PHP脚本,可以将PNG图像编码为Base64字符串.

我想用JavaScript做同样的事情.我知道如何打开文件,但我不知道如何进行编码.我不习惯使用二进制数据.

Sho*_*og9 788

您可以使用btoa()atob()转换为base64编码.

关于这些功能接受/返回的评论似乎有些混乱,所以...

  • btoa()接受一个"字符串",其中每个字符代表一个8位字节 - 如果你传递一个包含无法用8位表示的字符的字符串,它可能会中断.如果您实际将字符串视为字节数组,这不是问题,但如果您尝试执行其他操作,则必须先对其进行编码.

  • atob()返回一个"字符串",其中每个字符代表一个8位字节 - 也就是说,它的值将在0和之间0xff.但这并不意味着它是ASCII -大概,如果您使用此功能在所有的,你还指望用二进制数据,而不是文字来工作.

也可以看看:

  • 你应该使用`btoa(unescape(encodeURIComponent(str))))`如果str是UFT8 (62认同)
  • 请注意,这也适用于Webkit浏览器,例如Safari. (47认同)
  • 请注意Unicode字符串的特殊注意事项:https://developer.mozilla.org/En/DOM/Window.btoa#Unicode_Strings btoa和atob仅适用于基于ASCII的字符串.作为美国人,你可能不会注意到差异......但是第一次使用重音字符时,你的代码就会破裂. (25认同)
  • 但它不适用于iOS3的iPhone3G.当设置为iPhone4或iPhone时,它可以在模拟器iPhone模拟器上运行. (5认同)
  • 看我的编辑@Triynko.这些不打算用于处理*text*,period. (4认同)
  • 为了更好地记住函数的名称:`btoa()`****************a*fter,`atob()`**************之前 (4认同)
  • 是的,但仍然......它用于将字符串转换为 base64......任何非醉酒的编码员都会称它为 `toBase64`,会支持 unicode,并且会 *then* 出去喝酒。 (4认同)
  • 如果这些函数仅支持 ascii 字符串,那么根本不应该使用它们。时期。您使用 Base 64 编码字节数组,而不是字符数组(即字符串)。字符串是逻辑字符数组,而不是字节数组。字符数组需要首先通过选择字符编码(UTF8、UTF16 或 UTF32)将字符数组转换为字节数组,将每个字符转换为一个或多个字节的序列(对于 UTF8 或 UFT16 等可变长度编码方案)或序列固定长度(在恒定长度编码方案中,例如 UTF32)。获得字节数组后,对其进行 Base64 编码。 (3认同)
  • 这是一个polyfill https://github.com/davidchambers/Base64.js,最好使用本机函数和polyfill,而不是包含一个引入新API的库. (3认同)
  • 二进制,@ Will.b代表"二进制".像那些粗略的新闻组. (3认同)
  • 它的发音是"b到a"和"a到b",b代表二进制,代表ASCII (3认同)
  • 提供此函数只是为了与旧版 Web 平台 API 兼容,并且永远不应在新代码中使用,因为它们使用字符串来表示二进制数据,并且早于 JavaScript 中类型化数组的引入。对于使用 Node.js API 运行的代码,应使用 Buffer.from(str, 'base64') 和 buf.toString('base64') 执行 base64 编码字符串和二进制数据之间的转换。 (3认同)
  • @YuriAps,不幸的是,您的评论没有增加任何价值,您指的是浏览器端功能并说不应该使用它们,那么您提供的替代品是浏览器中不存在的服务器端功能! (3认同)
  • 而与base64解码相反的是,按SET方法编码的UTF8字符串:decodeURIComponent(escape(window.atob(b64))); (2认同)
  • 对于谁建议[这个编辑](http://stackoverflow.com/review/suggested-edits/10172482):真的不能强调你不应该将任意字符串传递给`btoa()`.是的,那个例子可行......但它有误导性; 宽字符(字符串文字合法)会导致问题. (2认同)
  • Javascript是一种醉酒的语言。“ atob”似乎代表“ base64的字母数字”,因此*当然*实际上却相反。 (2认同)
  • 所以,这就是人们在这里一直感到困惑的地方,@Will - 它绝对不应该用于将字符串与任何内容相互转换,除非它们是 Base64 的字符串(又名 alt.binaries ->“b”)。正如你所看到的,程序员们并没有喝醉,只是有点变态。 (2认同)

Sun*_*nov 286

从这里:

/**
*
*  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;
}

}
Run Code Online (Sandbox Code Playgroud)

此外,搜索"javascript base64 encoding"会转换很多其他选项,上面是第一个.

  • 请小心这段代码 - 它会尝试将您的字符串解释为UTF-8编码的字符串.我们遇到了一个二进制字符串的情况(即字符串中的每个字符都应该被解释为一个字节),而这段代码确实破坏了数据.阅读来源,卢克. (21认同)
  • 所有这一切都需要使大多数二进制编码/解码安全,它删除了utf8编码方法中有问题的`string = string.replace(/\r \n/g,"\n");`语句. (11认同)
  • 这适用于**<input type ="file"/>**HTML表单? (9认同)
  • @Marius:我想知道为什么他们甚至会包括`string = string.replace(/\r \n/n/g,"\n");``首先,lol.这就像"哦,让我们编码这个字符串,但首先,为什么我们不能随便将所有换行符随机归一化".在任何情况下都应该完全从班级中删除. (6认同)
  • 当base64编码是非标准时,这也很有用; 在我的情况下,没有使用"/"字符和"?" 改为使用了字符,这意味着即使在Chrome中,atob()也不会解码传入的base64字符串. (3认同)
  • 如果您使用来自 webtoolkito 信息的代码,请不要忘记版权:/** * * Base64 编码/解码 * http://www.webtoolkit.info/ * **/ (2认同)
  • 我不是javascript大师,但这段代码似乎包含一个错误:如果chr2是NaN,它的值仍然用在语句`enc2 =((chr1&3)<< 4)| (chr2 >> 4);`.在我的浏览器中,这可以正常,"NaN >> 4"等于0,但我不知道是否所有浏览器都这样做(同样,"NaN/16"等于NaN). (2认同)

dav*_*rey 111

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!"
Run Code Online (Sandbox Code Playgroud)

跨浏览器

// 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!"
Run Code Online (Sandbox Code Playgroud)

的jsfiddle


与Node.js

以下是在Node.js中将普通文本编码为base64的方法:

//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');
Run Code Online (Sandbox Code Playgroud)

以下是解码base64编码字符串的方法:

var b = new Buffer('SmF2YVNjcmlwdA==', 'base64')
var s = b.toString();
Run Code Online (Sandbox Code Playgroud)

与Dojo.js

使用dojox.encoding.base64编码字节数组:

var str = dojox.encoding.base64.encode(myByteArray);
Run Code Online (Sandbox Code Playgroud)

要解码base64编码的字符串:

var bytes = dojox.encoding.base64.decode(str)
Run Code Online (Sandbox Code Playgroud)

凉亭安装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=');
}]);
Run Code Online (Sandbox Code Playgroud)

  • `new Buffer()` 已弃用,请使用 `Buffer.from()` 代替 (4认同)
  • 此答案基于原始代码,并且不包括此处其他答案中发布的代码更新. (3认同)

小智 94

Sunny的代码很棒,除非它在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;
}
}
Run Code Online (Sandbox Code Playgroud)

  • 哦,我的坏,我从浏览器URL获取输入; 哪里| 转换为%7C; 因此编码也错了. (4认同)

Vit*_*nko 89

您可以使用btoa(to base-64)和atob(from base-64).

对于IE 9及更低版本,请尝试使用jquery-base64插件:

$.base64.encode("this is a test");
$.base64.decode("dGhpcyBpcyBhIHRlc3Q=");
Run Code Online (Sandbox Code Playgroud)

  • 为什么一切都需要成为jQuery插件:c这只是核心JavaScript功能,这与DOM或jQuery无关 (130认同)
  • 这不是一个核心功能,或者没有那么多不同的高投票答案(包括自己动手tl; dr代码).所以,imho这实际上是jQuery的一个很好的用例(一个衬里,预计甚至可以在Android的WebView中工作) - 如果它已经是依赖,那就更好了. (38认同)
  • @Risadinha - 除了它的功能根本不依赖于或扩展任何jQuery ...字面上在其代码中对jQuery的唯一引用是将它附加到jQuery对象...所以将它附加到jQuery有什么意义,因此需要使用jQuery?只是让它自己的1个衬里`base64.encode(...)`和`base64.decode(...)`...当它具有零jQuery特定功能时将它附加到jQuery使得绝对没有意义...... (9认同)

cra*_*wap 27

从接受的答案下面的评论(由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)));
Run Code Online (Sandbox Code Playgroud)

演示

(使用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);
});
Run Code Online (Sandbox Code Playgroud)
#btnDeConv{display:none;}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • 有人可以解释一下“unes​​cape”和“escape”在这个解决方案中正在做什么吗? (2认同)
  • 对于前端:我注意到“btoa”和“unes​​cape”和“escape”都被标记为已折旧。这有更多信息:/sf/ask/4819446341/ &amp; /sf/answers/1954864551/ (2认同)

rob*_*les 26

在两种实现方式中都存在一些错误_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;
}
Run Code Online (Sandbox Code Playgroud)

  • @Daan我在2011年写这个答案时没有足够的代表来编辑答案. (9认同)
  • IE7?我想我们应该停止浪费时间为此编写代码,除非开发人员强迫他们使用,否则人们不会停止使用这种旧技术! (2认同)

Joe*_*ale 16

我给了Sunny的回答,但是我想回馈一些我为自己的项目做出的改变,以防任何人发现它有用.基本上我只是稍微清理了原始代码,所以JSLint并没有那么多抱怨,而且我在评论中标记为私有的方法实际上是私有的.我还在我自己的项目中添加了两个方法,即decodeToHexencodeFromHex.

代码:

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
    };
}());
Run Code Online (Sandbox Code Playgroud)


qux*_*qux 14

如果你使用 Node.js,你可以这样做:

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

let b = Buffer.from(a, 'base64').toString();
console.log(b);
Run Code Online (Sandbox Code Playgroud)


mag*_*ker 13

要使Base64编码的String URL友好,在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, '/');
Run Code Online (Sandbox Code Playgroud)

另见这个小提琴:http://jsfiddle.net/magikMaker/7bjaT/

  • encodeURIComponent将改变base64编码字符串的长度,在URL中使用base64时,将' - '和'_'替换为'+'和'/'是标准做法(例如http://docs.python.org/library/base64的.html#base64.urlsafe_b64encode).无需心烦意乱. (11认同)
  • 我谦卑地建议使用`encodeURIComponent`可能会带来更好的结果,而且开发人员的工作量也会减少. (9认同)

Nij*_*kun 12

我已经手工重写了这些编码和解码方法,除了十六进制之外的模块化格式,用于跨平台/浏览器兼容性以及真正的私有范围,并且使用btoa并且atob如果它们存在则由于速度而不是利用它自己的编码:

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

用法:

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

utf8.encode(/* String */);
utf8.decode(/* String */);
Run Code Online (Sandbox Code Playgroud)


Joh*_*ohn 12

这个问题及其答案向我指出了正确的方向.
特别是使用unicode atob和btoa不能使用"香草",而这些天一切都是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"
Run Code Online (Sandbox Code Playgroud)

与使用自定义javascript函数的原始base64解码相比,这些函数将执行闪电,因为btoa和atob在解释器外执行.

如果你可以忽略旧的IE和旧的手机(如iphone 3?),这应该是一个很好的解决方案.

  • 这个答案拯救了我的理智。有关其他信息 - 使用“b64EncodeUnicode()”后,您可以在 PHP 中对结果字符串安全地使用“base64_decode()”。 (3认同)
  • https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/btoa (2认同)

Kat*_*hir 11

请注意,这不适用于原始Unicode字符串!请参阅此处的 Unicode部分.

编码语法

var encodedData = window.btoa(stringToEncode);

解码语法

var decodedData = window.atob(encodedData);


Ned*_*udi 10

如果你需要编码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
}  
Run Code Online (Sandbox Code Playgroud)

要通过id获取base64的图像:

function getBase64ImageById(id){  
  return getBase64Image(document.getElementById(id));  
} 
Run Code Online (Sandbox Code Playgroud)

更多在这里


Rix*_*Rix 10

对于较新的浏览器,将Uint8Array编码为字符串,并将字符串解码为Uint8Array.

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

对于Node.js,您可以使用以下命令将string,Buffer或Uint8Array编码为string,并从string,Buffer或Uint8Array解码为Buffer.

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


Dav*_*ido 10

2022 年弃用警告更新

我在 vscode 上看到弃用警告

This function is only provided for compatibility with legacy web platform APIs and should never be used in new code, 
because they use strings to represent binary data and predate the introduction of typed arrays in JavaScript. 
For code running using Node.js APIs, 
converting between base64-encoded strings and binary data should be performed using Buffer.from(str, 'base64') andbuf.toString('base64').
Run Code Online (Sandbox Code Playgroud)

经过更多搜索后,我发现这个问题说它没有被弃用

https://github.com/microsoft/TypeScript/issues/45566

所以web JS上弃用警告的解决方案,使用window.btoa 后警告就会消失。


Joh*_*han 7

使用缩小的polyfill为我正在使用的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})})();
Run Code Online (Sandbox Code Playgroud)


Dan*_*scu 6

我宁愿使用CryptoJS的bas64编码/解码方法,CryptoJS是使用最佳实践和模式在JavaScript中实现的标准和安全加密算法的最流行的库.


A T*_*A T 6

这是@ 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;
});
Run Code Online (Sandbox Code Playgroud)


小智 6

我需要将UTF-8字符串编码为我的项目的base64.这里的大部分答案在转换为UTF-8时似乎没有正确处理UTF-16代理对,所以为了完成起见,我将发布我的解决方案:

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('');
}
Run Code Online (Sandbox Code Playgroud)

请注意,代码未经过全面测试.我测试了一些输入,包括类似的东西,strToUTF8Base64('????')并与在线编码工具(https://www.base64encode.org/)的输出进行比较.


Ali*_*eza 6

您可以使用window.btoawindow.atob...

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

可能使用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!"
Run Code Online (Sandbox Code Playgroud)


jon*_*ana 6

这里有一个现场演示atob()btoa()JavaScript的内置函数:

<!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>
Run Code Online (Sandbox Code Playgroud)


Shi*_*ule 6

使用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);
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdn.jsdelivr.net/npm/js-base64@2.5.2/base64.min.js"></script>
Run Code Online (Sandbox Code Playgroud)


小智 5

对于我的项目,我仍然需要支持IE7并使用大量输入进行编码。

根据Joe Dyndale提出的代码以及Marius的评论中的建议,可以通过使用数组而不是字符串构造结果来提高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("");
};
Run Code Online (Sandbox Code Playgroud)


Vik*_*dey 5

好吧,如果您使用的是dojo,它为我们提供了直接编码或解码为base64的方法。

尝试这个:-

要使用dojox.encoding.base64编码字节数组:

var str = dojox.encoding.base64.encode(myByteArray);
Run Code Online (Sandbox Code Playgroud)

要解码base64编码的字符串:

var bytes = dojox.encoding.base64.decode(str);
Run Code Online (Sandbox Code Playgroud)


Mal*_*ous 5

尽管还有更多工作要做,但是如果您需要高性能的本机解决方案,则可以使用一些HTML5函数。

如果您可以将数据放入Blob,则可以使用FileReader.readAsDataURL()函数获取一个data://URL,然后将其切掉以获取base64数据。

但是,您可能需要做进一步的处理才能对数据+进行data://url 解码,因为我不确定URL 是否对字符进行了转义,但这应该很简单。


Car*_*ard 5

当我使用

\n
btoa("\xe2\x98\xb8\xe2\x98\xb9\xe2\x98\xba\xe2\x98\xbb\xe2\x98\xbc\xe2\x98\xbe\xe2\x98\xbf"))\n
Run Code Online (Sandbox Code Playgroud)\n

我得到:

\n
\n

错误 InvalidCharacterError:要编码的字符串包含Latin1 范围之外的字符。

\n
\n

我发现文档Unicode strings提供了如下解决方案。

\n

\r\n
\r\n
function toBinary(string) {\n  const codeUnits = new Uint16Array(string.length);\n  for (let i = 0; i < codeUnits.length; i++) {\n    codeUnits[i] = string.charCodeAt(i);\n  }\n  return String.fromCharCode(...new Uint8Array(codeUnits.buffer));\n}\n\nfunction fromBinary(binary) {\n  const bytes = new Uint8Array(binary.length);\n  for (let i = 0; i < bytes.length; i++) {\n    bytes[i] = binary.charCodeAt(i);\n  }\n  return String.fromCharCode(...new Uint16Array(bytes.buffer));\n}\n\nconst myString = "\xe2\x98\xb8\xe2\x98\xb9\xe2\x98\xba\xe2\x98\xbb\xe2\x98\xbc\xe2\x98\xbe\xe2\x98\xbf"\n// console.log(btoa(myString)) // Error InvalidCharacterError: The string to be encoded contains characters outside of the Latin1 range.\nconst converted = toBinary(myString)\nconst encoded = btoa(converted)\nconsole.log(encoded)\n\nconst decoded = atob(encoded)\nconst original = fromBinary(decoded)\nconsole.log(original);
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n