最近碰到一个需求,后端返回base64格式的数据,前端需要进行base64格式解码,好了,前端采用内部提供的atob函数进行解码,开完成,交付测试,然后测试小哥哥小姐姐反馈说中文乱码!

  然后查了一下,我后端代码采用utf8编码,这没问题,问题出在前端使用的atob函数,它居然采用的是Latin1(ISO-8859-1)编码!还不能修改编码方式,而且它还只在web端开发有这个atob函数!也不知道写这个atob函数的作者出于什么目的,Latin1(ISO-8859-1)编码用的很广么?竖中指!!!!

  没办法,问题要解决,我们本可以找一下第三方的包,但想想,还是觉的自己实现一个转码的函数,留着备用,这里分享出来:

    let base64util = function () {
let _keys = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; //base64格式加密
function encode(input) {
if (typeof input != "string") {
input = JSON.stringify(input)
} //utf8转码,Unicode值转换为字节数组
let buffer = [];
for (var n = 0; n < input.length; n++) {
var c = input.charCodeAt(n);
if (c < 128) { //一个字节
buffer.push(c);
} else if (c < 2048) { //两个字节
buffer.push((c >> 6) | 192, (c & 63) | 128);
} else if (c < 65536) { //三个字节
buffer.push((c >> 12) | 224, ((c >> 6) & 63) | 128, (c & 63) | 128);
} else if (c < 2097152) { //四个字节
buffer.push((c >> 18) | 240, ((c >> 12) & 63) | 128, ((c >> 6) & 63) | 128, (c & 63) | 128);
} else if (c < 67108864) { //五个字节
buffer.push((c >> 24) | 248, ((c >> 18) & 63) | 128, ((c >> 12) & 63) | 128, ((c >> 6) & 63) | 128, (c & 63) | 128);
} else { //六个字节
buffer.push((c >> 30) | 252, ((c >> 24) & 63) | 128, ((c >> 18) & 63) | 128, ((c >> 12) & 63) | 128, ((c >> 6) & 63) | 128, (c & 63) | 128);
}
} //转码,三字节转换成四字节
let i = 0, padding = buffer.length % 3;
padding && buffer.push(...new Array(padding = 3 - padding).fill(0));//先用0填补
let result = []
while (i < buffer.length) {
let [c1, c2, c3] = [buffer[i++], buffer[i++], buffer[i++]];
result.push(c1 >> 2, ((c1 & 0b11) << 4) | (c2 >> 4), ((c2 & 0b1111) << 2) | (c3 >> 6), c3 & 63);
}
padding && (result.splice(result.length - padding), result.push(...new Array(padding).fill(64)));//把0填补换成=
return result.map(v => _keys.charAt(v)).join("");
}
//base64格式解码
function decode(input) {
if (typeof input != "string") {
throw "invalid argument"
} //解码,四字节转换成三字节
let buffer = input.split(""), i = 0, padding;
let r = []
while (i < buffer.length) {
let array = buffer.slice(i, i += 4).map(v => _keys.indexOf(v))
if (array.length != 4 || array.some(v => v < 0)) throw "invalid input"
padding = array.filter(v => v == 64).length;//获取填补的=号数量
padding && (array.splice(r.length - padding), array.push(...new Array(padding).fill(0)));//把=填补换成0
let [e1, e2, e3, e4] = array
r.push((e1 << 2) | (e2 >> 4), ((e2 & 15) << 4) | (e3 >> 2), ((e3 & 3) << 6) | e4);
}
padding && r.splice(r.length - padding)//去掉填补 //utf8转码,字节数组转换成Unicode值
i = 0;
buffer = [];
while (i < r.length) {
let c = r[i++]
if (c < 128) //一个字节
buffer.push(c);
else if (c < 224) //两个字节
buffer.push(((c & 31) << 6) | (r[i++] & 63));
else if (c < 240) //三个字节
buffer.push(((c & 15) << 12) | ((r[i++] & 63) << 6) | (r[i++] & 63));
else if (c < 248) //四个字节
buffer.push(((c & 7) << 18) | ((r[i++] & 63) << 12) | ((r[i++] & 63) << 6) | (r[i++] & 63));
else if (c < 252) //五个字节
buffer.push(((c & 3) << 24) | ((r[i++] & 63) << 18) | ((r[i++] & 63) << 12) | ((r[i++] & 63) << 6) | (r[i++] & 63));
else //六个字节
buffer.push(((c & 1) << 30) | ((r[i++] & 63) << 25) | ((r[i++] & 63) << 18) | ((r[i++] & 63) << 12) | ((r[i++] & 63) << 6) | (r[i++] & 63));
}
return buffer.map(v => String.fromCharCode(v)).join("");
} return { encode, decode };
}()

  使用:  

    //转码
base64util.encode("say:上山打老虎")
//解码
base64util.decode("c2F5OuS4iuWxseaJk+iAgeiZjg==")

  结果:

  

