解决 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. ibatis 参数之模糊查询

    因项目需要最近使用ibatis,在使用查询语句的时候,想着通用性所以没有在配置文件里用N多的and 语句,而是如下: <select id="getUsersList" re ...

  2. Django ajax方法提交表单,及后端接受数据

    前台代码: {% block content %} <div class="wrapper wrapper-content"> <div class=" ...

  3. django drf安装和doc生成

    1.打开drf官网https://www.django-rest-framework.org/,把相关的包pip install 2.INSTALLED_APPS添加drf 3.url配置 4.tes ...

  4. Python数据模型建立

    基本结构AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bigint自增列,必须填入参数 pri ...

  5. vs 页面浏览不显示.aspx后缀名

    转:http://www.cnblogs.com/hllive/p/6029763.html 由vs2013新建“web窗体应用程序”的网站,URL不显示扩展名.那今天就实现该功能 1.首先打开vs2 ...

  6. Ubuntu16.04以root身份登入!

    首先以非root用户身份登入系统. 1,修改root密码:启动shell,随后在shell里面输入命令: sudo passwd root 最后输入root要使用的密码,需要输入两次,这样root密码 ...

  7. [USACO17DEC]Standing Out from the Herd(广义后缀自动机)

    题意 定义一个字符串的「独特值」为只属于该字符串的本质不同的非空子串的个数.如 "amy" 与 “tommy” 两个串,只属于 "amy" 的本质不同的子串为 ...

  8. css3里面的-webkit-transition

    css3里面的-webkit-transition (1)-webkit-transition-timing-function 可以定义动画的变化时间曲线-webkit-transition-timi ...

  9. Python脚本模板

    1.Python脚本规范基础模板 #coding:utf8 import time, re, os, sys, time,urllib2,shutil,string import json,datet ...

  10. Python导模块问题

    我们在import一个模块的时候,有没有想过如果我重复的import会怎么样?导入时都做了些什么?让我们来看看 1.首先我们新建一个demo,py,里面只有一句输出语句 2.多次导入demo,运行之后 ...