vue实现文件下载

文件下载有很多种方式,本文主要介绍7种。

一、a标签下载


  
  

优点

  • 可以下载txt、png、pdf等类型文件
  • download的属性是HTML5新增的属性
    href属性的地址必须是非跨域的地址,如果引用的是第三方的网站或者说是前后端分离的项目(调用后台的接口),这时download就会不起作用。 此时,如果是下载浏览器无法解析的文件,例如.exe,.xlsx..那么浏览器会自动下载,但是如果使用浏览器可以解析的文件,比如.txt,.png,.pdf....浏览器就会采取预览模式;所以,对于.txt,.png,.pdf等的预览功能我们就可以直接不设置download属性(前提是后端响应头的Content-Type: application/octet-stream,如果为application/pdf浏览器则会判断文件为 pdf ,自动执行预览的策略)

缺点

  • a标签只能做get请求,所有url有长度限制
  • 无法获取下载进度
  • 无法在header中携带token做鉴权操作
  • 跨域限制
  • 无法判断接口是否返回成功
  • IE兼容问题

二、form标签下载

图2-1

  
  

优点

  • 兼容性好,不会出现URL长度限制问题
  • form标签get和post都可以

缺点

  • 无法获取下载进度
  • 无法在header中携带token做鉴权操作
  • 无法直接下载浏览器可直接预览的文件类型(txt、png、pdf会直接预览)
  • 无法判断接口是否返回成功

三、window.open下载


  
  

优点

  • 简单方便直接

缺点

  • 会出现URL长度限制问题
  • 需要注意url编码问题
  • 无法获取下载进度
  • 无法在header中携带token做鉴权操作
  • 无法直接下载浏览器可直接预览的文件类型(txt、png、pdf会直接预览)
  • 无法判断接口是否返回成功

四、iframe下载


  
  

优点

  • 可以下载txt、png、pdf等类型文件

缺点

  • 无法获取下载进度
  • 无法在header中携带token做鉴权操作
  • 无法判断接口是否返回成功
  • 兼容、性能差

五、location.href下载


  
  

优点

  • 简单方便直接
  • 可以下载大文件(G以上)

缺点

  • 会出现URL长度限制问题
  • 需要注意url编码问题
  • 无法获取下载进度
  • 无法在header中携带token做鉴权操作
  • 无法直接下载浏览器可直接预览的文件类型(txt、png、pdf会直接预览)
  • 无法判断接口是否返回成功

六、ajax下载(Blob - 利用Blob对象生成Blob URL

如果后端需要做token验证,那么a、form、iframe、window.open、location.href都无法在header中携带token,这时候可以使用ajax来实现。


  
  

  • responseType
    responseType若不设置,会导致下载的文件可能打不开ajax.responseType = 'blob';
  • new FileReader()
    1.文件下载的接口存在返回失败的情况(例如:服务器连接不上、接口报错等),对于下载失败的情况我们需要在页面上弹出失败提示,而不是将失败信息写进文件里等用户打开,这时候可以使用FileReader去根据响应头里的content-type判断接口是否返回成功;
    2.如果content-type返回application/json表示文件流返回失败,此时直接在页面上弹出失败信息(图6-1);如果是其他格式就认为文件流已经返回。
    图6-1
  • this.getResponseHeader('content-disposition')
    后端返回的文件名称,主要获取后缀名,否则某些浏览器会一律识别为txt,导致下载下来的都是txt
    图6-2
  • new Blob([this.response], {type: '文件类型'}) Application Type 对照表
    1.Blob.type一个字符串,表明该 Blob 对象所包含数据的 MIME 类型。如果类型未知,则该值为空字符串;
    2.对于pdf:type为application/pdf 同时 a标签 不设置download属性(图6-3), 可以直接预览(图6-4)
    图6-3

    图6-4
  • axios中其实已经提供了获取文件上传和下载进度的事件,这里我使用的是原生ajax(axios雷同,只需要修改请求方法)。


    图6-5

优点

  • 可以下载txt、png、pdf等类型文件
  • 可以在header中携带token做鉴权操作
  • 可以获取文件下载进度
  • 可以判断接口是否返回成功

缺点

  • 兼容性问题,IE10以下不可用,注意Safari浏览器,官网给出
    Safari has a serious issue with blobs that are of the type application/octet-stream
  • 将后端返回的文件流全部获取后才会下载

七、ajax下载(Data URL - base64编码后的url


  
  

  • fileSaver
    网上介绍很多,可以自己百度下

优点

  • 可以下载txt、png、pdf等类型文件
  • 可以在header中携带token做鉴权操作
  • 可以获取文件下载进度
  • 可以判断接口是否返回成功

缺点

  • 兼容性问题,IE10以下不可用
  • 将后端返回的文件流全部获取后才会下载

八、大文件下载注意点

  • fileSaver
    批量下载时,总量不超过2G可以用下这个,但是每个浏览器允许下载的最大文件不一样~
    图8-1
  • ajax下载
    如果后端需要对下载接口做token鉴权,此时需要使用ajax获取文件流(第六、七点),可以了解下ajax文件下载原理。
    简单来说,文件下载依赖浏览器特性。前端获取到服务器端生成的字节流,此时数据是存在于js的内存中的,是不可以直接保存在本地的,利用Blob对象和window.URL.createObjectURL对象生成一个虚拟的URL地址,然后在利用浏览器的特性进行下载。
    因此对于ajax下载大文件时,会出现浏览器崩溃情况,此时可以考虑使用链接直接下载或使用分片下载
    图8-2
  • 链接下载
    链接下载需要后端一边去下载要打包的文件,一边把打包好的东西写入这个链接。存在的问题是,如果文件很大,那么这个链接需要一直保持,相当于这个接口一直开着没有结束;而且一旦中间出了什么问题,已经下载的东西也全部废了,因此推荐使用分片下载

相关文章

  • node实现文件上传、下载
  • vue实现文件上传

你可能感兴趣的:(vue实现文件下载)