javascript实现base64格式转码与解码的更多相关文章

  1. 把vux中的@font-face为base64格式的字体信息解码成可用的字体文件

    在最近移动端项目中用到了vux,感觉用着还习惯,当把vux使用到PC端的时候出现了IE浏览器出现,这样的错误信息: CSS3114: @font-face 未能完成 OpenType 嵌入权限检查.权 ...

  2. javascript中base64和Gzip的使用

    一般的使用流程(4步): 服务器端将字符串Gzip压缩为 字节数组——>通过base64转为字符串(后传递到客户端)——>解码base64字符串为字节数组——>Gzip解码字节数组为 ...

  3. javascript 使用btoa和atob来进行Base64转码和解码

    javascript原生的api本来就支持,Base64,但是由于之前的javascript局限性,导致Base64基本中看不中用.当前html5标准正式化之际,Base64将有较大的转型空间,对于H ...

  4. JavaScript对HTML字符转义与反转义(转码和解码)

    HTML的Encode(转码)和解码(Decode)在平时的开发中也是经常要处理的,在这里总结了使用javascript处理HTML的Encode(转码)和解码(Decode)的常用方式 一.用浏览器 ...

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

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

  6. javascript处理HTML的Encode(转码)和解码(Decode)

    HTML的Encode(转码)和解码(Decode)在平时的开发中也是经常要处理的,在这里总结了使用javascript处理HTML的Encode(转码)和解码(Decode)的常用方式 一.用浏览器 ...

  7. base64格式的图片数据如何转成图片

    base64格式的图片数据如何转成图片 一.总结 一句话总结:不仅要去掉前面的格式串,还需要base64_decode()解码才行. // $base_img是获取到前端传递的值 $base_img ...

  8. 图片64base转码与解码

    场景一:图片转码成base64,传输,接收后解码成png等格式图片 import base64 # 读取图片,转换为base64编码格式 with open("F:\Archer\pictu ...

  9. html5 图片转为base64格式异步上传

    因为有这个需求(移动端),所以就研究了一下,发现还挺不错的.这个主要是用了html5的API,不需要其他的JS插件,不过只有支持html5的浏览器才行,就现在而言应该大部份都支持的.<!DOCT ...

随机推荐

  1. Android 实现微信QQ分享以及第三方登录

    集成准备 在微信开放平台创建移动应用,输入应用的信息,包括移动应用名称,移动应用简介,移动应用图片信息,点击下一步,选择Android 应用,填写信息提交审核. 获取Appkey 集成[友盟+]SDK ...

  2. Spring Cloud Feign原理详解

    目录 1.什么是Feign? 2.Open Feign vs Spring Cloud Feign 2.1.OpenFeign 2.2.Spring Cloud Open Feign 3.Spring ...

  3. Mockito 入门详解

    一个测试方法主要包括三部分: setup 执行操作 验证结果 public class CalculatorTest { Calculator mCalculator; @Before // setu ...

  4. 使用jdbc,查询数据库数据,并将其封装为对象输出

    package cn.itcast.jdbc;import cn.itcast.domain.User;import java.sql.*;import java.util.ArrayList;imp ...

  5. 避免警报疲劳:每个 K8s 工程团队的 8 个技巧

    避免警报疲劳:每个 K8s 工程团队的 8 个技巧 监控 Kubernetes 集群并不容易,警报疲劳通常是一个问题.阅读这篇文章,了解减少警报疲劳的有用提示. 如果您是随叫随到团队的一员,您可能知道 ...

  6. Java(变量和常量)

    变量 可以变化的量.可以通过变量来操控内存中的数据:变量可以指代的是内存中的一块空间,而这块空间的位置是确定的但里边要放什么东西还不确定. Java是强类型语言,每个变量都要声明其类型. Java变量 ...

  7. Linux编译安装、压缩打包、定时任务管理

    编译安装 压缩打包 定时任务管理 一.编译安装 使用源代码,编译打包软件 1.特点 1.可以定制软件 2.按需构建软件 2.编译安装 1.下载源代码包 wget https://nginx.org/d ...

  8. CF1581B Diameter of Graph 题解

    Content \(\textsf{CQXYM}\) 想要构造一个包含 \(n\) 个点和 \(m\) 条边的无向连通图,并且他希望这个图满足下列条件: 该图中不存在重边和自环.也就是说,一条边应该连 ...

  9. CF1461A String Generation 题解

    Content 构造一个仅由 a,b,c 三个字符组成,且最长回文子串长度不超过 \(k\) 的长度为 \(n\) 的字符串. 数据范围:数据组数 \(\leqslant 10\),\(1\leqsl ...

  10. k8s daemonset controller源码分析

    daemonset controller分析 daemonset controller简介 daemonset controller是kube-controller-manager组件中众多控制器中的 ...