关于blob:Js之Blob类型以及文件流下载流程

8次阅读

共计 1946 个字符,预计需要花费 5 分钟才能阅读完成。

什么是 blob?

以下是 MDN 的官网解释:

Blob 对象示意一个不可变、原始数据的类文件对象。它的数据能够按文本或二进制的格局进行读取,也能够转换成 ReadableStream 来用于数据操作。
Blob 示意的不肯定是 JavaScript 原生格局的数据。File 接口基于 Blob,继承了 blob 的性能并将其扩大使其反对用户零碎上的文件。
要从其余非 blob 对象和数据结构一个 Blob,请应用 Blob() 构造函数。

实际上 file 对象只是 blob 对象的一个更具体的版本,blob 存储着大量的二进制数据,并且 blobsizetype 属性,都会被 file 对象所继承。
所以,在大多数状况下,blob 对象和 file 对象能够用在同一个中央,例如,能够应用 FileReader 借口从 blob 读取数据,也能够应用 URL.createObjectURL()blob 创立一个新的 URL 对象。

blob 的创立

Blob() 构造函数 容许通过其它对象创立 Blob 对象。比方,用字符串构建一个 blob

var debug = {hello: "world"};
var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'});

构造函数,承受两个参数,第一个为一个数据序列,能够是任意格局的值,例如,任意数量的字符串,Blobs 以及 ArrayBuffers。第二个参数,是一个蕴含了两个属性的对象,其两个属性别离是:

type — MIME 的类型。

endings — 决定 append() 的数据格式,(数据中的 \n 如何被转换)能够取值为 “transparent” 或者 “native”(t 的话不变,n 的话按操作系统转换;t* 为默认)。

blob 的利用

大文件宰割(分片上传)
slice() 办法承受三个参数,起始偏移量,完结偏移量,还有可选的 mime 类型。如果 mime 类型,没有设置,那么新的 Blob 对象的 mime 类型和父级一样。

当要上传大文件的时候,此办法十分有用,能够将大文件宰割分段,而后各自上传,因为宰割之后的 Blob 对象和原始的是独立存在的。

不过目前浏览器实现此办法还没有对立,火狐应用的是 mozSlice(),Chrome 应用的是 webkitSlice(),其余浏览器则失常的形式 slice()

能够写一个兼容各浏览器的办法:

function sliceBlob(blob, start, end, type) {
  type = type || blob.type;
  if (blob.mozSlice) {return blob.mozSlice(start, end, type);
  } else if (blob.webkitSlice) {return blob.webkitSlice(start, end type);
  } else {throw new Error("This doesn't work!");
  }
}

文件流下载

后端返回的数据是文件流的时候,须要在 axios 申请指定 responseType:

// 下载接口 文件下载
export function downloadRes(data) {
  return request({
    timeout: 30000,
    responseType: 'blob',  // 须要指定
    baseURL: 'xxx',
    method: 'post',
    data
  })
}

这是返回的 data 就是 blob 类型数据,然而咱们下载的话还须要一个文件名,后端会默认指定把文件名放在 content-disposition 这个响应头:

let fileName = '';
const contentDisposition = res.headers['content-disposition'];
if (contentDisposition) {fileName = window.decodeURI(res.headers['content-disposition'].split('=')[1], "UTF-8");
}

创立 blob 对象,创立 reader,监听加载工夫,创立 a 标签,模仿点击事件,移除 a 标签。这就是一个文件流下载的根本流程:

const blob = new Blob([res.data]);
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = (e) => {const a = document.createElement('a');
    a.download = fileName;
    a.href = e.target.result;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
}
正文完
 0