Blob

266 阅读5分钟

Blob介绍

Blob( Binary Large Object ) 表示二进制类型的大对象。对于数据库管理系统来说,它将二进制数据存储为单一个体的集合,通常用于影像,声音或多媒体文件。

在JavaScript中,Blob类型表示不可变的类似文件对象的原始数据。

为了能够直观感受,创建一个Blob对象。

var text = '我是Blob对象' 

var blob = new Blob([text],{type:'text/plain'})  

Blob对象含有两个属性:size 和 type。

  • size表示数据的大小(以字节为单位)
  • type表示 MIME 的类型。

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

Blob构造函数的属性和方法

var blob = new Blob( array, options ); 

参数说明:

  • array 是一个由 Blob, DOMString , ArrayBuffer, ArrayBufferView,等对象构成的 Array。DOMStrings会被编码为UTF-8。

  • optinos一般默认会指定两个属性 .

    • type: 默认值为 "",它代表了将会被放入到blob中的数组内容的MIME类型
    • endings,默认值为"transparent",用于指定包含行结束符\n的字符串如何被写入。主要有两个值: "native" 和 “transparent ”。 “native” 代表行结束符会被更改为适合宿主操作系统文件系统的换行符,"transparent"代表会保持blob中保存的结束符不变

例子1 :从DOMString创建Blob

var aFileParts = ['<a id="a"><b id="b">hey!</b></a>']; // 一个包含DOMString的数组 

var oMyBlob = new Blob(aFileParts, {type : 'text/html'}); // 得到 blob 

例子2:从类型化数组和字符串创建 Blob

var hello = new Uint8Array([72, 101, 108, 108, 111]); // 二进制格式的 "hello" 

var blob =  new Blob([hello, ' ', 'semlinker'], {type: 'text/plain'}); 

方法说明

  • arrayBuffer() 方法返回一个 Promise 对象,包含 blob 中的数据,并在 ArrayBuffer 中以二进制数据的形式呈现。
  • slice() 方法用于创建一个包含源 Blob的指定字节范围内的数据的新 Blob 对象
  • stream() 方法返回一个ReadableStream对象,读取它将返回包含在Blob中的数据。
  • text() 方法返回一个 Promise 对象,包含 blob 中的内容,使用 UTF-8 格式编码

Blob的使用场景

1. 分片上传

onFile.addEventListener('change', async function (e) {

      const file = e.target.files[0]

      const chunkSize = 100

      const url = '/tools_upload_image_v2/'

      for (let start = 0; start < file.size; start += chunkSize) {

        const chunk = file.slice(start, start + chunkSize + 1);

        const fd = new FormData()

        fd.append('Filedata', chunk)

        await fetch(url, { body: fd, method: 'POST',headers:{}}).then(res => {

          console.log('res', res)

        }).catch(err=>{

          console.log('err', err)

        })

      }

    })

2. 下载文件

const imgUrl='https:/xxxxx/free_stock_photo.jpg'

onDownLoad.addEventListener('click', async () => {

    await fetch(imagUrl).then(res => {

       return res.blob()

    }).then(blob=>{

      let objectURL = URL.createObjectURL(blob); 

      onImgBg.src = objectURL;

    })

  })

Blob URL 是一种伪协议,允许Blob 和File对象作为图像,在浏览器中,使用 URL.createObjectURL() 方法来创建 Blob URL,该方法接收一个 Blob 对 象,并为其创建一个唯一的 URL,其形式为 blob:/

blob:http://xxxxx/5930e215-94ef-4ad2-8b58-a1057f0889b2

浏览器内部为每个通过 URL.createObjectURL 生成的 URL ,存储了一个 URL → Blob 映射。URL 的生命周期和创建它的窗口中的 document 绑定的,当窗口关闭的时候,这个链接也就失效了。

可以通过将跨域链接转换成 blob 伪协议,下载一个跨域的文件。

3. Blob 转换为 Base64

