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

IT技术 javascript base64 binaryfiles
2021-01-14 19:48:54

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

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

6个回答

您可以使用btoa()atob()与 base64 编码相互转换。

关于这些函数接受/返回什么的评论似乎有些混乱,所以......

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

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

也可以看看:


这里的大多数评论都已过时。除非您支持非常过时的浏览器,否则您可能可以同时使用btoa()atob()

检查这里:

请参阅我的编辑,@Triynko。这些不打算用于处理文本,句点。
2021-03-13 19:48:54
请注意 Unicode 字符串的特殊考虑:developer.mozilla.org/En/DOM/Window.btoa#Unicode_Strings btoa 和 atob 仅适用于基于 ASCII 的字符串。作为美国人,您可能不会注意到有什么不同……但是当您第一次使用带重音的字符时,您的代码就会出错。
2021-03-24 19:48:54
请注意,这也适用于 webkit 浏览器,例如 Safari。
2021-03-28 19:48:54
btoa(unescape(encodeURIComponent(str))))如果 str 是 UFT8,您应该使用
2021-04-04 19:48:54
它的发音是b to aand a to b,b 代表二进制,a 代表 ASCII
2021-04-07 19:48:54

从这里

/**
*
*  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 encoding”会出现很多其他选项,上面是第一个。

@Marius:我想知道为什么他们甚至string = string.replace(/\r\n/g,"\n");首先要包括在内,哈哈。就像“哦,让我们对这个字符串进行编码,但首先,我们为什么不无缘无故地随机标准化所有换行符”。在任何情况下,都绝对应该将其从课程中删除。
2021-03-13 19:48:54
这在 base64 编码非标准时也很有用;在我的情况下,没有使用“/”字符,而“?” 字符被改为使用,这意味着即使在 Chrome atob() 中也不会解码传入的 base64 字符串。
2021-03-15 19:48:54
所有需要使其对大多数二进制编码/解码安全以删除string = string.replace(/\r\n/g,"\n");utf8 编码方法中的可疑语句。
2021-03-31 19:48:54
请注意此代码 - 它会尝试将您的字符串解释为 UTF-8 编码的字符串。我们有一个例子,我们有一个二进制字符串(即字符串中的每个字符都应该被解释为一个字节),而这段代码确实破坏了数据。阅读来源,卢克。
2021-04-02 19:48:54
如果您使用来自 webtoolkito 信息的代码,请不要忘记版权:/** * * Base64 编码/解码 * webtoolkit.info * **/
2021-04-05 19:48:54

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!"

js小提琴


使用 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.
// The 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=');
}]);
此答案基于原始代码,不包括对此处其他答案中发布的该代码的更新。
2021-03-25 19:48:54
建议的 NodeJS 解决方案已被弃用。
2021-03-27 19:48:54
new Buffer()已弃用,请Buffer.from()改用
2021-04-02 19:48:54

Sunny 的代码很棒,只是它在 Internet Explorer 7 中由于对“this”的引用而中断。通过用“Base64”替换这些引用来修复它:

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

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

        input = Base64._utf8_encode(input);

        while (i < input.length) {

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

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

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

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

        return output;
    },

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

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

        while (i < input.length) {

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

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

            output = output + String.fromCharCode(chr1);

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

        output = Base64._utf8_decode(output);

        return output;
    },

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

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

            var c = string.charCodeAt(n);

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

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

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }
        }
        return string;
    }
}
哦,糟糕,我正在从浏览器 URL 获取输入;哪里| 转换为 %7C;因此编码也是错误的。
2021-03-14 19:48:54
我尝试使用此函数,但收到错误:由以下原因引起:org.mozilla.javascript.EcmaError:TypeError:无法在对象 teste teste teste 中找到函数替换我正在尝试使用“teste teste teste”对 .txt 进行编码。有谁知道为什么会出现这个错误?
2021-03-23 19:48:54
我知道这真的很旧,但我在不止一个地方看到过这个函数,关键字符串实际上是 65 个字符,而不是 64 个。该字符串不是标准规范,我不确定它是否重要,但只是想知道如果它呢?
2021-03-29 19:48:54
“严格使用”;是什么打破了“this”和其他类型元素,如“with”,从我读到的内容来看,“eval”受到了抨击。所有关于滥用的错误想法。就我个人而言,我不明白为什么 JavaScript 需要沿着它的路线走下去,它从来就不是一个紧密绑定的程序,而且比现在更复杂。如果你想被绑定,那么为 javascript 制作一个编译器。
2021-04-04 19:48:54
@JonathanWagner - 有 64 个字符用于正常编码。第 65 个字符用作填充它们,输入字符串没有可被 3 整除的字符数。
2021-04-06 19:48:54

您可以使用btoa(到 Base64)和atob(从 Base64)。

对于 Internet Explorer 9 及以下版本,请尝试使用jquery-base64插件:

$.base64.encode("this is a test");
$.base64.decode("dGhpcyBpcyBhIHRlc3Q=");
我喜欢将这样的代码片段安装到 jQuery 中,主要是因为它们将存在于受控命名空间中。如果你没有使用 AMD 或 CommonJS 或类似的设计模式,你的全局命名空间很容易被一堆随机函数弄得非常混乱。
2021-03-11 19:48:54
@Risadinha - 除了它的功能根本不依赖或扩展任何 jQuery ...使用jQuery?只需让它成为自己的 1 个班轮,base64.encode(...)然后base64.decode(...)......当它具有零 jQuery 特定功能时将它附加到 jQuery 绝对没有意义......
2021-03-13 19:48:54
这不是核心功能,或者不会有那么多不同的高票答案(包括自己动手做的 tl;dr 代码)。所以,恕我直言,这实际上是 jQuery 的一个很好的用例(一个 liner,预计甚至可以在 Android 的 WebView 中工作) - 如果它已经是一个依赖项,那就更多了。
2021-03-23 19:48:54
为什么一切都需要成为 jQuery 插件:c 这只是 JavaScript 的核心功能,与 DOM 或 jQuery 无关
2021-04-04 19:48:54
未请求 jQuery。不是一个简单的老 JS 问题的有效答案。
2021-04-04 19:48:54