我使用Javascript window.atob()函数来解码base64编码的字符串(特别是来自GitHub API的base64编码的内容)。问题是我得到ascii编码的字符返回(如âⅱ而不是™)。我如何正确地处理传入的base64编码流,以便将其解码为utf-8?


当前回答

如果试图解码节点中utf8编码数据的Base64表示,您可以使用本机Buffer helper

Buffer.from("4pyTIMOgIGxhIG1vZGU=", "base64").toString(); // '✓ à la mode'

Buffer的toString方法默认为utf8,但您可以指定任何所需的编码。例如,相反的操作是这样的

Buffer.from('✓ à la mode', "utf8").toString("base64"); // "4pyTIMOgIGxhIG1vZGU="

其他回答

这是我的一行程序解决方案,结合了Jackie Hans的答案和另一个问题的一些代码:

const utf8_encoded_text = new TextDecoder().decode(Uint8Array.from(window.atob(base_64_decoded_text).split("").map(x => x.charCodeAt(0))));

下面是一些面向可能缺少escape/unescape()的浏览器的面向未来的代码。请注意,ie9及以上版本不支持atob/btoa(),因此您需要为它们使用自定义base64函数。

// Polyfill for escape/unescape
if( !window.unescape ){
    window.unescape = function( s ){
        return s.replace( /%([0-9A-F]{2})/g, function( m, p ) {
            return String.fromCharCode( '0x' + p );
        } );
    };
}
if( !window.escape ){
    window.escape = function( s ){
        var chr, hex, i = 0, l = s.length, out = '';
        for( ; i < l; i ++ ){
            chr = s.charAt( i );
            if( chr.search( /[A-Za-z0-9\@\*\_\+\-\.\/]/ ) > -1 ){
                out += chr; continue; }
            hex = s.charCodeAt( i ).toString( 16 );
            out += '%' + ( hex.length % 2 != 0 ? '0' : '' ) + hex;
        }
        return out;
    };
}

// Base64 encoding of UTF-8 strings
var utf8ToB64 = function( s ){
    return btoa( unescape( encodeURIComponent( s ) ) );
};
var b64ToUtf8 = function( s ){
    return decodeURIComponent( escape( atob( s ) ) );
};

一个更全面的UTF-8编码和解码的例子可以在这里找到:http://jsfiddle.net/47zwb41o/

如果试图解码节点中utf8编码数据的Base64表示,您可以使用本机Buffer helper

Buffer.from("4pyTIMOgIGxhIG1vZGU=", "base64").toString(); // '✓ à la mode'

Buffer的toString方法默认为utf8,但您可以指定任何所需的编码。例如,相反的操作是这样的

Buffer.from('✓ à la mode', "utf8").toString("base64"); // "4pyTIMOgIGxhIG1vZGU="

事物是变化的。escape/unescape方法已弃用。

你可以在对字符串进行base64编码之前对其进行URI编码。注意,这不会生成base64编码的UTF8,而是生成base64编码的url编码数据。双方必须就相同的编码达成一致。

参见工作示例:http://codepen.io/anon/pen/PZgbPW

// encode string
var base64 = window.btoa(encodeURIComponent('€ 你好 æøåÆØÅ'));
// decode string
var str = decodeURIComponent(window.atob(tmp));
// str is now === '€ 你好 æøåÆØÅ'

对于OP的问题,第三方库如js-base64应该可以解决这个问题。

小修正,unescape和escape已弃用,因此:

function utf8_to_b64( str ) {
    return window.btoa(decodeURIComponent(encodeURIComponent(str)));
}

function b64_to_utf8( str ) {
     return decodeURIComponent(encodeURIComponent(window.atob(str)));
}


function b64_to_utf8( str ) {
    str = str.replace(/\s/g, '');    
    return decodeURIComponent(encodeURIComponent(window.atob(str)));
}