解决 Javascript 中 atob 方法解码中文字符乱码问题
2016-03-14 16:33
1121 查看
转载地址:http://blog.sqrtthree.com/2015/08/29/utf8-to-b64/
首先, 为什么要编码?
由于一些网络通讯协议的限制, 又或者是出于信息加密的目的, 我们就需要将原信息转换为 base64 编码,然后才能进行传输.例如,发送某些含有 ASCII 码表中 0 到 31 之间的控制字符的数据。
通常的方法是通过
然后接收方使用
从而得到原数据.
但是这种方法存在的问题是:
base64编码的时候中文部分会变为乱码.详情如下:
我们在 bash 终端下先得到『中文』这两个字的 base64 编码
然后我们在 Chrome console 里面通过
结果如下
继续在 Chrome console 里面执行
结果报错.
经查资料发现,
ASCII 编码.
由于
ASCII 编码, 我们在转换中文的时候就需要先将中文转换为ASCII字符序列,再通过 btoa 进行 base64 编码, 从而实现『曲线救国』。
转换ASCII字符序列的方法我们可以借助于
编码:
解码:
但是通过上面的解码方式解码 github 的 readme 数据的时候仍旧是乱码, 经过查找相关资料发现了Base64的编码与解码转的最优方案是下面这种:
通过上面的这种方法去解析 github 的数据的时候, 发现中文能够正常显示了. 显然 github 也是采用了这种方案.
https://developer.mozilla.org/en/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/btoa
首先, 为什么要编码?
由于一些网络通讯协议的限制, 又或者是出于信息加密的目的, 我们就需要将原信息转换为 base64 编码,然后才能进行传输.例如,发送某些含有 ASCII 码表中 0 到 31 之间的控制字符的数据。
通常的方法是通过
window.btoa()方法对源数据进行编码,
然后接收方使用
window.atob()方法对其进行解码,
从而得到原数据.
window.btoa
与 window.atob 不支持中文
但是这种方法存在的问题是:window.btoa()不支持中文,
window.atob()转换含有中文的
base64编码的时候中文部分会变为乱码.详情如下:
我们在 bash 终端下先得到『中文』这两个字的 base64 编码
1 2 | $ echo 中文 | base64 5Lit5paHCg== |
window.atob进行解码,
结果如下
1 23 | > window.atob('5Lit5paHCg==') < "ä¸æ " |
window.btoa编码,
结果报错.
1 2 | > window.btoa('中文'); < Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range. |
btoa方法仅支持
ASCII 编码.
借助
encodeURIComponent 和 decodeURIComponent 转义中文字符
由于btoa方法仅支持
ASCII 编码, 我们在转换中文的时候就需要先将中文转换为ASCII字符序列,再通过 btoa 进行 base64 编码, 从而实现『曲线救国』。
转换ASCII字符序列的方法我们可以借助于
encodeURIComponent和
decodeURIComponent这两个方法完成.
编码:
1 2 | > window.btoa(encodeURIComponent('中文')) < "JUU0JUI4JUFEJUU2JTk2JTg3" |
1 2 | > decodeURIComponent(window.atob('JUU0JUI4JUFEJUU2JTk2JTg3')) < "中文" |
GitHub
API 获取 README 的中文乱码问题
但是通过上面的解码方式解码 github 的 readme 数据的时候仍旧是乱码, 经过查找相关资料发现了Base64的编码与解码转的最优方案是下面这种:1 23 | function utf8_to_b64(str) { return window.btoa(unescape(encodeURIComponent(str))); } function b64_to_utf8(str) { return decodeURIComponent(escape(window.atob(str))); } // Usage: utf8_to_b64('✓ à la mode'); // JTI1dTI3MTMlMjUyMCUyNUUwJTI1MjBsYSUyNTIwbW9kZQ== b64_to_utf8('JTI1dTI3MTMlMjUyMCUyNUUwJTI1MjBsYSUyNTIwbW9kZQ=='); // "✓ à la mode" utf8_to_b64('I \u2661 Unicode!'); // SSUyNTIwJTI1dTI2NjElMjUyMFVuaWNvZGUlMjUyMQ== b64_to_utf8('SSUyNTIwJTI1dTI2NjElMjUyMFVuaWNvZGUlMjUyMQ=='); // "I ♡ Unicode!" |
参考资料
https://developer.mozilla.org/en/docs/Web/API/WindowBase64/Base64_encoding_and_decodinghttps://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/btoa
相关文章推荐
- 基于javascript html5实现3D翻书特效
- JavaScript 声明全局变量与局部变量
- js通用对象数组冒牌排序
- 【js】js 总结,提供公共utils js
- 浏览器图片\文件上传到服务器 ajaxfileupload.js使用实例
- JSP自定义标签简单入门教程
- 说说JSON和JSONP,也许你会豁然开朗
- __proto__与prototype的区别
- javascript作用域链学习笔记
- Javascript学习笔记:闭包题解(3)
- JS 刷新随机统制DIV的的位置
- 【2016年Esri开发者大会亮点解析】JavaScript API 4.0即将发布,大力支持3D
- JS取出数组中重复的元素
- getElementsByClassName的用法 和 js获取class
- javascript小实例,PC网页里的拖拽(转)
- JavaScript substring() 方法
- XML和JSON优缺点
- Javascript学习笔记:闭包题解(2)
- iuni-core.js
- js第13天