原文地址
转载文章,侵删

场景是这样的, 后台传来经过 base64 编码的字符串(原始字符串含有中文), 需要在前端进行解码, 但 js 中的 atob 解码方法不支持 unicode 字符集( btoa 也是), 换言之, 中文被解码出来是会乱码的, 那怎么办呢? 此时就要用到今天介绍的黑魔法了.

黑魔法

// 使用utf-8字符集进行base64编码
function utoa(str) {return window.btoa(unescape(encodeURIComponent(str)));
}
// 使用utf-8字符集解析base64字符串
function atou(str) {return decodeURIComponent(escape(window.atob(str)));
}

则我只需要调用 atou 函数, 即可解析后台传来的含有中文的 base64 编码字符串了

分析atou

其实上述方法在 MDN 中已有介绍, 但却没有讲明原理, 下面将分析要点

先来分析 atou 函数

其实该函数的关键是做了一个拉丁字符到 utf-8 字符的转换.

为什么这么说呢? 因为 atob 函数使用的是拉丁字符集, 而 decodeURIComponent 使用的是 utf-8 字符集

此时调用 escape 函数, 则会对拉丁字符集文本进行百分号编码(percent-encoding), 简单来说就是非 ASCII 字符如 È (拉丁字符, 上面有个点的 E), 它的在字符集中对应的十六进制字节为 0xC8 , 则其百分号编码为 %C8, ASCII 字符如 [0-9a-z] 则不需要转换

最后再调用 decodeURIComponent 函数, 它会将百分号编码的字符串解析成 utf-8 字符集的字符串, 则 window.atob 返回的拉丁文就变成 unicode 文字了, 中文也就可以显示出来了

这样讲可能有点难懂, 下面举个简单的例子

例子

以中文人字为例, 其对应的 base64 编码为 5Lq6

首先对其解码 window.atob('5Lq6') 的结果为拉丁字符串 人
使用 escape 对拉丁字符串进行百分号编码, 也可以理解成把字符串翻译成拉丁字符集中对应的十六进制符号, escape('人') 结果为 %E4%BA%BA
使用 decodeURIComponent 解析百分号编码字符串, 相当于把十六进制符号翻译成 utf-8 字符集中对应的字符, decodeURIComponent('%E4%BA%BA') 结果为 人, 则原始的中文字就被正确的解析出来了!

分析utoa

因为 atou 要用到 escape 以及 decodeURIComponent 函数, 则很容易理解 utoa 要用与之相对应的 unescape 以及 encodeURIComponent 函数.

但其实事情可以有点微妙的变化.

如果 base64 的编码与解析全是由自己控制的, 且代码仅在 js 环境下运行, 那么可以不需要 escape/unescape 函数, utoa 方法可以改写为

function utoa(str) {return btoa(encodeURIComponent(str))
}

因为 encodeURIComponent 函数是使用 utf-8 字符集的, 输出的结果是字符串对应的百分号编码, 而百分号编码是在 ASCII 码范围内, btoa 函数当然可以识别, 则上面的写法也是可行的

只不过它有一个明显的缺点, 那就是这样编码出来的字符串变长了

提问

如何评价上述黑魔法?
我认为这种方法的优点是, 使用的全是 js 内置的函数, 不需要借助第三类库, 对于有洁癖的同学来说(比如说我), 更容易接受.

缺点的话, 可能是使用了 escape/unescape 函数, 这两个函数不被标准推荐使用, 不过我认为那是针对 UR I进行编码解码的场景, 这里 escape/unescape 并不用于 URI 的编码与解码, 并没有用错地方. 只不过因为不鼓励使用, 未来有可能不被浏览器实现, 但我觉得浏览器开发商为了兼容性, 短时间内并不会这样做

是否可以使用 encodeURI/decodeURI 函数?
答案是可以的. 简单来说, encodeURIencodeURIComponent 的区别在于, 后者编码得彻底, 也即 URI 符号的编码粒度更细. 比如 URI 中常见的符号 =, encodeURI('=') 的结果是 =, 而 encodeURIComponent('=') 的结果是 %3D , encodeURI/decodeURI 函数同样使用的是 utf-8 字符集, 所以粒度的不同并不影响结果.

