说明

  • base64 是一种编码方式,数据从一种形式转换为另一种形式进行传输 / 存储
  • **编码过程会使数据量增加大约33%**,因为它把每3个字节的二进制数据扩展成了4个可打印的字符
  • Base64编码很容易解码,所以不具备任何形式的加密或数据安全性,它主要用于解决数据表示和传输问题,而不是数据保护
  • 文本数据不需要 base64 编码,因为没必要,还会增加数据大小。
  • 二进制数据如果需要采用文本方式才能传输或者接收方要求必须是文本,则可以使用 base64 编码
  • http 本身是支持文本和二进制数据传输的,例如文件的上传、下载传输的就是二进制数据
  • Base64是一种用64个字符来表示任意二进制数据的方法。
    • 大写字母 A-Z
    • 小写字母 a-z
    • 数字 0-9
    • 加号 (+)
    • 斜线 (/)
    • (在某些情况下,还会使用等号 (=) 作为填充字符,以确保编码后的字符串长度是4的倍数)

基本原理

将原始数据按每3个字节一组(共24位)进行分组,然后将这24位划分为4个6位的段,每个6位段对应Base64字符集中的一位字符。如果原始数据的字节数不是3的倍数,那么在最后不足3字节的情况下,会使用0位填充到24位,并在编码的末尾添加1或2个等号(=)来标记填充的数量。

应用

  • 在电子邮件中传输二进制文件(如附件)。电子邮件协议smtp只能传输ASCII码可打印字符,所以可以使用base64编码解决。
  • 在HTTP协议中传输非文本内容,如图片、音频和视频等
  • 在XML和JSON等文本格式的数据中嵌入二进制数据。
  • 在一些需要文本格式的环境或协议中安全地表示和传输密码或其他二进制信息。

base64 转 PDF

Web

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>base64转pdf</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<!-- <style>
iframe {
height: 800px;
width: 800px
}
</style> -->


</head>

<body>
<div>
<a class="down" href=""></a>
</div>
<button onclick="myFunction()">download Img</button>

<button onclick="myFunction2()">download pdf </button>
</body>
<script>

function myFunction() {
let base64 = 'data:image/png;base64,JVBERdhZDQzN2RlYjI1YTk4YjA+XS9JbmZvIDMgMCBSL1Jvb3QgMSAwIFIvU2l6ZSAxNT4+CiVpVGV4dC03LjEuMgpzdGFydHhyZWYKMTUyMDM0CiUlRU9GCg==';
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
//调用
let blob = dataURLtoBlob(base64);
let link = document.createElement('a')
link.download = 'abc.pdf' // 要下载的文件名
link.href = URL.createObjectURL(blob);
// 触发点击
document.body.appendChild(link);
link.click();
// 然后移除
document.body.removeChild(link);
}

/**
* desc: base64对象转blob文件对象
* @param urlData :数据的base64对象
* @param type :类型 png,pdf,doc,mp3等;
* @returns {Blob}:Blob文件对象
*/
function base64ToBlob(urlData, type) {
let arr = urlData.split(',');
let array = arr[0].match(/:(.*?);/);
let mime = (array && array.length > 1 ? array[1] : type) || type;
// 去掉url的头,并转化为byte
let bytes = window.atob(arr[1]);
// 处理异常,将ascii码小于0的转换为大于0
let ab = new ArrayBuffer(bytes.length);
// 生成视图(直接针对内存):8位无符号整数,长度1个字节
let ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], {
type: mime
});
}

/**
* desc: 下载导出文件
* @param blob :返回数据的blob对象或链接
* @param fileName :下载后文件名标记
* @param fileType :文件类 word(docx) excel(xlsx) ppt等
*/
function downloadExportFile(blob, fileName, fileType) {
let downloadElement = document.createElement('a');
let href = blob;
if (typeof blob == 'string') {
downloadElement.target = '_blank';
} else {
href = window.URL.createObjectURL(blob); //创建下载的链接
}
downloadElement.href = href;
downloadElement.download = fileName + '.' + fileType; //下载后文件名
document.body.appendChild(downloadElement);
downloadElement.click(); //触发点击下载
document.body.removeChild(downloadElement); //下载完成移除元素
if (typeof blob != 'string') {
window.URL.revokeObjectURL(href); //释放掉blob对象
}
}

/**
* desc: base64转文件并下载
* @param base64 {String} : base64数据
* @param fileType {String} : 要导出的文件类型png,pdf,doc,mp3等
* @param fileName {String} : 文件名
*/
function downloadFile(base64, fileName, fileType) {
let typeHeader = 'data:application/' + fileType + ';base64,' // 定义base64 头部文件类型
let converedBase64 = typeHeader + base64; // 拼接最终的base64
let blob = base64ToBlob(converedBase64, fileType) // 转成blob对象
downloadExportFile(blob, fileName, fileType) // 下载文件
}

function myFunction2() {
let base64 = 'JVBERi0xLjcKJeLjz9MKNSAwIG9iagxxxx';
downloadFile(base64,"123","pdf");
}
</script>

</html>

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 指定保存到的文件
File file = new File("/Users/wangwz/Desktop/test.pdf");

try (FileOutputStream fos = new FileOutputStream(file); ) {
// To be short I use a corrupted PDF string, so make sure to use a valid one if you want to preview the PDF file
// base64 数据
String b64 = "JVBERi0xLjcKJeLjz9MKNSAwU2l6ZSAxNT4+CiVpVGV4dC03LjEuMgpzdGFydHhyZWYKMTUyMDM0CiUlRU9GCg==";
byte[] decoder = Base64.getDecoder().decode(b64);

fos.write(decoder);
System.out.println("PDF File Saved");
} catch (Exception e) {
e.printStackTrace();
}

base64 转 blob

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function convertBase64UrlToBlob(data){
var arr = data.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type:mime});
}

//base64 转 blob ,文件上传
var blob = convertBase64UrlToBlob(base64Data);

var form = new FormData(); // FormData 对象
form.append("filepath", "/upload/peploe.jpg");
form.append("file", blob, "file_"+Date.parse(new Date())+".jpg"); // 文件对象
var xhr = new XMLHttpRequest(); // XMLHttpRequest 对象
xhr.open("post", url, true); //post方式,url为服务器请求地址,true 该参数规定请求是否异步处理。
xhr.onload = uploadComplete; //请求完成
xhr.onerror = uploadFailed; //请求失败

xhr.upload.onprogress = progressFunction;//【上传进度调用方法实现】
xhr.upload.onloadstart = function(){//上传开始执行方法
ot = new Date().getTime(); //设置上传开始时间
oloaded = 0;//设置上传开始时,以上传的文件大小为0
};

xhr.send(form); //开始上传,发送form数据

图片

img

  • src 指定的图片可以是图片路径,也可以是 base64 图片数据。根据图片压缩类型,需要添加前缀

  • src = 前缀 + base64 数据

前缀

  • gif 格式图片

    1
    data:image/gif;base64,
  • png 格式图片

    1
    data:image/png;base64,
  • jpeg 格式图片

    1
    data:image/jpeg;base64,
  • icon 格式图片

    1
    data:image/x-icon;base64,

问题

base64 数据传输后内部出现换行问题,导致显示不正确,可以将换行去掉

1
this.fingerBase64 = this.fingerBase64.replace(/[\r\n]/g, "");