这个问题依旧是因为部门里那个温柔体贴疯狂找茬的测试提出的问题,指出下载默认名称不对,那有啥办法,测试大人都提出来了,改呗
情景再现:
- Q:乍一看这个问题,下载不简单?直接往 a 标签的 href 属性塞个远程链接不就完事了?
- W:但那样的话弹出下载框的默认名字是远程文件的名字耶,名字很乱的
- Q:直接用
download
属性自定义下载默认名不就完事了? - w:这里就要说明一下这个
download
属性了:download
是个h5新增属性,来规定文件的下载名称
但这个方法有个问题,那就是只支持同源策略,跨域情况下这个属性是无效的
显然,在这里我们是远程文件,注定了一定会跨域,只能绕路选择其他办法了
方案一
思路
这里采取的是通过ajax
请求远程文件获取文件数据的方式来处理,分为如下几步
- 将二进制数据转换为blob
通过ajax
请求远程文件url
,获取返回值中的文件blob
数据,即res.data
- 创建本地url
根据blob对象,通过URL.createObjectURL(blob)
API创建本地url,记住最后要通过URL.revokeObjectURL(url)
释放 URL 地址 - 创建a标签
创建a标签,根据本地url设置标签的href
属性,并自定义设置其download
属性,由于是本地url,为同源,因此download
属性有效 - 模拟点击a标签下载文件
将a标签添加入文档流中,通过click()
模拟点击a标签,然后将其移除文档流就可以了
代码
引入需要类库,这里使用 axios 发出 ajax 请求
1 | import axios from 'axios' |
点击下载触发函数 downloadFile:
1 | downloadFile(file) |
请求处理函数 downloadHandle:
1 | downloadHandle(response, fileName = '') |
方案二
- q:上面这些好麻烦啊,又不想努力,只能找找类库两行代码解决才能维持的了生计这个样子
- w:那可以试试这个插件:
FileSaver.js
FileSaver.js
- 安装
1 | npm install file-saver --save |
- 引用
1 | import FileSaver from 'file-saver' |
- 使用
1 | FileSaver.saveAs(Blob / File / Url, filename) |
使用 FileSaver.js 实现问题需求
1 | import FileSaver from 'file-saver' |
一行搞定,喜大普奔
后记
不过个人还是建议学会或者直接使用方案一中的方法,毕竟使用类库会增大项目大小,而且本质也不麻烦,程序员本来就是需要不断地学习,一味使用别人插件那不就是搬砖工了吗其实我只是懒得学各种类库插件啊哈哈