用fetch发送请求 对请求回来的二进制文件流进行处理
fetch('/upload/user.png').then((res) => {
res.blob().then((blob) => {
const blobUrl = window.URL.createObjectURL(blob);
// 这里的文件名根据实际情况从响应头或者url里获取
const filename = 'user.txt';
const a = document.createElement('a');
a.style.display = 'none'
//这里需要插入body的话,后面需要再移除
a.href = blobUrl;
a.download = filename;
a.click();
window.URL.revokeObjectURL(blobUrl);
});
});
如果是arraybuffer文件
先把arraybuffer转化为
生成Blob对象,设置type等信息
const blobres = res.arrayBuffer();
const fileBlob = new Blob([blobres],{ type: 'application/zip' })
因为上面直接是blob对象,所以这里就接着,上面就ok了
考虑火狐,下载多个场景
ts
复制代码
// 检查浏览器型号和版本
const useBrowser = () => {
const ua = navigator.userAgent.toLowerCase();
const re = /(msie|firefox|chrome|opera|version).*?([\d.]+)/;
const m = ua.match(re);
const Sys = {
browser: m[1].replace(/version/, "'safari"),
version: m[2]
};
return Sys;
};
ts
复制代码
const downloadByUrl = (url: string, filename: string) => {
if (!url) throw new Error('当前没有下载链接');
const a = document.createElement("a");
// 火狐兼容
if (useBrowser().browser === "firefox") {
a.target = "_blank";
}
a.style.display = "none";
a.href = url;
a.download = filename;
// 使用target="_blank"时,添加rel="noopener noreferrer"
//堵住钓鱼安全漏洞 防止新页面window指向之前的页面
a.rel = "noopener noreferrer";
document.body.append(a);
a.click();
setTimeout(() => {
a.remove();
}, 1000);
};
先发送请求获取 blob 文件流,这样就能在请求时进行鉴权;
鉴权通过后再执行下载操作。
Content-Disposition
是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地
同源就直接使用 download 下载
跨域就先获取 blob,
用 createObjectURL 或 readAsDataURL 读取链接,再用 download 下载。
js
复制代码
import downloadByUrl from "@/utils/download";
const download = async () => {
const blob = await fetchFile();
// 生成访问 blob 的 URL
const url = URL.createObjectURL(blob);
// 调用刚刚封装的 a 标签下载方法
downloadByUrl(url, "表格文件.xlsx");
// 删除映射,释放内存
URL.revokeObjectURL(url);
};
js
复制代码
import downloadByUrl from "@/utils/download";
const download = async () => {
const blob = await fetchFile();
// 声明一个 fileReader
const fileReader = new FileReader();
// 将 blob 读取成 base64
fileReader.readAsDataURL(blob);
// 读取成功后 下载资源
fileReader.onload = function () {
downloadByUrl(fileReader.result);
};
};
js
复制代码
export const fetchFile = async (params) => {
return axios.get(api, {
params,
responseType: "blob"
});
};
URL.createObjectURL(blob) 可以直接访问,
无需“编码/解码”,但需要记得撤销(revoke);
而 Data URL 无需撤销(revoke)任何操作,
但对大的 Blob 进行编码时,性能和内存会有损耗。
总而言之,这两种从 Blob 创建 URL 的方法都可以用。
但通常 URL.createObjectURL(blob) 更简单快捷。