前端文件下载兼容方案(兼容主流浏览器,包括IE与Safari)

13,430 阅读3分钟

2018年10月26日更新

评论区大家提出了很多留存的问题,比如说不能兼容IE11,不能下载txt和video文件等问题。txt和video的下载问题我还没有证实。不过这些意见都十分可贵。

另外还有人给出了一系列的解决方案,比如利用jszip实现文件批量打包下载;使用fileSaver.js + Blob的方式进行文件下载等。虽然我还没来得及去一一验证,但是很感谢大家给出的宝贵方案,也为浏览到本篇文章的读者们提供了一条解决问题的思路。

虽然让人难以置信,但是我刚才试了一下,直接对location赋值的方式进行文件下载,实验结果竟然相当好,不但在IE11中能够正常下载,在Safari中也可以正常下载。

具体实现方式如下:

window.location.href = yourFilePath

这里的yourFilePath是调用后台文件下载的接口地址。后台在接口中返回文件流供前端下载。

其实我在下面所说的downLoadTemplateURL也是指的后台文件下载的接口地址。一开始表述的不太清晰,可能会造成一部分读者的误解,在此特地声明一下。


之前处理文件下载功能一直使用的是window.open(URL)的方式。这样当然也是可以实现文件下载功能的,而且使用起来还很方便。

但是有一次测试发现这个方法在Safari浏览器中并不能正常下载,于是我又开始寻找兼容性更好的下载功能实现方案。今天给大家推荐的是一个我目前一直在使用,而且到目前为止还没有发现兼容性问题的一个解决方案。当然,如果大家在使用过程中发现此方案存在什么bug,也欢迎在评论区进行发言,发现问题,解决问题,才能促使大家共同成长。

其实html中的<a>标签不光有导航链接的作用,同时还能实现文件下载功能。具体用法如下:

<a id="downLoadExcel" :href="downLoadTemplateURL" :download="filename"></a>

<a>标签中添加download属性即可实现点击下载功能。这里最好在前端指定下载的文件名,因为有时候通过后台提供文件名会产生乱码,而由前端指定文件名则完全没有这方面的顾虑。

downLoadTemplateURLfilename都是通过动态赋值的,这样,无论是在开发环境还是生产环境,代码都可以复用,不需要进行修改。

具体实现代码如下:

downLoadExcelTemplate() {
    const vm = this
    vm.downLoadTemplateURL = vm.apiHost + "downloadYourFileURL"
    vm.filename = "myTest.pdf"
    setTimeout( () => {
      document.querySelector("#downLoadExcel").click()
    },500)
  },

我这里采用的是点击自定义按钮,在自定义按钮的点击事件中主动触发 <a> 标签的点击事件的方法。这样可以在触发下载文件功能前进行额外操作。

至于对click进行延迟触发——也就是使用setTimeout()方法,是为了在修改下载路径和文件名后给浏览器预留足够的时间将变量值渲染到<a>标签中。否则在触发click事件时,对应值还没有成功渲染,会导致无法成功下载。

经过测试这个方法是完全能够满足绝大部门需求的,如果你还有什么其他方案,欢迎分享出来,大家一起学习,共同进步。

结束语

如果你喜欢本篇文章欢迎点赞、关注。你的支持是我继续分享的最大动力。