js 黑魔法之使用 atob 解码 utf-8 字符相关推荐

  1. atob解码图片base64时候报错

    最近在改一个bug, 使用图片的base64编码 进行压缩时一直报错,Failed to execute 'atob' on 'Window': The string to be decoded is ...

  2. js encodeuri转码和解码

    js encodeuri转码和解码教程如下: 输入一段html代码 实现结果:将代码加密 js实现代码如下: /*! JSFuck 0.4.0 - http://jsfuck.com */(funct ...

  3. Java18-day09【字节缓冲流、字符流、编码表、字符串与字符流中的编码解码问题、字符流读写数据的方式、字符缓冲流、IO流小结】

    视频+资料(工程源码.笔记)[链接:https://pan.baidu.com/s/1MdFNUADVSFf-lVw3SJRvtg   提取码:zjxs] Java基础--学习笔记(零起点打开java ...

  4. js 替换字符串中所有满足条件的字符

    js 替换字符串中所有满足条件的字符 1.需求 2.实现 2.1 replace不知道的那些事 1.需求 网上找材料时,趴下来的文件是带其他条件的(我们不需要的),需要替换掉 2.实现 2.1 rep ...

  5. 正则js判断是否存在中文和全角字符

    正则js判断是否存在中文和全角字符 var str = ... String.prototype.isChinese = function () {var reg = /[^\x00-\xff]/ig ...

  6. Python爬虫:js的btoa和atob和pythonBase64编码解码比对分析

    比对js和py的Base64编码解码,探求一个共通之处 javascript代码 对英文字符进行base64编码解码 var str = 'javascript';// 编码 btoa(str) // ...

  7. js实现base64编码和解码

    文章目录 需求 什么是Base64 编码规则 如何解码 js实现基于base64的编码解码 window自带函数进行Base64编码解码 Base64编码的实际运用 图片base64编码 需求 应公司 ...

  8. 用 JS 进行 Base64 编码、解码

    从IE10+浏览器开始,所有浏览器就原生提供了 Base64 编码.解码方法,不仅可以用于浏览器环境,Service Worker 环境也可以使用. 方法名就是 atob 和 btoa ,具体语法如下 ...

  9. Js编码和Java后台解码

    注: 在使用get提交,url传递参数的时候,会带来中文乱码的问题,对此可以使用js编码来解决. Js编码的几种方式区别: 1.window.escape()与HttpUtility.UrlEncod ...

最新文章

  1. 非阻塞socket的连接
  2. java+criteriaquery_Hibernate动态条件查询(Criteria Query)
  3. python连接sqlite加密_C#连接加密的Sqlite数据库的方法
  4. Keras之Mask R-CNN:《极限挑战》第四季第2期助力高考—使用Mask R-CNN代替Photoshop抠图、颜色填充框出目标检测/图像分割/语义分割
  5. pythonurllib微博登录怎么删_Python骚操作之删微博还需用手动吗?Python去做就好了!...
  6. CodeForces - 1486E Paired Payment(分层图最短路)
  7. 怎么上传文件到kk服务器,VS Code 关于SFTP上传文件到多服务器的配置
  8. java去除重复对象_Java19-2 集合类去除重复对象
  9. ubuntu虚拟机联网
  10. registry:NoSuchMethodError zookeeper.server.quorum.flexible.QuorumMaj
  11. Java多个注解合并_Java注解合并,注解继承
  12. git 小乌龟 配置_Git-TortoiseGit完整配置流程
  13. 2022年江西省研究生数学建模竞赛冰壶运动求解全过程文档及程序
  14. PHP + 小程序开发过程
  15. it工种分类_科普篇!程序员都有哪些工种和类型呢?
  16. 电磁波传播matlab程序,电磁波在不同介质中传播的 MATLAB 仿真教学实践论文
  17. 期货从业有哪些公式要背?
  18. MindManager教你做一份完美的笔记
  19. gcc/g++搜索路径
  20. android手机怎么上卡,安卓手机卡慢怎么办 安卓手机卡慢解决方案【详解】

热门文章

  1. P8400 [CCC 2022 J1] Cupcake Party
  2. a:visited为何不起作用及如何清除缓存
  3. FOC - SVPWM
  4. 【转载】SAP中与物料BOM有关的表关联
  5. GSM/CDMA/固定电话,呼叫等待,呼叫转移
  6. 47个“企业数字化转型”常见术语合集,看完秒懂~
  7. springBoot 和 spring security 版本对应关系
  8. 苹果账号被禁用怎么办?
  9. python编辑elif显示错误_Python if / elif语法错误…为什么
  10. java 分批次处理大数据量数据