这个算是 URL.createObjectURL 的一个替代方法,将 Blob 转换为 base64 编码的字符串 。现代浏览器支持一种名为 Data URLs 的特性,允许使用 base64 对图片或其他文件的二进制数据进行编码,将其作为文本字符串嵌入网⻚中。

onBlobToBase64.addEventListener('click', () => {

    if (saveBlob) {

      var reader = new FileReader();

        reader.onload = function (e) {

           onImgBase.src = e.target.result

        }

        reader.readAsDataURL(saveBlob);

    } else {

      alert('请先获取Blob')

    }



  })

4. 图片压缩

let canvas = document.createElement("canvas");

    let img = document.createElement("img");

    img.crossOrigin = "anonymous";

    const MAX_WIDTH = 800; // 图片最大宽度

    return new Promise((resolve, reject) => {

      img.src = base64;

      img.onload = () => {

        let targetWidth, targetHeight;

        if (img.width > MAX_WIDTH) {

          targetWidth = MAX_WIDTH;

          targetHeight = (img.height * MAX_WIDTH) / img.width;

        } else {

          targetWidth = img.width;

          targetHeight = img.height;

        }

        canvas.width = targetWidth;

        canvas.height = targetHeight;

        let ctx = canvas.getContext("2d");

        ctx.clearRect(0, 0, targetWidth, targetHeight); // 清除画布 

        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

        let imageData = canvas.toDataURL(mimeType, quality / 100);

        resolve(imageData);

      };

    });

图片越小,压缩之后反而变得更大;反之,图片越大,图片压缩之后,变大的比例就越小

canvas压缩图片的秘密_weixin_34114823的博客-CSDN博客

blog.uproject.cn/articles/20…

Blob 与 ArrayBuffer的区别

ArrayBuffer 对象代表储存二进制数据的一段内存,它不能直接读写,只能通过视图(TypedArray视图和DataView视图)来读写,视图的作用是以指定格式解读二进制数据。

Blob 类型的对象表示不可变的类似文件对象的原始数据。Blob 表示的不一定JavaScript 原生格式的数据。File 接口基于 Blob,继承了Blob 功能并将其扩展为支持用户系统上的文件。

两者的比较

  • 除非你需要使用 ArrayBuffer 提供的写入/编辑的能力,否则 Blob 格式可能是最好的。
  • Blob 对象是不可变的,而 ArrayBuffer 是可以通过 TypedArrays 或 DataView 来操作。
  • ArrayBuffer 是存在内存中的,可以直接操作。而 Blob 可以位于磁盘、高速缓存内存和其他不可用的位置。
  • ArrayBuffer 的数据,是可以按照字节去操作的,而 Blob 只能作为一个完整对象去处理。Blob 类型可以通过Sice 方法,返回一个新的Blob对象,包含了Blob对象中指定范围内的数据。

Blob 与 ArrayBuffer 对象之间是可以相互转化的:

  • 使用 FileReader 的 readAsArrayBuffer() 方法,可以把 Blob 对象转换为 ArrayBuffer 对象;
  • 使用 Blob 构造函数,如 new Blob([new Uint8Array(data]); ,可以把 ArrayBuffer 对 象转换为 Blob 对象。
function BlobToArryBuffer() {

    const fileReader = new FileReader()

    fileReader.readAsArrayBuffer(saveBlob)

    console.log('转换前的Blob', saveBlob)

    fileReader.onload = function () {

      console.log('转换后的ArrayBuffer', fileReader.result)

      arryBuffer = fileReader.result

    }

  }

  function ArrayBufferToBlob() {

    console.log('转换前的ArrayBuffer', arryBuffer)

    const blob = new Blob([new Uint8Array(arryBuffer)], { type: "image/jpeg"             })  

    console.log('转换后的Blob', blob)

  }

使用总结

  1. 通过将跨域资源文件转换成 blob 伪协议,跳过跨域问题。使用场景,下载跨域文件资源
  2. 将blob转换成 base64,对于一些小文件可以减少请求,优化页面的加载