初探 Js 中的 Blob、ArrayBuffer、File 、FileRender、FormData

1,826 阅读3分钟

Blob

Blob 对象表示一个不可变、原始数据的类文件对象。

基本使用

语法

const blob = new Blob(array, options)

参数

  • array 是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成,DOMStrings会被编码为UTF-8。
  • options 是一个可选,它可能会指定如下两个属性:
    • type,默认值为 "",内容的MIME类型。
    • endings,默认值为"transparent",用于指定包含行结束符\n的字符串如何被写入。 它是以下两个值中的一个: "native",代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者 "transparent",代表会保持blob中保存的结束符不变

实例属性、方法

  • type 类型 常见的MIME 类型
  • size 大小、单位为字节
  • slice()Blob 中截取一部分并返回一个新的 Blob(用法同数组的 slice)
  • arrayBuffer() 返回一个以二进制形式展现的 promise
  • stream() 返回一个ReadableStream对象
  • text() 返回一个文本形式的 promise 后面三个方法兼容性不太好

示例

    const blob1 = new Blob(['hello blob'],{ type: 'text/plain'})
    console.log(blob1) // Blob {size: 10, type: "text/plain", slice: function}

    const blob2 = new Blob([JSON.stringify({ a: 1 }, null, 2)],{ type: 'application/json'})
    console.log(blob2) // Blob {size: 12, type: "application/json", slice: function}

    const blob3 = blob2.slice(0, 5)
    console.log(blob3) // Blob {size: 5, type: "", slice: function}

应用场景

  • 文件上传、分片上传

    见 File 的使用

  • 文件预览、下载

  <!-- 文件预览 -->
  <canvas id="canvas"></canvas>
  <script>
    const canvas = document.querySelector('#canvas')
    const ctx = canvas.getContext('2d');

    ctx.fillStyle = 'green';
    ctx.fillRect(10, 10, 150, 100);

    // toDataURL
    // data url 生成对应图片的代码片段,可以在任意地方使用(base64)
    createImg(canvas.toDataURL('image/png'))
    function createImg(url) {
      console.log(url)
      const img = document.createElement('img')
      img.src = url
      document.body.appendChild(img)
    }

    // toBlob
    canvas.toBlob((blob) => {
      // blob url 只有在当前窗口下使用,这个 URL 的生命周期和创建它的窗口中的 document 绑定
      const url = window.URL.createObjectURL(blob)
      console.log(url)
      const img = document.createElement('img')
      img.onload = () => {
        // 适当的情况下删除,防止内存泄漏
        window.URL.revokeObjectURL(url)
      }
      img.src = url
      document.body.appendChild(img)

      // blob 借助 FileReader 转 data url(base64)
      // data url 生成对应图片的代码片段,可以在任意地方使用(base64)
      const render = new FileReader()
      render.onload = ({target: { result }}) => {
        console.log(result, 'FileReader')
      }
      render.readAsDataURL(blob)
    })

  </script>
  
  <!-- 文件下载 -->
  <script>
    // txt 文件
    const fileContent1 = new Blob(['hello world', 'hello blob'])
    const downloadText1 = document.createElement('a')
    const href1 = downloadText1.href = window.URL.createObjectURL(fileContent1)
    downloadText1.download="1.txt"
    downloadText1.innerText = 'download 1.txt'
    downloadText1.onclick = () => {
      // 这里不能删除,删除了下次下载就找不到了
      // window.URL.revokeObjectURL(href1)
    }
    document.body.appendChild(downloadText1)

    document.body.appendChild(document.createElement('br'))

    // csv 文件
    const csvData =  [
      ['#', 'name', 'age'],
      [1, '张三', 20],
      [2, 'Owen', 22],
      [3, 'Tom', 18]
    ]
    const fileContentExcel = new Blob(csvData.map(item => `${item.join(',')}\n`))
    const downloadText2 = document.createElement('a')
    const href2 = downloadText2.href = window.URL.createObjectURL(fileContentExcel)
    downloadText2.download="1.csv"
    downloadText2.innerText = 'download 1.csv'
    downloadText2.onclick = () => {
      // 这里不能删除,删除了下次下载就找不到了
      // window.URL.revokeObjectURL(href2)
    }
    document.body.appendChild(downloadText2)
  </script>

