最近碰到一个需求,后端返回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. tableView和tableViewCell的背景颜色问题

    当在tableView中添加cell数据时,我们会发现原本设置的tableView的背景颜色不见了,这是因为加载cell数据时,tableView的背景颜色被cell数据遮盖住了,此时,可以通过设置c ...

  2. 【Linux】【Services】【Package】Basic

    Linux程序包管理           概述         API:Application Program Interface         ABI:Application Binary Int ...

  3. Centos7源码部署Redis3.2.9

    目录 一.环境准备 二.安装 三.测试 四.编写启动脚本 一.环境准备 [Redis-Server] 主机名 = host-1 系统 = centos-7.3 地址 = 1.1.1.1 软件 = re ...

  4. Nginx模块之ngx_http_gzip_module

    Module ngx_http_gzip_module 该ngx_http_gzip_module模块是一个使用"gzip"方法压缩响应的过滤器.这通常有助于将传输数据的大小减少一 ...

  5. 转: 再谈select, iocp, epoll,kqueue及各种I/O复用机制

    首先,介绍几种常见的I/O模型及其区别,如下: blocking I/O nonblocking I/O I/O multiplexing (select and poll) signal drive ...

  6. [BUUCTF]REVERSE——reverse2

    reverse2 附件 例行检查,64位目标 64位ida载入,首先shift+f12检索程序里的字符串 得到了"this is the right flag!" 的提示字符串,还 ...

  7. CSAcademy Prefix Suffix Counting 题解

    CSAcademy Prefix Suffix Counting 题解 目录 CSAcademy Prefix Suffix Counting 题解 题意 思路 做法 程序 题意 给你两个数字\(N\ ...

  8. GET与POST的比较

    HTTP 方法:GET 对比 POST HTTP 消息 标签列表(字母排序) 两种最常用的 HTTP 方法是:GET 和 POST. 什么是 HTTP? 超文本传输协议(HTTP)的设计目的是保证客户 ...

  9. CF1111A Superhero Transformation 题解

    Content 有两个字符串 \(s,t\).规定元音字母只能够变换成元音字母,辅音字母只能够变换成辅音字母.试问 \(s\) 能否经过若干次变换得到 \(t\). 数据范围:\(1\leqslant ...

  10. Python3 json &pickle 数据序列化

    json 所有语言通用的信息交换格式 json.dumps()将list列表.dict字典.元组.函数等对象转换为可以存储的字符格式存入文件 json.dump(数据对象名,已以写方式打开的对象) 直 ...