下载
后端会返回二进制数据,需要前端对响应进行处理并下载
直接打开
直接打开后端下载接口地址
ts
window.open('http://www.baidu.com/api/download')缺陷:
无法命名
无法进行权限验证(无法带token)
只适用于get直接返回Blob的接口
使用a标签的download
原生下载
原生下载不会占用浏览器内存,从后端直接传输到计算机本地,不会将文件存在浏览器内存中。
html
<a href="http://api.com/download" download="demo.xls"> </a>ajax下载
原生下载无法携带鉴权信息,因此我们会使用ajax下载对象并存在浏览器内存中,再模拟a标签的下载能力下载
- 使用URL.createObjectURL创建内存URL
- 创建a标签
- 设置a标签的href指向内存URL,download设置文件名
- 模拟点击a标签
- 下载完成
ts
<template>
<div>
<button @click="downloadFile">下载文件</button>
</div>
</template>
<script setup lang="ts">
import axios from 'axios'
const downloadFile = async () => {
try {
// 1️⃣ 用 axios 获取文件,注意 responseType
const response = await axios.get('/api/file/download', {
responseType: 'blob', //必须设置,转为Blob
})
// 3️⃣ 生成临时 URL
const url = URL.createObjectURL(response.data)
// 4️⃣ 创建 a 标签下载
const a = document.createElement('a')
a.href = url
// 5️⃣ 获取文件名(可从 headers 或自定义)
a.download = 'demo.xls'
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
// 6️⃣ 释放临时 URL
URL.revokeObjectURL(url)
} catch (err) {
console.error('下载失败', err)
}
}
</script>ajax缺陷
ajax下载得到了文件会存在浏览器内存中,如果文件过大,那么将会造成浏览器的卡顿。因为浏览器需要将文件下载到内存中再执行下一步操作
file-saver
file-saver对使用a标签的download进行下载进行了封装,我们可以直接使用
