使用window.btoa和window.atob来进行Base64编码和解码

 

方法描述

WindowBase64.atob() 函数用来解码一个已经被base-64编码过的数据。

WindowBase64.btoa() 函数 将ascii字符串或二进制数据转换成一个base64编码过的ASCII字符串,该方法不能直接作用于Unicode字符串.

window.atob: a ==> b
window.btoa: b ==> a

你可以使用 window.btoa() 方法来编码一个可能在传输过程中出现问题的数据,并且在接受数据之后,使用 window.atob() 方法来将数据解码。

var encodedData = window.btoa(stringToEncode);

var decodedData = window.atob(encodedData);

例子:

var encodedData = window.btoa("Hello, world"); //编码
console.log(encodedData);//SGVsbG8sIHdvcmxk
var decodedData = window.atob(encodedData); //解码
console.log(decodedData);//Hello, world

 

备注:

由于一些网络通讯协议的限制,你必须使用该方法对原数据进行编码后,才能进行发送.接收方使用相当于 window.atob 的方法对接受到的base64数据进行解码,得到原数据.
例如, 发送某些含有ASCII码表中0到31之间的控制字符的数据.

Unicode问题

由于 DOMString 是16位编码的字符串,所以如果有字符超出了8位ASCII编码的字符范围时,在大多数的浏览器中对Unicode字符串调用 window.btoa 将会造成一个 Character Out Of Range 的异常。
有2种方法解决这个问题:

第一个是转义整个字符串然后编码这个它;
第二个是把UTF-16的 DOMString 转码为UTF-8的字符数组然后编码它。 [我没测试过]
下面是2个可行的方法。

方法一: 编码之前转义字符串

function b64EncodeUnicode(str) {
    return window.btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
    function(match, p1) {
        return String.fromCharCode('0x' + p1);
    }));
}

b64EncodeUnicode('✓ à la mode');// "4pyTIMOgIGxhIG1vZGU="

 

方法二: 用JavaScript的TypedArray和UTF-8重写DOM的atob()和btoa()

使用像TextEncoding(包含了早期(legacy)的windows,mac, 和 ISO 编码), 
TextEncoderLite 或者 Buffer 这样的文本编码器增强(polyfill)和Base64增强, 
比如base64-js。

最简单, 最轻量级的解决方法就是使用 TextEncoderLite 和 base64-js.

测试案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>window.atob() && window.btoa()</title>
</head>
<body>
    <input type="text" id="iptText" name="" />
    <input type="button" id="iptBtoa" value="btoa编码" onclick="btoaFun()" />
    <input type="button" id="iptAtob" value="atob解码" onclick="atobFun()" />
    <div>
        <label id="lblInfo1" style="color: red"></label>
        <br/>
        <label id="lblInfo2" style="color: blue"></label>
    </div>
    <script type="text/javascript">

    /* window.atob() 解码*/
    function atobFun() {
        let strText = document.getElementById('lblInfo1').innerHTML;
        let strText2 = document.getElementById('lblInfo2').innerHTML;
        console.log(strText + "解码");
        let strLen = strText.trim();
        if (strLen.length > 0) {
            let encodedStr = window.atob(strText);
            document.getElementById('lblInfo1').innerHTML = encodedStr;

            let encodedStr2 = b64_to_utf8(strText2);
            document.getElementById('lblInfo2').innerHTML = encodedStr2;

            console.log(encodedStr + "解码");
            console.log(encodedStr2 + "解码");
        } else {
            alert('请输入字符串');
        }
    }
    /* window.btoa() 编码*/
    function btoaFun() {
        let strText = document.getElementById('iptText').value;
        let strLen = strText.trim();
        if (strLen.length == 0) {
            alert('请输入字符串');
        } else {
            let decodedStr = window.btoa(strText);
            document.getElementById('lblInfo1').innerHTML = decodedStr;

            let decodedStr2 = utf8_to_b64(strText);
            document.getElementById('lblInfo2').innerHTML = decodedStr2;

            console.log(decodedStr + "编码");
            console.log(decodedStr2 + "编码");

        }
    }

    function utf8_to_b64(str) {
        //encodeURIComponent()会对它发现的任何非标准字符进行编码。
        // unescape && escape 慢慢被废弃,不建议使用。
        // return window.btoa(unescape(encodeURIComponent(str)));
        // return window.btoa(encodeURIComponent(str));

        return window.btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, 
            function (match, p1) {
                return String.fromCharCode('0x' + p1);
        }));
    }
    function b64_to_utf8(str) {
        //decodeURIComponent() 解析所有的非标准字符
        // unescape && escape 慢慢被废弃,不建议使用。
        // return decodeURIComponent(escape(window.atob(str)));
        return decodeURIComponent(window.atob(str));
    }


    </script>
</body>
</html>
完整案例

 

posted @ 2017-03-22 15:03  weiqinl  阅读(1201)  评论(0编辑  收藏  举报