V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lsqy
V2EX  ›  前端开发

前端通过 Blob 实现文件下载

  •  
  •   lsqy ·
    lsqy · 2019-12-19 11:41:38 +08:00 · 3051 次点击
    这是一个创建于 1561 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近遇到一个需求,需要将页面中的配置信息下载下来供用户方便使用,以前这个场景的需求有时候会放到后端处理,然后给返回一个下载链接。其实并不需要这么麻烦,这样既增大了服务器的负载,也让用户产生了没有必要的网络请求,现在前端也是可以直接通过Blob对象进行前端文件下载了,下面简单记录下相关实现

    Blob 对象简要介绍

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

    语法

    const aBlob = new Blob( array, options ); 
    
    

    参数说明

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

    示例

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

    URL.createObjectURL() 与 URL.revokeObjectURL()介绍

    URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的 URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的 URL 对象表示指定的 File 对象或 Blob 对象。相当于这个方法创建了一个传入对象的内存引用地址

    createObjectURL 语法

    objectURL = URL.createObjectURL(object);
    

    参数说明

    • object 是用于创建 URL 的 File 对象、Blob 对象或者 MediaSource 对象。​

    返回值

    • 一个可以引用到指定对象的DOMString

    URL.revokeObjectURL() 静态方法用来释放一个之前已经存在的、通过调用 URL.createObjectURL() 创建的 URL 对象。当你结束使用某个 URL 对象之后,应该通过调用这个方法来让浏览器知道不用在内存中继续保留对这个文件的引用了。

    你可以在 sourceopen 被处理之后的任何时候调用 revokeObjectURL()。这是因为 createObjectURL() 仅仅意味着将一个媒体元素的 src 属性关联到一个 MediaSource 对象上去。调用revokeObjectURL() 使这个潜在的对象回到原来的地方,允许平台在合适的时机进行垃圾收集

    revokeObjectURL 语法

    window.URL.revokeObjectURL(objectURL);
    

    参数说明

    • objectURL 是一个 DOMString,表示通过调用 URL.createObjectURL() 方法产生的 URL 对象。

    内存管理

    在每次调用createObjectURL() 方法时,都会创建一个新的 URL 对象,即使你已经用相同的对象作为参数创建过。当不再需要这些 URL 对象时,每个对象必须通过调用 URL.revokeObjectURL() 方法来释放。浏览器会在文档退出的时候自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。

    实际运用

    比如在某后台管理中希望将用户的几个配置信息导入到一个json文件当中供用户下载下来

    代码实现如下:

    const config = {
      name: 'lsqy',
      password: 'yourpassword',
      ak: 'XXXXXXXXXX',
      sk: 'XXXXXXXXXX'
    }
    
    const blobContent = new Blob(
      [JSON.stringify(config, null, 2)],
      {type : 'application/json'}
    );
    
    const blobUrl = window.URL.createObjectURL(blobContent)
    
    downloadFileByBlob(blobUrl, 'config.json')
    
    function downloadFileByBlob(blobUrl, filename) {
      const eleLink = document.createElement('a')
      eleLink.download = filename
      eleLink.style.display = 'none'
      eleLink.href = blobUrl
      // 触发点击
      document.body.appendChild(eleLink)
      eleLink.click()
      // 然后移除
      document.body.removeChild(eleLink)
    }
    
    
    

    执行上面的代码,我们可以得到一个config.json的文件,可以看到,其实很简单就实现了这个场景需求,当然这里是下载的json文件,下载其他的文件也是一样的道理,只是需要得到相应文件的blob数据,再结合相应的MIME类型即可;

    兼容性方面目前主流浏览器都已支持,ie10 以及以上也支持。

    另外Blob结合URL.createObjectURL()URL.revokeObjectURL()还可以用在预览图片、预览 PDF、视频链接防盗等多种场景中,大家可以发挥自己的想象力来进行实现

    参考链接

    文章首发自个人博客

    2 条回复    2019-12-19 12:45:45 +08:00
    newbieRenew
        1
    newbieRenew  
       2019-12-19 12:09:26 +08:00 via iPhone
    之前也做过一样的,下载 json。a 连接并不需要 append 到 dom 里,直接调用 click()就行了
    bshu
        2
    bshu  
       2019-12-19 12:45:45 +08:00 via Android
    FileSaver.js ,可直接用的轮子。另外送你给大坑,国产手机浏览器都无法下载。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1366 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 23:34 · PVG 07:34 · LAX 16:34 · JFK 19:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.