前言

说起Blob对于一部分人来说会很陌生,因为没有接触过,包括我之前也没有接触过,后来一个功能的实现才有机会接触Blob,现在来学习一下Blob的使用场景。后面有代码仓库地址

正文

什么是Blob

Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。

创建一个Blob对象
 1var aBlob = new Blob( array, options )
  • array 是一个由ArrayBufferArrayBufferViewBlobDOMString 等对象构成的 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方法

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形式

 1import { useState, useEffect, useRef, useMemo, useCallback } from 'react'
 2import { IconSty, UploadImgFrameSty } from './style';
 3import { PlusOutlined } from '@ant-design/icons';
 4import { Button } from 'antd';
 5export default function BlobUse() {
 6  const [imgUrl, setImgUrl] = useState('')
 7  const [isShow, setIsShow] = useState(false)
 8  const inputDom = useRef(null)
 9
10  const selectFile = useCallback((e: any) => {
11    
12    if (imgUrl) {
13      window.URL.revokeObjectURL(imgUrl)
14    }
15    const url = window.URL.createObjectURL(e.target.files[0]);
16    setImgUrl(url)
17    setIsShow(true)
18
19    
20    
21    
22    
23    
24    
25    
26    
27  }, [imgUrl])
28
29  useEffect(() => {
30    return () => {
31      imgUrl && window.URL.revokeObjectURL(imgUrl)
32    }
33  }, [])
34
35  return (
36    <>
37      <h3>Blob 实现本地图片预览</h3>
38      <UploadImgFrameSty>
39        {
40          !isShow && <IconSty>
41            <PlusOutlined />
42          </IconSty>
43        }
44        <input ref={inputDom} type="file" onChange={selectFile} accept="image/*" />
45        {isShow && <img src={imgUrl} />}
46      </UploadImgFrameSty>
47    </>
48  )
49}

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),将没有空格。

 1import { useState, useEffect, useRef, useMemo, useCallback } from 'react'
 2import { IconSty, UploadImgFrameSty } from './style';
 3import { PlusOutlined } from '@ant-design/icons';
 4import { Button } from 'antd';
 5export default function BlobUse() {
 6
 7  const clickDownload = useCallback(() => { 
 8    const data = {
 9      name: '张三',
10      age: 18,
11      second: "我不会出现在下载的数据中",
12    };
13    downloadJson(data, "json.json");
14  }, [])
15
16
17  
18  const downloadJson = useCallback((data: any, filename: string) => {
19    if (!data) {
20      alert("保存的数据为空");
21      return;
22    }
23
24    if (!filename) {
25      filename = "json.json";
26    }
27    if (typeof data === "object") {
28      data = JSON.stringify(data, null, 4);
29    }
30    let blob = new Blob([data], { type: "text/json" });
31
32    
33    let a = document.createElement("a");
34    a.download = filename;
35    a.href = window.URL.createObjectURL(blob);
36    a.click();
37    URL.revokeObjectURL(a.href);
38  }, [])
39
40  return (
41    <>
42      <h3>下载JSON文件</h3>
43      <Button type="primary" onClick={clickDownload}>下载JSON文件</Button>
44    </>
45  )
46}
47

Blob实现文件下载

后端以流的形式返回文件数据,我们通过将请求头responseType设置为blob,表示我们期望服务器响应的数据以二进制形式返回,并封装在一个Blob对象中。然后通过URL.createObjectURL配合动态生成a标签来下载文件。

具体的实现看这个:

从前后端代码看文件下载方式 - 掘金 (juejin.cn)

Blob文件切片上传

Blob 表示的不一定是 JavaScript 原生格式的数据。File 接口基于 Blob,继承了 blob 的功能并将其扩展以支持用户系统上的文件。

文件切片使用的slice方法,其实就是Blob身上的slice方法,具体的实现可以去看看之前写的文章

前端切片上传文件(可暂停),以链接形式返回 - 掘金 (juejin.cn)

结语

仓库地址

官方的文档: Blob - Web API 接口参考 | MDN (mozilla.org)

个人笔记记录 2021 ~ 2025