File

File 描述文件信息的一个对象,可以让 JavaScript 访问文件信息,预览或者提交给服务端。File 继承于 Blob

基本使用

语法

const file = new File(bits, name[, options])

参数

  • array 是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成,DOMStrings会被编码为UTF-8。
  • name 表示文件名称,或者文件路径。
  • options 是一个可选,它可能会指定如下两个属性:
    • type,默认值为 "",内容的MIME类型。
    • lastModified: 数值,表示文件最后修改时间的 Unix 时间戳(毫秒)。默认值为 Date.now()。

实例属性、方法

  • 继承 Blob 的所有属性、方法
  • lastModified 最后修改时间

产生 File 对象的场景

  • new File() 构造函数
  • 通过 <input type="file" /> 获取文件
  • 自由拖放操作生成的 DataTransfer 对象
  • 通过 CanvasmozGetAsFile() API 生成 已过时

使用 File 对象的场景

  • FileRender 借助FileRender 转换成 data url(base64)、text等
  • URL.createObjectURL() 生成 blob url 做在线预览
   <input type="file" onchange="handlechange(event)" />
   <script>
     function handlechange(event) {
       const {
         target: { files },
       } = event;
       const file = files[0];

       preview(file);
     }
     
     function preview(file) {
       const { type } = file;
       if (!type.startsWith("image")) return;

       const url = window.URL.createObjectURL(file);
       const img = document.createElement("img");
       img.onload = () => {
         // 适当的情况下删除,防止内存泄漏
         window.URL.revokeObjectURL(url);
       };
       img.src = url;
       document.body.appendChild(img);
     }
   </script>
  • createImageBitmap() 剪裁图像 兼容性不好
  // 裁剪图像到上传的过程(这种方式兼容性不好,建议使用 canvas 裁剪)
  // 图像dom -> 裁剪 -> canvas绘制 -> toBlob() -> Ajax上传
  createImageBitmap(img, 0, 0, 32, 32).then((res) => {
    const canvas = document.getElementById("myCanvas");
    const ctx = canvas.getContext("2d");
    ctx.drawImage(res, 0, 0);
  });
  • XMLHttpRequest.send() 上传
   <input type="file" onchange="handlechange(event)" />
   <script>
     function handlechange(event) {
       const {
         target: { files },
       } = event;
       const file = files[0];

       uploadFile(file);
       preview(file);
     }

     function uploadFile(file) {
       const formData = new FormData();

       formData.append(
         "content",
         file
       );
       fetch("http://localhost:3000/upload-file", {
         method: "post",
         body: formData,
       })
         .then((res) => res.json())
         .then((res) => {
           console.log(res, "res");
         });
     }

     function preview(file) {
       const { type } = file;
       if (!type.startsWith("image")) return;

       const url = window.URL.createObjectURL(file);
       const img = document.createElement("img");
       img.onload = () => {
         // 适当的情况下删除,防止内存泄漏
         window.URL.revokeObjectURL(url);
       };
       img.src = url;
       document.body.appendChild(img);
     }
   </script>

ArrayBuffer

ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区。不能直接操作 ArrayBuffer 的内容,而是要通过类型数组对象DataView对象来操作 ArrayBuffer 文档

FileRender

一个转换工具,将 Blob or File 转换成 text、data url(base64)、ArrayBuffer 使用见上面的 File 转 base64

FormData

一种数据格式,用于表单的上传

使用见上面的文件上传

总结

  • Blob、ArrayBuffer、File 都是二进制的数据
  • FileRender 转换工具
  • FormData 通讯数据格式

通过 Ajax 的时候我们可以设置 responseTypeblobArrayBuffer,后端返回流,前端来处理。

博文推荐

【笔记不易,如对您有帮助,请点赞,谢谢】