本文详细介绍 JavaScript 中 Blob 对象的创建方式、基本属性及核心方法。涵盖通过构造函数生成 Blob、使用 slice 方法进行大文件分片处理,以及结合 File 对象实现本地图片预览。内容包含代码示例与浏览器兼容性处理方案,帮助开发者掌握二进制数据处理技巧。
Blob 对象概述
Blob(Binary Large Object,二进制大对象)这一术语源自数据库领域,例如 Oracle 数据库中便存在类似的字段类型。早期数据库为了存储音频、图像及可执行文件等二进制数据,便为这类数据对象命名为 Blob。
在 Web 开发领域,Blob 被定义为一种包含只读数据的类文件对象。需要注意的是,Blob 内部存储的数据并不一定是 JavaScript 原生数据格式。常见的 File 接口便继承自 Blob,并在此基础上进行了扩展,以支持对用户本地系统文件的访问。

构建一个 Blob 对象通常有三种主要方式:
- 利用 Blob 对象的构造函数进行创建。
- 调用已有 Blob 对象的 slice 接口,从中截取生成一个新的 Blob 对象。
- 通过 Canvas API 的 toBlob 方法,将当前绘制的图像信息转换为 Blob 对象。下文将重点介绍第一种构建方式的实现细节:
创建 Blob 对象
使用方法:通过构造函数创建 Blob 对象。
var blob = new Blob(array[optional], options[optional]);
该构造函数接受两个参数。
第一个参数是一个数据序列,可以是任意格式的值,例如任意数量的字符串、Blobs 或 ArrayBuffers。
第二个参数用于指定放入 Blob 中的数据类型(MIME 类型)。后端可以通过枚举 MimeType 来获取对应的类型信息:
MimeType mimeType = MimeType.toEnum(file.getContentType());)。
<script>
var blob = new Blob(["Hello World!"],{type:"text/plain"});
</script>
Blob 属性与构造注意事项
Blob 对象包含以下基本属性:
- size:表示 Blob 对象所包含的字节数,该属性为只读。
- type:表示 Blob 对象包含的数据 MIME 类型,若类型未知则返回空字符串。
尝试使用原生对象直接构建 Blob 时:
<script type="text/javascript">
window.onload = function() {
var blob = new Blob(1234);
}
</script>
系统会提示出错:
Uncaught TypeError: Failed to construct ‘Blob': The 1st argument is neither an array, nor does it have indexed properties.
错误原因在于 Blob 构造函数要求第一个参数必须是数组,而此处传入的第一个参数既不是数组,也不具备可索引的属性。既然提到了对象的可索引属性,这让人联想到类数组对象的概念,而 Arguments 对象就是一个很好的例子。我们来尝试一下:
<script type="text/javascript">
function testArgumentsBlob() {
var blob = new Blob(arguments);
console.log(blob.size);//3
console.log(blob.type);//""
}
window.onload = function() {
testArgumentsBlob(1, 2, 3);
}
</script>
结果显示,即使是类数组对象,且数组元素类型为 Number,也能得出正确结论。推测这可能是由于构造函数内部将 Number 类型自动转换为 String 所致。
接着尝试其他参数类型:
window.onload = function() {
var arg = {hello: "2016"};
var blob = new Blob([JSON.stringify(arg, null, "\t")], {type: "application/json"});
console.log(blob.type);//application/json
console.log(blob.size);//20
}
此时 blob.type 等于 application/json,符合预期。arg 转换为字符串后的长度为 16,加上制表符 \t 的宽度 4 个字节,总大小等于 20。
Blob 切片与浏览器兼容处理
Blob 对象还包含以下基本方法:
大文件分割(slice() 方法),该方法的用法与数组的 slice 类似。
Blob.slice([start, [end, [content-type]]])
slice() 方法接受三个参数:起始偏移量、结束偏移量,以及可选的 MIME 类型。如果未设置 MIME 类型,新生成的 Blob 对象的 MIME 类型将与父级保持一致。
在上传大文件时,此方法非常实用。它可以将大文件分割为多个片段分别上传,因为分割后生成的 Blob 对象与原始对象是相互独立的。
不过,目前各浏览器对该方法的实现尚未统一:Firefox 使用 mozSlice(),Chrome 使用 webkitSlice(),而其他浏览器则使用标准的 slice()。
因此,可以编写一个兼容各浏览器的封装方法:
function sliceBlob(blob, start, end, type) {
type = type || blob.type;
if (blob.mozSlice) {
return blob.mozSlice(start, end, type);
} else if (blob.webkitSlice) {
return blob.webkitSlice(start, end type);
} else {
throw new Error("This doesn't work!");
}
}
利用 Blob 显示图片缩略图
利用 Blob 显示缩略图。
var input = document.createElement("input");
input.type = "file";
input.accept = "image/*";
input.multiple = true;
input.style.display = "none";
document.body.appendChild(input);
var fileSelect = document.createElement("a");
fileSelect.href = "#";
fileSelect.appendChild(document.createTextNode("Choose files"));
document.body.appendChild(fileSelect);
var imgList = document.createElement("div");
imgList.innerHTML = "<p>No file Selected!</p>"
document.body.appendChild(imgList);
input.addEventListener("change", function(e) {
var files = this.files;
if(!files.length) {
return;
}
imgList.innerHTML = "";
var list = document.createElement("ul");
imgList.appendChild(list);
for(var i = 0; i < files.length; i++) {
var li = document.createElement("li");
list.appendChild(li);
var img = document.createElement("img");
img.src = window.URL.createObjectURL(files[i]);
img.height = 60;
img.width = 60;
img.onload = function() {
window.URL.revokeObjectURL(this.src);
}
li.appendChild(img);
var info = document.createElement("span");
info.innerHTML = files[i].name + ":" + files[i].size + " bytes";
li.appendChild(info);
}
}, false);
fileSelect.addEventListener("click", function(e) {
input.click();
e.preventDefault();
}, false);
由于 File 对象继承自 Blob,我们可以很方便地利用 File 对象加载本地系统的图片文件,并通过 createObjectURL 生成一个 URL 来进行显示。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。