首页/文章/javascript

Blob的几个使用场景

2023-12-01
17146 分钟
...

前言

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

正文

什么是Blob

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

创建一个Blob对象
var 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形式

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) => {
    
    if (imgUrl) {
      window.URL.revokeObjectURL(imgUrl)
    }
    const url = window.URL.createObjectURL(e.target.files[0]);
    setImgUrl(url)
    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),将没有空格。

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");
  }, [])


  
  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" });

    
    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)

结语

仓库地址

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

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
javascript2026-02-24
navigator.sendBeacon全指南
在前端开发中,埋点系统是必不可少的一环。我们经常需要在用户 关闭页面 、 刷新 或 跳转路由 时,向服务器发送最后一条统计数据(比如用户停留时长、页面跳出率)。 但这看似简单的需求,在实现时却危机四伏:请求发不出去?页面跳转卡顿?今天我们就来聊聊这个问题的终极解决方案 —— 。 一、 痛点与传统方案的挣扎 场景还原 当用户点击关闭按钮时,浏览器会触发生命周期事件( 或 )。如果我们直接使用普通的异步 AJAX ( 或 ) 发送请求,浏览...
学习
javascript2025-11-02
理解浏览器事件系统,从用户点击到事件对象的完整旅程
深入理解浏览器事件系统:从用户点击到事件对象的完整旅程 “当我点击页面按钮时,背后发生了什么?为什么回调函数能收到一个包含丰富信息的event对象?今天,让我们一起揭开浏览器事件系统的神秘面纱。” 一个令人困惑的现象 作为前端开发者,我们每天都在写这样的代码: 这段代码如此熟悉,以至于我们很少停下来思考:​ ​这个 对象到底从哪里来?它为什么能知道点击的精确坐标?为什么能识别是哪个元素被点击了?​ ​ 更神奇的是,当我们手动创建事件时:...
学习
javascript2025-10-01
实现大文件上传全流程详解
在日常开发中,大文件上传是个绕不开的坎——动辄几百 MB 甚至 GB 级的文件,直接上传不仅容易超时,还会让用户体验大打折扣。最近我用 Vue+Express 实现了一套完整的大文件上传方案,支持分片上传、断点续传、秒传和手动中。 一、先看效果:我们要实现什么? 先上核心功能清单,确保大家明确目标,知道我们要解决哪些实际问题: 大文件分片上传 :将文件切成固定大小的小片段分批上传,避免单次请求超时 秒传 :服务器已存在完整文件时,直接返...
学习
javascript2025-09-18
JavaScript 的多线程能力:Worker
如果你写过一些计算量稍大的 JavaScript 代码,比如图像处理、大量数据排序或者复杂的算法,你几乎肯定遇到过浏览器“卡死”的现象。点击页面没反应,动画也停了,就像整个世界都静止了。 这就是主线程被阻塞的典型后果。因为主线程既要负责执行 JavaScript,又要负责渲染页面、响应用户操作,一旦它被繁重的计算任务占满,就无暇顾及其他,用户体验便直线下降。 这个问题的根源,正是“主线程是单线程的”。那么,如何解决呢? 答案很简单:把这...
学习面试
javascript2025-09-15
一张 8K 海报差点把首屏拖垮
你给后台管理系统加了一个「企业风采」模块,运营同学一口气上传了 200 张 8K 宣传海报。首屏直接飙到 8.3 s,LCP 红得发紫。 老板一句「能不能像朋友圈那样滑到哪看到哪?」——于是你把懒加载重新翻出来折腾了一轮。 解决方案:三条技术路线,你全踩了一遍 1\. 最偷懒:原生 一行代码就能跑,浏览器帮你搞定。 🔍 关键决策点 2020 年后现代浏览器全覆盖,IE 全军覆没。 必须写死 ,否则 CLS 会抖成 PPT。 适用场景...
学习
javascript2025-09-10
🚀 Web Worker让你的应用丝滑
🌟 引言 在日常的前端开发中,你是否遇到过这样的困扰: 大数据处理时页面卡死 :处理几万条数据时,页面直接卡成PPT,用户点击毫无反应 复杂计算阻塞UI :图片处理、数据分析等计算密集型任务让整个应用假死 文件上传/下载卡顿 :大文件操作时,其他功能完全无法使用 实时数据处理性能差 :WebSocket接收大量数据时,页面渲染严重滞后 今天分享6个Web Worker的核心技巧,让你的应用告别卡顿,用户体验丝滑如德芙! 💡 核心技巧...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录