实现下载文件功能

381 阅读3分钟
  const { userAgent } = navigator;

  
  downLoadMethods (data, fileName = '') {
    if (!data) {
      return;
    }
    if (!fileName) {
      const disposition = data?.headers['content-disposition'];
      const reg = /(filename=)(.+)/
      fileName = disposition.match(reg)[0] || ''

      if (fileName) {
        fileName = fileName.split('=')[1]
      }
    }
    const blob = new Blob([data.data]);
    if ('download' in document.createElement('a')) { // 非IE下载
      const elink = document.createElement('a');
      elink.download = fileName;
      elink.style.display = 'none';
      elink.href = URL.createObjectURL(blob);
      document.body.appendChild(elink);
      elink.click();
      URL.revokeObjectURL(elink.href); // 释放URL 对象
      document.body.removeChild(elink);
    } else { // IE10+下载
      navigator.msSaveBlob(blob, fileName);
    }
  },

Blob类型

参考:www.jianshu.com/p/b322c2d5d…

满足的特殊需求

  1. mysql中的Blob类型表示二进制数据的容器
  2. 在web中,Blob类型的对象表示不可变的类型文件对象的原始对象,即,Blob对象时二进制数据,但它是蕾丝文件对象的二进制数据,因此可以像操作File对象一样操作Blob对象,实际上File继承自Blob

基本用法

  1. 可以通过Blob的构造函数创建Blob对象
Blob(blobParts[,options])

参数说明: blobParts:数据类型,数组中的每一项连接起来构成Blob对象的数据,数组中的每项元素可以是ArrayBuffer(二进制数据缓冲区),ArrayBufferView,Blob,DOMString。或其他类型对象的混合体。

options:可选项,字典格式类型,可以制定如下两种属性:

  • type,默认值为“”,它代表了将会被放入到blob中的数组内通的MIME类型

  • endings,默认值为“transparent”,用于指定包含行结束符\n 的字符串如何被写入。它是以下两个之中的一个:“native”,表示行结束符会被更改为合适宿主操作系统文件系统的换行符,“transparents”,表示会保持blob中保存的结束符不变

 var data1 = "a";
    var data2 = "b";
    var data3 = "<div style='color:red;'>This is a blob</div>";
    var data4 = { "name": "abc" };

    var blob1 = new Blob([data1]);
    var blob2 = new Blob([data1, data2]);
    var blob3 = new Blob([data3]);
    var blob4 = new Blob([JSON.stringify(data4)]);
    var blob5 = new Blob([data4]);
    var blob6 = new Blob([data3, data4]);

    console.log(blob1);  //输出:Blob {size: 1, type: ""}
    console.log(blob2);  //输出:Blob {size: 2, type: ""}
    console.log(blob3);  //输出:Blob {size: 44, type: ""}
    console.log(blob4);  //输出:Blob {size: 14, type: ""}
    console.log(blob5);  //输出:Blob {size: 15, type: ""}
    console.log(blob6);  //输出:Blob {size: 59, type: ""}

size代表Blob 对象中所包含数据的字节数。这里要注意,使用字符串和普通对象创建Blob时的不同,blob4使用通过JSON.stringify把data4对象转换成json字符串,blob5则直接使用data4创建,两个对象的size分别为14和15。blob4的size等于14很容易理解,因为JSON.stringify(data4)的结果为:"{"name":"abc"}",正好14个字节(不包含最外层的引号)。blob5的size等于15是如何计算而来的呢?实际上,当使用普通对象创建Blob对象时,相当于调用了普通对象的toString()方法得到字符串数据,然后再创建Blob对象。所以,blob5保存的数据是"[object Object]",是15个字节(不包含最外层的引号)。

Blob的使用场景

  1. 分片上传
  2. Blob URL
  3. Blob URL和Data URL有什么区别 (1)1. Blob URL得长度一般比较短,但Data URL因为直接存储图片base64编码后得数据,往往很长。当显示大图片时,使用Blob URL更优。

(2)Blob URL可以方便的使用XMLHttpRequest获取源数据,对于Data URL, 并不是所有浏览器都支持通过XMLHttpRequest获取源数据的。

(3) Blob URL只能在当前应用内部使用,把Blob URL复制到浏览器的地址栏中,是无法获取数据的。Data URL相比之下,就有很好的移植性,你可以在任意浏览器使用。

URL.createObjectURL

会静态创建一个DOMString,其中包含一个URL用来表示参数中给出的对象

附录

  1. 内存管理

每次调用createObjectURL方法的时候,都会创建一个新的URL对象,即使你已经用相同的对象作为参数创建过,当不在再需要这些URL对象时,每个对象必须通过调用URL.revokeObjectURL方法来释放

浏览器在 document 卸载的时候,会自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。