Blob进行文件上传

BLOB (binary large object)

二进制大对象,是一个可以存储二进制文件的容器。

Blob,Binary Large Object的缩写,二进制类型的大对象,代表不可改变的原始数据
在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型。

  • Blob基本用法
  • Blob对象

Blob对象指的是字节序列,并且具有size属性,是字节序列中的字节总数,和一个type属性,它是小写的ASCII编码的字符串表示的媒体类型字节序列。

  • size:以字节数返回字节序列的大小。获取时,符合要求的用户代理必须返回一个FileReader或一个FileReaderSync对象可以读取的总字节数,如果Blob没有要读取的字节,则返回0 。
  • type:小写的ASCII编码字符串表示媒体类型Blob。在获取时,用户代理必须Blob以小写形式返回a类型的ASCII编码字符串,这样当它转换为字节序列时,它是可解析的MIME类型,或者是空字符串(0字节)如果是类型无法确定。
    构造函数
    创建blob对象本质上和创建一个其他对象的方式是一样的,都是使用Blob() 的构造函数来进行创建。 构造函数接受两个参数:

第一个参数为一个数据序列,格式可以是ArrayBuffer, ArrayBufferView, Blob, DOMString
第二个参数是一个包含以下两个属性的对象

  • type: MIME的类型,
  • endings: 决定第一个参数的数据格式。默认值为”transparent”,用于指定包含行结束符n的字符串如何被写入。 它是以下两个值中的一个: “native”,表示行结束符会被更改为适合宿主操作系统文件系统的换行符; “transparent”,表示会保持blob中保存的结束符不变。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var data1 = "a";
var blob1 = new Blob([data1]);
console.log(blob1); //输出:Blob {size: 1, type: ""}

var debug = {hello: "world"};
var blob = new Blob([JSON.stringify(debug, null, 2)],{type : 'application/json'});
console.log(blob) // 输出 Blob(22) {size: 22, type: "application/json"}

// 创建一个8字节的ArrayBuffer,在其上创建一个每个数组元素为2字节的“视图”
var abf = new ArrayBuffer(8)
var abv = new Int16Array(abf)
var bolb_ArrayBuffer = new Blob(abv, {type : 'text/plain'})
console.log(bolb_ArrayBuffer) //输出 Blob(4) {size: 4, type: "text/plain"}

//window.atob 对用base-64编码过的字符串进行解码 。你可以使用 window.btoa() 方法来编码一个可能在传输过程中出现问题的数据,并且在接受数据之后,使用 atob() 方法再将数据解码。
let encodedData = window.btoa("Hello, world"); // 编码 "SGVsbG8sIHdvcmxk"
let decodedData = window.atob(encodedData); // 解码 "Hello, world"

var blob = new Blob(["Hello World!"],{type:"text/plain"}); //Blob(12) {size: 12, type: "text/plain"}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* dataURL to blob
* @param dataURI
* @returns {Blob}
*/
function dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], {type: mimeString});
}


// atob() 将base64解码
// btoa() 将字符串转码为base64
var str = 'javascript';
window.btoa(str)
//转码结果 "amF2YXNjcmlwdA=="
window.atob("amF2YXNjcmlwdA==")
//解码结果 "javascript"

Blob URL和Data URL的区别

Blob URL

Data URL

Blob URL的长度一般比较短,但Data URL因为直接存储图片base64编码后的数据,往往很长,如上图所示,浏览器在显示Data URL时使用了省略号(…)。当显式大图片时,使用Blob URL能获取更好的可能性。
Blob URL可以方便的使用XMLHttpRequest获取源数据,比如设置XMLHttpRequest返回的数据类型为blob
Blob URL 只能在当前应用内部使用,把Blob URL复制到浏览器的地址栏中,是无法获取数据的。Data URL相比之下,就有很好的移植性,可以在任意浏览器中使用。

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
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
<html>

<head>
<title></title>
<meta charset="UTF-8" />
<style>
body {
background:palegreen;
}
div{
float: left;
margin-left: 50px;
}
</style>
</head>

<body>
<div>
<h3>默认</h3>
<img class="sample1" img2blob="img/1.png" />
</div>
<div>
<h3>加水印</h3>
<img class="sample2" img2blob="img/2.jpg" />
</div>
<script>
function img2blob(imgUrl, obj = {}) {
var b = {
watermark: '',
fontStyle: 'Arial',
fontSize: '30',
fontColor: 'black',
fontX: 10,
fontY: 50
};

var d = imgUrl.getAttribute('img2blob'),
a = Object.assign(b, obj),
f = new Image();
f.src = d;
f.onload = function() {
var g = document.createElement('canvas');
g.width = f.naturalWidth;
g.height = f.naturalHeight;
var h = g.getContext('2d');
h.drawImage(f, 0, 0);
if(a.watermark != '') {
h.font = a.fontSize + 'px ' + a.fontStyle;
h.fillStyle = a.fontColor;
h.fillText(a.watermark, a.fontX, a.fontY);
}
var j = g.toDataURL('image/png'),
k = DataUriToBinary(j),
l = new Blob([k], {
type: 'image/png'
}),
m = window.URL.createObjectURL(l);
imgUrl.setAttribute('src', m)
console.log(m)
};

}

function DataUriToBinary(n) {
var o = ';base64,',
p = n.indexOf(o) + o.length,
q = n.substring(p),
r = window.atob(q),
s = r.length,
t = new Uint8Array(new ArrayBuffer(s));
for(var i = 0; i < s; i++) {
t[i] = r.charCodeAt(i);
}
return t;
}
</script>
<script type="text/javascript">
img2blob(document.querySelector(".sample1"))
img2blob(document.querySelector(".sample2"), {
watermark: '@Blob测试',
fontStyle: 'Arial',
fontSize: '30', // px
fontColor: '#ff0000', // default 'black'
fontX: 30, // The x coordinate where to start painting the text
fontY: 50 // The y coordinate where to start painting the text
})
</script>

</body>

</html>

DataURI(base64)对象转blob对象(二进制)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* 工具方法:dataURL(base64字符串)转换为Blob对象(二进制大对象) */
//data:image/png;base64,iVBORw0KGgoAAAANSUhEUg......

function dataURLtoBlob(dataurl) {
var arr = dataurl.split(',');
var mime = arr[0].match(/:(.*?);/)[1];// 结果: image/png
console.log("arr[0]====" + JSON.stringify(arr[0]));// "data:image/png;base64"
console.log("arr[0].match(/:(.*?);/)====" + arr[0].match(/:(.*?);/));// :image/png;,image/png
console.log("arr[0].match(/:(.*?);/)[1]====" + arr[0].match(/:(.*?);/)[1]);// image/png
var bstr = atob(arr[1].replace(/\s/g, ''));
var n = bstr.length;
var u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type: mime}); //值,类型
}
1
2
3
4
5
6
7
8
9
10
11
12
function DataUriToBinary(n) {
var o = ';base64,',
p = n.indexOf(o) + o.length,
q = n.substring(p),
r = window.atob(q),
s = r.length,
t = new Uint8Array(new ArrayBuffer(s));
for(var i = 0; i < s; i++) {
t[i] = r.charCodeAt(i);
}
return t;
}