How can you encode a string to Base64 in JavaScript?

前端 未结 26 3883
梦如初夏
梦如初夏 2020-11-21 04:02

I have a PHP script that can encode a PNG image to a Base64 string.

I\'d like to do the same thing using JavaScript. I know how to open files, but I\'m not sure how

相关标签:
26条回答
  • 2020-11-21 04:45

    You can use btoa() and atob() to convert to and from base64 encoding.

    There appears to be some confusion in the comments regarding what these functions accept/return, so…

    • btoa() accepts a “string” where each character represents an 8-bit byte – if you pass a string containing characters that can’t be represented in 8 bits, it will probably break. This isn’t a problem if you’re actually treating the string as a byte array, but if you’re trying to do something else then you’ll have to encode it first.

    • atob() returns a “string” where each character represents an 8-bit byte – that is, its value will be between 0 and 0xff. This does not mean it’s ASCII – presumably if you’re using this function at all, you expect to be working with binary data and not text.

    See also:

    • How do I load binary image data using Javascript and XMLHttpRequest?
    0 讨论(0)
  • 2020-11-21 04:45

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

    Cross-Browser

    // 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


    with Node.js

    Here is how you encode normal text to base64 in 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');
    

    And here is how you decode base64 encoded strings:

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

    with Dojo.js

    To encode an array of bytes using dojox.encoding.base64:

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

    To decode a base64-encoded string:

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

    bower install 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=');
    }]);
    
    0 讨论(0)
  • 2020-11-21 04:45

    There's a couple of bugs in both implementations of _utf8_decode. c1 and c2 are assigned as global variables due to broken use of the var statement, and c3 is not initialized or declared at all.

    It works, but these variables will overwrite any existing ones with the same name outside this function.

    Here's a version that won't do this:

    // 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;
    }
    
    0 讨论(0)
  • 2020-11-21 04:46

    Well, if you are using dojo, it gives us direct way to encode or decode into base64.

    Try this:-

    To encode an array of bytes using dojox.encoding.base64:

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

    To decode a base64-encoded string:

    var bytes = dojox.encoding.base64.decode(str);
    
    0 讨论(0)
  • 2020-11-21 04:48

    Here is an AngularJS Factory version of @user850789's one:

    '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;
    });
    
    0 讨论(0)
  • 2020-11-21 04:49

    This question and it's answers pointed me to the right direction.
    Especially with unicode atob and btoa can not be used "vanilla" and these days EVERYTHING is unicode ..

    Directly from Mozilla, two nice functions for this purpose (tested with unicode and html tags inside)

    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"
    

    These functions will perform lightning fast in comparison to raw base64 decoding using a custom javascript function as btoa and atob are executed outside the interpreter.

    If you can ignore old IE and old mobile phones (like iphone 3?) this should be a good solution.

    0 讨论(0)
提交回复
热议问题