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)

相关推荐
拉不动的猪3 分钟前
前端常见数组分析
前端·javascript·面试
小吕学编程20 分钟前
ES练习册
java·前端·elasticsearch
Asthenia041227 分钟前
Netty编解码器详解与实战
前端
袁煦丞32 分钟前
每天省2小时!这个网盘神器让我告别云存储混乱(附内网穿透神操作)
前端·程序员·远程工作
一个专注写代码的程序媛2 小时前
vue组件间通信
前端·javascript·vue.js
一笑code2 小时前
美团社招一面
前端·javascript·vue.js
懒懒是个程序员2 小时前
layui时间范围
前端·javascript·layui
NoneCoder2 小时前
HTML响应式网页设计与跨平台适配
前端·html
凯哥19702 小时前
在 Uni-app 做的后台中使用 Howler.js 实现强大的音频播放功能
前端
烛阴2 小时前
面试必考!一招教你区分JavaScript静态函数和普通函数,快收藏!
前端·javascript