方法描述
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>