解决 Javascript 中 atob 方法解码中文字符乱码问题

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

window.btoa 与 window.atob 不支持中文

对于 unicode 编码的字符进行 base64 编码之后,通过浏览器原生的 btoa 方法界面中文会乱码。

在 bash 终端,将“中文”转成 base64 编码

$ echo 中文 | base64
5Lit5paHCg==

在 Chrome console 通过 window.atob 解码,结果为乱码

> window.atob('5Lit5paHCg==')
中文

在 Chrome console 中执行 windows.btoa 编码,报错

> 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 字符序列,如果通过 encodeURIComponent 将中文字符编码成ASCII字符序列,再通过 btoa 进行 base64 编码。

编码

> window.btoa(encodeURIComponent('中文'))
"JUU0JUI4JUFEJUU2JTk2JTg3"

解码

> decodeURIComponent(window.atob('JUU0JUI4JUFEJUU2JTk2JTg3'))
"中文"

虽然到达了曲线救国的目的,但是由于 encodeURIComponent 和 decodeURIComponent 已经达到了转义控制字符的目的,使用 atob 和 btoa 感觉是多此一举。

第三方 Base64 工具

webtoolkit.base64是一个第三方实现的 Base64 编码工具,完美的支持 unicode 编码的字符串。

> Base64.encode('中文')
"5Lit5paH" > Base64.decode('5Lit5paH');
"中文"

另外,如果服务端为 Nodejs ,可用如下 coffee 代码进行 base64 的编码和解码。

btoa: (s)->
(new Buffer(s, 'utf8')).toString('base64')
atob: (s)->
(new Buffer(s, 'base64').toString('utf8'))

参考阅读

  1. btoa(), atob() 支援中文的方法
  2. How to encode UTF8 characters into Base64 in JavaScript
  3. window.atob
  4. Best practice: escape, or encodeURI / encodeURIComponent

Vangie Du

将来的你,一定会感谢现在拼命努力的自己!

Javascript 中 atob/btoa的更多相关文章

  1. Javascript中Base64编码解码的使用实例

    Javascript为我们提供了一个简单的方法来实现字符串的Base64编码和解码,分别是window.btoa()函数和window.atob()函数. 1 var encodedStr = win ...

  2. JavaScript中七种数据类型·中·一

    Standing on Shoulders of Giants; 说到JavaScript里的类型很容易就让人想起 42和"42",分别是string型和number型,但是他们可 ...

  3. javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈

    Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...

  4. javascript中的this与函数讲解

    前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...

  5. JavaScript 中的数据类型

    Javascript中的数据类型有以下几种情况: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Function,Date,Ar ...

  6. javascript中的操作符详解1

    好久没有写点什么了,根据博主的技术,仍然写一点javascript新手入门文章,接下来我们一起来探讨javascript的操作符. 一.前言 javascript中有许多操作符,但是许多初学者并不理解 ...

  7. 掌握javascript中的最基础数据结构-----数组

    这是一篇<数据结构与算法javascript描述>的读书笔记.主要梳理了关于数组的知识.部分内容及源码来自原作. 书中第一章介绍了如何配置javascript运行环境:javascript ...

  8. javascript中变量提升的理解

    网上找了两个经典的例子 var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); // 10 var ...

  9. 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

    前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...

随机推荐

  1. sp_helptext输出错行问题解决

    相信,大家对sp_helptext存储过程一定不陌生,它可以帮你快速获取存储过程等对象的定义.但它有一个致命的缺点就是:每行最多返回255个nvarchar类型的字符,假如有一个编写不规范的存储过程, ...

  2. javascript 获取iframe里页面中元素值的方法 关于contentWindow和contentDocumen

    javascript 获取iframe里页面中元素值的方法 IE方法:document.frames['myFrame'].document.getElementById('test').value; ...

  3. ansible 常用模块的使用

    安装 yum -y install ansible 配置文件/etc/ansible/hosts 模块介绍与使用 ping模块 [root@node1 config]# ansible k8s -m ...

  4. checkbox attr 和 prop ,onclick 事件,

    给checkbox 添加默认的勾选,尽量使用 checked=“checked”,不要使用checked=“true”. <td><input id="checkboxid ...

  5. Elasticsearch学习(2) windows环境下Elasticsearch同步mysql数据库

    在上一章中,我们已经能够通过spring boot来使用Elasticsearch,但是由于我们习惯性的将数据写入mysql,所以为了解决这个问题,Elasticsearch为我们提供了一个插件log ...

  6. 重载<<运算符第二个参数必须加上const

    如题,在重载<<时不停的报错,说找不到匹配的函数,仔细观察和书上的样例对比后发现,我的第二个参数缺少了一个const,抱着试一试的心态,因为平时也没注意const这个东西,也不经常用,试了 ...

  7. Python的编码详解

    一. 编码介绍 计算机只能处理数字(最底层的0和1),如果要处理文本,就必须将文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以一个字节能表示的最大整数就 ...

  8. P4850 [IOI2009]葡萄干raisins 记忆化搜索

    $ \color{#0066ff}{ 题目描述 }$ 普罗夫迪夫的著名巧克力大师Bonny需要切开一板带有葡萄干的巧克力.巧克力是一个包含许多相同的方形小块的矩形.小块沿着巧克力的边排列成n行m列,即 ...

  9. MODBUS协议相关代码(CRC验证 客户端程序)

    Modbus协议是一种已广泛应用于当今工业控制领域的通用通讯协议.通过此协议,控制器相互之间.或控制器经由网络(如以太网)可以和其它设备之间进行通信.Modbus协议使用的是主从通讯技术,即由主设备主 ...

  10. Git密钥

    SSH keys SSH key 可以让你在你的电脑和Code服务器之间建立安全的加密连接. 先执行以下语句来判断是否已经存在本地公钥: 1. cat ~/.ssh/id_rsa.pub    如果你 ...