• 关于 Blob


    博客地址:https://ainyi.com/88

    对于 Blob,前端开发中可能比较少遇到;数据库中可使用 Blob 概念,例如 Mysql 存储二进制数据的类型就是 Blob,也就是说图片可存储于数据库中,以二进制格式存储

    Blob 对象表示一个不可变、原始数据的类文件对象。File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件

    Blob 是二进制数据对象,是类文件对象的二进制数据

    我在之前有篇博客说到 Blob:利用 Blob 处理 Node 层返回的二进制文件流字符串并下载文件
    这里我利用 Blob 实现文件拆分再合并下载的方法,算是第一次使用


    我们最常见的应该是 Blob URL 技术,文件上传的预览、视频播放的 src,均是采用这种技术实现

    WechatIMG6.png

    WechatIMG5.png

    Blob URL 就是以 blob: 开头的一段地址,指向的是一个二进制数据
    使用 URL.createObjectURL(blob) 方法生成,参数为 Blob 对象

    这个 Blob URL 是可以直接访问的;需要注意的是这个 URL 的生效时间,等同于网页的存在时间,一旦网页刷新或关闭,这个 Blob URL 就失效

    构造函数

    Blob(blobParts[, options])
    

    返回一个新创建的 Blob 对象,其内容由参数中给定的数组串联组成

    参数说明:
    blobParts:数组类型,数组中的每一项连接起来构成 Blob 对象的数据,数组中的每项元素可以是ArrayBuffer, ArrayBufferView, Blob, DOMString

    options:可选参数;字典格式类型,可以指定如下两个属性:

    1. type:放入到 blob 中的数组内容的 MIME 类型 MIME 参考手册
    2. endings:用于指定包含行结束符 的字符串如何被写入;可设置值:native、transparent;native:表示行结束符会被更改为适合宿主操作系统文件系统的换行符; transparent:表示会保持blob中保存的结束符不变;默认值为 transparent;

    使用场景

    介绍三种使用场景

    1. 二进制流文件下载
    2. 图片预览
    3. 视频加载

    二进制流文件下载

    // 获取文件二进制流 content
    const content = await downloadContract(params)
    
    // 再利用 Buffer 转为对象
    const buf = Buffer.from(content, 'binary')
    
    // 生成 Blob 对象,type 类型设置为 pdf 的 MIME 类型
    const blob = new Blob([buf], {type: 'application/pdf'});
    
    // 获取 Blob URL,可赋值到 a 标签 href 属性进行下载
    const url = URL.createObjectURL(blob)
    

    通过 Blob 生成文件、利用 Blob URL 获取下载链接,这样就实现后端返回二进制格式的文件进行合并再下载

    图片预览

    较为简单,获取文件对象后,再通过 createObjectURL 方法得到 Blob URL
    最后直接赋值到 img 标签的 src 属性即可

    <input id="upload" type="file" />
    <img id="preview" src="" alt="预览"/>
    
    const upload = document.querySelector('#upload')
    const preview = document.querySelector('#preview')
    
    upload.onchange = function() {
      const file = upload.files[0] // File 对象
      const src = URL.createObjectURL(file)
      preview.src = src
    }
    

    视频加载

    视频地址,不同于上面的 input,可以直接拿到 File 对象
    只有一个视频地址怎么能将这个 URL 变成我们想要的 Blob URL 形式呢

    URL.createObjectURL(blob) 方法来看,首先要拿到存储这个视频原始数据的 Blob 对象

    平时我们请求接口可以使用 axios / ajax / xhr 或 fetch,请求一个服务端地址可以返回我们相应的数据,那如果我们去请求一个图片或视频地址会返回什么?应当是返回图片和视频的数据,这种情况只要设置正确responseType才能拿到我们想要的格式数据

    // responseType 参数如下:
    // text 字符串;blob Blob对象;arraybuffer ArrayBuffer 对象
    function ajax(url, cb) {
      const xhr = new XMLHttpRequest()
      xhr.open('get', url)
      xhr.responseType = 'blob'
      xhr.onload = function() {
        cb(xhr.response)
      }
      xhr.send()
    }
    

    上面请求返回一个 Blob 对象,接下来只要然后通过 createObjectURL 生成 Blob URL 赋值给视频的 src 属性就可以了

    ajax('video.mp4', function(res){
      const src = URL.createObjectURL(res)
      video.src = src
    })
    

    大文件分片上传

    最近看到一篇文章:大规格文件的上传优化

    里面讲的是利用 Blob 实现文件分片上传,对于大文件上传有很好的效果

    其核心思想是文件分片,使用 File.slice() 方法进行文件分片;File 对象是继承 Blob 对象的,因此 File 对象也有 slice 方法

    Blob.slice([start[, end[, contentType]]])
    

    start 可选
    这个参数代表 Blob 里的下标,表示第一个会被会被拷贝进新的 Blob 的字节的起始位置。如果你传入的是一个负数,那么这个偏移量将会从数据的末尾从后到前开始计算
    举例来说: -10 将会是 Blob 的倒数第十个字节。它的默认值是0, 如果你传入的start的长度大于源 Blob 的长度,那么返回的将会是一个长度为0并且不包含任何数据的一个 Blob 对象

    end 可选
    这个参数代表的是 Blob 的一个下标,这个下标-1的对应的字节将会是被拷贝进新的Blob 的最后一个字节。如果你传入了一个负数,那么这个偏移量将会从数据的末尾从后到前开始计算
    举例来说: -10 将会是 Blob 的倒数第十个字节。它的默认值就是它的原始长度(size)

    contentType 可选
    给新的 Blob 赋予一个新的文档类型。这将会把它的 type 属性设为被传入的值。它的默认值是一个空的字符串


    文件分片方法
    定义每一个分片文件的大小变量为 chunkSize,通过文件大小 FileSize 和分片大小 chunkSize 得到分片数量 chunks,使用 for 循环和 file.slice() 方法对文件进行分片,序号为 0 - n,和已上传的切片列表做比对,得到所有未上传的分片,push 到请求列表 requestList

    上传进度
    监听原生 Javascript 的 XMLHttpRequest 的 progress 事件,这个事件会返回文件已上传的大小和总大小,可实现上传进度的变化

    博客地址:https://ainyi.com/88

  • 相关阅读:
    jsp-servlet(2)响应HTML文档-书籍管理系统
    jsp-servlet(1)环境搭建(Tomcat和myeclipse)和基本概念
    MySQL(2)数据库 表的查询操作
    MySQL(1) 基本操作(MySQL的启动,表的创建,查询表的结构和表的字段的修改)
    Java 构造器Constructor 继承
    数据结构:链表的操作
    C++指针易错点梳理
    C++操作符重载
    无重复字符的最长子串-LeetCode-第3题-C++
    计算几何模板存储
  • 原文地址:https://www.cnblogs.com/ainyi/p/12905898.html
Copyright © 2020-2023  润新知