Blob的几个使用场景

前言

说起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方法

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)

结语

仓库地址

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

相关推荐
喵叔哟28 分钟前
重构代码之取消临时字段
java·前端·重构
还是大剑师兰特1 小时前
D3的竞品有哪些,D3的优势,D3和echarts的对比
前端·javascript·echarts
王解1 小时前
【深度解析】CSS工程化全攻略(1)
前端·css
一只小白菜~1 小时前
web浏览器环境下使用window.open()打开PDF文件不是预览,而是下载文件?
前端·javascript·pdf·windowopen预览pdf
方才coding1 小时前
1小时构建Vue3知识体系之vue的生命周期函数
前端·javascript·vue.js
阿征学IT1 小时前
vue过滤器初步使用
前端·javascript·vue.js
王哲晓1 小时前
第四十五章 Vue之Vuex模块化创建(module)
前端·javascript·vue.js
丶21361 小时前
【WEB】深入理解 CORS(跨域资源共享):原理、配置与常见问题
前端·架构·web
发现你走远了1 小时前
『VUE』25. 组件事件与v-model(详细图文注释)
前端·javascript·vue.js
Mr.咕咕1 小时前
Django 搭建数据管理web——商品管理
前端·python·django