常用的几种方式
- 使用 a 标签直接点击 url
- 使用 iframe 标签挂载
- 使用 axios请求url 进行 blob 转换,再添加 a 标签
- 使用 表单提交
a 标签点击方式
步骤
-
获取到接口地址 url
-
const link = document.createElement('a') link.style.display = 'none' link.href = url link.setAttribute('download', 'test.zip') link.click()
注意:关于 a 标签的 download 属性用法
优缺点
- 优点1 方式简单,一般都能实现, 不需要额外写进度条
- 优点2 a 标签无需挂载到 dom,只需要给这个a 标签执行 click() 事件就能触发浏览器下载文件
- 缺点 遇到连续点击不同的文件下载时,或网络速度慢时,如果服务器尚未反应时就连续下一个文件下载(请求会被cancel 掉),会出现上一个文件未能下载的情况,也就是只有最后一个点击下载生效
iframe 标签挂载方式
步骤
- 获取到接口地址 url
-
const link = document.createElement('iframe') link.style.display = 'none' link.src = url // 注意 iframe 标签必须挂载到 dom 上,否则无法触发浏览器下载(也是缺点之一) document.body.appendChild(link)
优缺点
- 优点1 方式简单,一般也都能实现,不需要额外写进度条
- 优点2 遇到连续下载不同文件,能避免服务器未反应的情况,即请求不会被cancel(解决 a 标签的问题)
- 缺点1 iframe 标签必须挂载到 dom 上,并且在请求未成功前不能删除
axios请求url 方式
步骤
-
步骤1 需要一个能将请求结果转换成 blob 流格式的 axios 实例,去请求该 url
(此处假设请求方式为 get 请求)
注意:代码中几个比较重要的 api ( 摘取自 MDN )
(1). responseType:
XMLHttpRequest.responseType属性是一个枚举类型的属性,返回响应数据的类型。它允许我们手动的设置返回数据的类型。如果我们将它设置为一个空字符串,它将使用默认的"text"类型。
在工作环境 (Work Environment) 中将 responseType 的值设置为 "document" 通常会被忽略. 当将 responseType 设置为一个特定的类型时,你需要确保服务器所返回的类型和你所设置的返回值类型是兼容的。那么如果两者类型不兼容呢?恭喜你,你会发现服务器返回的数据变成了 null ,即使服务器返回了数据。还有一个要注意的是,给一个同步请求设置 responseType 会抛出一个 InvalidAccessError 的异常。
responseType 支持以下几种值:
(2). FileReader:
FileReader 对象允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
(3). HTTP Header:
content-type 根据实际请求头判断, 普通数据请求中会返回 'application/json; charset=utf-8'
-
步骤2 需要一个文件转换的方法 blobToFile( blob, fileName )
思路是:根据请求返回的 blob 对象,利用 URL.createObjectURL() 获得该文件二进制流的 URL对象,然后再执行新建 a 标签,执行点击(这里与第一种 a 标签方法类似),最后释放这个 URL对象)
-
步骤3 调用请求下载方法,并执行文件转换,即:
// 引入相关文件 import { DOWNLOAD_GET } from './API/get' import blobToFile from from '@/utils/blobToFile' // methods getDownLoadFile() { return DOWNLOAD_GET(`${url}`) } async downLoadFile() { // this.url 是这个文件的地址 // this.fileName 是这个文件的文件名,这里稍后补充如何自动填入 try { const blob = await this.getDownFile(this.url) blobToFile(blob, this.fileName) } }