前言
说起Blob对于一部分人来说会很陌生,因为没有接触过,包括我之前也没有接触过,后来一个功能的实现才有机会接触Blob,现在来学习一下Blob的使用场景。后面有代码仓库地址
正文
什么是Blob
Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。
创建一个Blob对象
ini
var aBlob = new Blob( array, options );
-
array 是一个由
ArrayBuffer,ArrayBufferView,Blob,DOMString等对象构成的Array,或者其他类似对象的混合体,它将会被放进Blob。DOMStrings 会被编码为 UTF-8。 -
options 是一个可选的
BlobPropertyBag字典,它可能会指定如下两个属性:type,默认值为"",它代表了将会被放入到 blob 中的数组内容的 MIME 类型。常见的MIME类型text/plain:纯文本文件text/html:HTML 文档text/css:CSS 样式表application/javascript:JavaScript 脚本application/json:JSON 数据image/jpeg:JPEG 图像image/png:PNG 图像audio/mpeg:MP3 音频video/mp4:MP4 视频
endings,默认值为"transparent",用于指定包含行结束符\n的字符串如何被写入。- "transparent":表示不对文本数据进行行尾符号的转换。这是默认值。
- "native":表示将文本数据的行尾符号转换为当前平台的本地行尾符号。
Blob属性
- size(只读):表示
Blob对象中所包含数据的大小(以字节为单位)。 - type(只读):一个字符串,表明该
Blob对象所包含数据的 MIME 类型。如果类型未知,则该值为空字符串。
Blob方法
-
返回一个 promise,其会兑现一个包含
Blob所有内容的二进制格式的ArrayBuffer。 -
返回一个新的
Blob对象,包含了源Blob对象中指定范围内的数据。 -
返回一个能读取
Blob内容的ReadableStream。 -
返回一个 promise,其会兑现一个包含
Blob所有内容的 UTF-8 格式的字符串。
Blob实现上传图片浏览
代码很简单很容易看懂,介绍一下URL.createObjectURL()和URL.revokeObjectURL()。
URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的 URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的 URL 对象表示指定的 File 对象或 Blob 对象。
在每次调用 createObjectURL() 方法时,都会创建一个新的 URL 对象,即使你已经用相同的对象作为参数创建过。当不再需要这些 URL 对象时,每个对象必须通过调用 URL.revokeObjectURL() 方法来释放。
base64形式和Blob URL形式的src中数据差别很大,二者各有各的优势
- Blob URL 可以更好地处理大型文件,因为Blob URL不会将整个文件读入内存中,
FileReader会将整个文件读入内存中。 - Blob URL 可以更好地保护用户的隐私,因为它们不会将文件的内容暴露给第三方,
base64编码可以在任何应用程序中使用。 - Blob URL生命周期和创建它的窗口中的
document绑定,base64可以用于存储和传输文件。
base64形式 
Blob URL形式

tsx
import { useState, useEffect, useRef, useMemo, useCallback } from 'react'
import { IconSty, UploadImgFrameSty } from './style';
import { PlusOutlined } from '@ant-design/icons';
import { Button } from 'antd';
export default function BlobUse() {
const [imgUrl, setImgUrl] = useState('')
const [isShow, setIsShow] = useState(false)
const inputDom = useRef(null)
const selectFile = useCallback((e: any) => {
//Blob URL
if (imgUrl) {
window.URL.revokeObjectURL(imgUrl)
}
const url = window.URL.createObjectURL(e.target.files[0]);
setImgUrl(url)
setIsShow(true)
//base64
// const file = e.target.files[0];
// const reader = new FileReader();
// reader.readAsDataURL(file);
// reader.onload = () => {
// setImgUrl(reader.result as string);
// setIsShow(true);
// };
}, [imgUrl])
useEffect(() => {
return () => {
imgUrl && window.URL.revokeObjectURL(imgUrl)
}
}, [])
return (
<>
<h3>Blob 实现本地图片预览</h3>
<UploadImgFrameSty>
{
!isShow && <IconSty>
<PlusOutlined />
</IconSty>
}
<input ref={inputDom} type="file" onChange={selectFile} accept="image/*" />
{isShow && <img src={imgUrl} />}
</UploadImgFrameSty>
</>
)
}
Blob实现JSON文件下载
这里还是利用URL.createObjectURL()和URL.revokeObjectURL(),再配合JSON.stringify用来调整文件内容格式。
JSON.stringify(value[, replacer [, space]])
-
value
将要序列化成 一个 JSON 字符串的值。
-
replacer
可选 ,如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;如果该参数为 null 或者未提供,则对象所有的属性都会被序列化。
-
space
可选 ,指定缩进用的空白字符串,用于美化输出(pretty-print);如果参数是个数字,它代表有多少的空格;上限为 10。该值若小于 1,则意味着没有空格;如果该参数为字符串(当字符串长度超过 10 个字母,取其前 10 个字母),该字符串将被作为空格;如果该参数没有提供(或者为 null),将没有空格。
tsx
import { useState, useEffect, useRef, useMemo, useCallback } from 'react'
import { IconSty, UploadImgFrameSty } from './style';
import { PlusOutlined } from '@ant-design/icons';
import { Button } from 'antd';
export default function BlobUse() {
const clickDownload = useCallback(() => {
const data = {
name: '张三',
age: 18,
second: "我不会出现在下载的数据中",
};
downloadJson(data, "json.json");
}, [])
/** 下载JSON文件*/
const downloadJson = useCallback((data: any, filename: string) => {
if (!data) {
alert("保存的数据为空");
return;
}
if (!filename) {
filename = "json.json";
}
if (typeof data === "object") {
data = JSON.stringify(data, null, 4);
}
let blob = new Blob([data], { type: "text/json" });
//创建一个a标签进行下载
let a = document.createElement("a");
a.download = filename;
a.href = window.URL.createObjectURL(blob);
a.click();
URL.revokeObjectURL(a.href);
}, [])
return (
<>
<h3>下载JSON文件</h3>
<Button type="primary" onClick={clickDownload}>下载JSON文件</Button>
</>
)
}
Blob实现文件下载
后端以流的形式返回文件数据,我们通过将请求头responseType设置为blob,表示我们期望服务器响应的数据以二进制形式返回,并封装在一个Blob对象中。然后通过URL.createObjectURL配合动态生成a标签来下载文件。
具体的实现看这个:
从前后端代码看文件下载方式 - 掘金 (juejin.cn)
Blob文件切片上传
Blob 表示的不一定是 JavaScript 原生格式的数据。File 接口基于 Blob,继承了 blob 的功能并将其扩展以支持用户系统上的文件。
文件切片使用的slice方法,其实就是Blob身上的slice方法,具体的实现可以去看看之前写的文章
前端切片上传文件(可暂停),以链接形式返回 - 掘金 (juejin.cn)
