一、Blob是什么
在一般的Web开发中,很少会用到Blob,但Blob可以满足一些场景下的特殊需求。Blob,Binary Large Object的缩写,代表二进制类型的大对象。Blob的概念在一些数据库中有使用到,例如,MYSQL中的BLOB类型就表示二进制数据的容器。在Web中,Blob类型的对象表示不可变的类似文件对象的原始数据,通俗点说,就是Blob对象是二进制数据,但它是类似文件对象的二进制数据,因此可以像操作File对象一样操作Blob对象,实际上,File继承自Blob。
最早是数据库直接用Blob来存储二进制数据对象,这样就不用关注存储数据的格式了。在web领域,Blob对象表示一个只读原始数据的类文件对象,虽然是二进制原始数据但是类似文件的对象,因此可以像操作文件对象一样操作Blob对象。
ArrayBuffer对象用来表示通用的、固定长度的原始二进制数据缓冲区。我们可以通过new ArrayBuffer(length)来获得一片连续的内存空间,它不能直接读写,但可根据需要将其传递到TypedArray视图或 DataView 对象来解释原始缓冲区。实际上视图只是给你提供了一个某种类型的读写接口,让你可以操作ArrayBuffer里的数据。TypedArray需指定一个数组类型来保证数组成员都是同一个数据类型,而DataView数组成员可以是不同的数据类型。
二、Blob API 简介
以下为 Blob 使用场景
三、分片上传
利用Blob进行文件上传的完整步骤_微若轻澜的博客-CSDN博客
四、使用插件
Web Uploader支持多图上传,大文件上传,压缩图片上传,拖拽上传,显示上传进度,预览等。当上传的需求要求可预览、显示上传进度、中断上传过程、大文件分片上传等等,这时传统的表单上传很难实现这些功能,我们可以借助现有插件完成。
五、从互联网下载数据
// Blob--内容转化为文件下载
export const fileDownload = (file, fileName = '下载文件', options) => {
// 创建隐藏的可下载链接
let eleLink = document.createElement('a')
eleLink.download = fileName
eleLink.style.display = 'none'
// 字符内容转变成blob地址
let blob = options ? new Blob([file], options) : new Blob([file])
eleLink.href = URL.createObjectURL(blob)
// 触发点击
document.body.appendChild(eleLink)
eleLink.click()
// 然后移除
document.body.removeChild(eleLink)
}
// url地址下载,fileName暂无作用
export const urlDownload = (url, fileName = '下载文件') => {
// 创建隐藏的可下载链接
let eleLink = document.createElement('a')
eleLink.download = fileName
eleLink.style.display = 'none'
eleLink.href = url
// 触发点击
document.body.appendChild(eleLink)
eleLink.click()
// 然后移除
document.body.removeChild(eleLink)
}
六、Blob用作URL
// Blob网址/对象网址只能在浏览器内部制作, 不能在服务器上创建自己的Blob网址
// 可以通过文件读取器API创建Blob并获取File对象,
// 尽管BLOB只是意味着Binary Large对象并以字节数组的形式存储。
// 客户端可以请求数据以ArrayBuffer或Blob的形式发送。
// 服务器应该将数据作为纯二进制数据发送。
// 数据库通常也使用Blob来描述二进制对象,实际上我们基本上是在谈论字节数组。
var blob = new Blob([arrayBufferWithPNG], {type: "image/png"}),
url = (URL || webkitURL).createObjectURL(blob),
img = new Image();
img.onload = function() {
URL.revokeObjectURL(this.src); // clean-up memory
document.body.appendChild(this); // add image to DOM
}
img.src = url;
七、url、base64、blob相互转换
7.1、url 转 base64
// url 转 base64
// 原理: 利用canvas.toDataURL的API转化成base64
function urlToBase64(url) {
return new Promise ((resolve,reject) => {
let image = new Image();
image.onload = function() {
let canvas = document.createElement('canvas');
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
// 将图片插入画布并开始绘制
canvas.getContext('2d').drawImage(image, 0, 0);
// result
let result = canvas.toDataURL('image/png')
resolve(result);
};
// CORS 策略,会存在跨域问题https://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror
image.setAttribute("crossOrigin",'Anonymous');
image.src = url;
// 图片加载失败的错误处理
image.onerror = () => {
reject(new Error('urlToBase64 error'));
};
}
// 调用:
let imgUrL = `http://XXX.jpg`
urlToBase64(imgUrL).then(res => {
// 转化后的base64图片地址
console.log('base64', res)
})
7.2、base64 转 blob
// 原理:利用URL.createObjectURL为blob对象创建临时的URL
function base64ToBlob ({b64data = '', contentType = '', sliceSize = 512} = {}) {
return new Promise((resolve, reject) => {
// 使用 atob() 方法将数据解码
let byteCharacters = atob(b64data);
let byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
let slice = byteCharacters.slice(offset, offset + sliceSize);
let byteNumbers = [];
for (let i = 0; i < slice.length; i++) {
byteNumbers.push(slice.charCodeAt(i));
}
// 8 位无符号整数值的类型化数组。内容将初始化为 0。
// 如果无法分配请求数目的字节,则将引发异常。
byteArrays.push(new Uint8Array(byteNumbers));
}
let result = new Blob(byteArrays, {
type: contentType
})
result = Object.assign(result,{
// 这里一定要处理一下 URL.createObjectURL
preview: URL.createObjectURL(result),
name: `XXX.png`
});
resolve(result)
})
}
// 调用
let base64 = base64.split(',')[1]
base64ToBlob({b64data: base64, contentType: 'image/png'}).then(res => {
// 转后后的blob对象
console.log('blob', res)
})
7.3、blob 转 base64
// 原理:利用fileReader的readAsDataURL,将blob转为base64
blobToBase64(blob) {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = (e) => {
resolve(e.target.result);
};
// readAsDataURL
fileReader.readAsDataURL(blob);
fileReader.onerror = () => {
reject(new Error('blobToBase64 error'));
};
});
}
// 调用
blobToBase64(blob).then(res => {
// 转化后的base64
console.log('base64', res)
})
八、图片压缩
// 图片压缩
// 接收三个参数:
// file:是读取的文件,需要input type="file"获取或者通过js获取
// rate:压缩比例;按照原来图片的百分比
// maxSize: 压缩后的最大文件
// rate有则使用rate,最大限制拦截,会判断rate后是否大于maxSize,如果大于,则剪切,不大于,这rate
// fileType:返回内容的类型;file即压缩后的第一个参数,blob是blob文件,base64是base64文件
// 返回:promise,第一个参数:filePress,即压缩后的fileType文件;第二个参数:base64,即源文件base64
export const imgPress = ({ file, rate = 1, maxSize = 800, fileType = 'file' }) => {
return new Promise(resolve => {
// new一个文件读取方法,监听文件读取
let reader = new FileReader()
reader.readAsDataURL(file)
let img = new Image()
reader.onload = function (e) {
img.src = e.target.result
}
img.onload = function () {
let canvas = document.createElement('canvas')
let context = canvas.getContext('2d')
// 文件大小KB
const fileSizeKB = file.size / 1024
// 配置rate和maxSize的关系
if (fileSizeKB * rate > maxSize) {
rate = Math.floor(maxSize / fileSizeKB * 10) / 10
}
// 缩放比例,默认0.5
let targetW = canvas.width = this.width * rate
let targetH = canvas.height = this.height * rate
context.clearRect(0, 0, targetW, targetH)
context.drawImage(img, 0, 0, targetW, targetH)
if (fileType === 'file' || fileType === 'blob') {
canvas.toBlob(function (blob) {
resolve({ filePress: fileType === 'blob' ? blob : new File([blob], file.name, { type: file.type }), base64: img.src })
})
} else {
resolve({ filePress: fileType === 'base64' ? canvas.toDataURL(file.type) : null, base64: img.src })
}
}
})
}
九、生成PDF
十、Blob与ArrayBuffer的区别
Blob
全称:Binary Large Object
(二进制大型对象)
Blob
对象表示一个二进制文件的数据内容,通常用来读写文件,比如一个图片文件的内容就可以通过 Blob
对象读写。
与 ArrayBuffer
区别:
Blob
用于操作二进制文件
ArrayBuffer
用于操作内存
10.1、ArrayBuffer转Blob
var buffer = new ArrayBuffer(16);
var blob = new Blob([buffer]);
10.2、Blob转ArrayBuffer
var blob = new Blob([1,2,3,4,5]);
var reader = new FileReader();
reader.onload = function() {
console.log(this.result);
}
reader.readAsArrayBuffer(blob);
十一、Blob(Binary Large Object)表示二进制类型的大对象。
十二、在数据库管理系统中,将二进制数据存储为Blob。
十三、通过 Blob
对象的构造函数直接设置文件的 Content-Type(即 MIME 类型)
核心方法
在创建 Blob
对象时,通过第二个参数(配置对象)的 type
属性指定 MIME 类型
const blob = new Blob(
['文件内容'], // 数据数组(可以是字符串、ArrayBuffer等)
{
type: 'text/plain' // 👈 通过 type 属性设置 Content-Type
}
);
示例场景
假设需要生成一个 CSV 文件并指定其类型
// 创建 CSV 内容
const csvContent = "Name,Age\nAlice,30\nBob,25";
// 创建 Blob 并设置 Content-Type 为 text/csv
const blob = new Blob([csvContent], { type: 'text/csv' });
// 生成下载链接
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = 'data.csv';
link.click();
参考文献
图片:前端展示图像(img 、picture、svg、canvas )及常用图片格式(PNG、JPG、JPEG、WebP、GIF、SVG、AVIF等)_snow@li的博客-CSDN博客
为什么视频网站的视频链接地址是blob?_llhh33的博客-CSDN博客_blob
(13条消息) JS___Blob处理二进制数据分片上传_web_blog的博客-CSDN博客
利用Blob进行文件上传的完整步骤_微若轻澜的博客-CSDN博客
(14条消息) 大文件分片上传前后端实现_程序员小潘-CSDN博客
(14条消息) vue+大文件分片上传_Mr_Zang666的博客-CSDN博客
https://segmentfault.com/a/1190000019823978