一、目前接触到的前端下载文件的两种形式
- 接口直接返回
url
,通过 js手动创建a
标签、属性src
指向返回的url
,模拟点击事件来进行下载。 - 接口直接返回
数据流
或是base64
格式数据、这类数据就需要用的 blob 对象和 URL.createObjectURL() 来手动生成url了,然后再通过模拟点击事件来进行下载。
二、具体操作code(主要是第二种方法)
1、blob 数据需要设置请求的返回type
request 文件: file 需要下载的话传个 true
// fetch
function request(params, file){
const { api, method="POST", data={} } = params;
const url = window.location.origin + api;
const config = {
method,
headers: { 'Content-Type': 'application/json', },
body: JSON.stringify(data)
}
// 判断是否是file请求
// 是的话需要设置返回blob 格式数据
file? config['responseType']='blob':void 0;
return fetch(url,config)
.then((response) => file? response.blob():response.json())
.catch((error) => console.log("error",error))
}
// 导出
export function orderExport(){
return request({ api:"/export", }, true)
}
文件code
fileExport = () =>{
orderExport().then(res=>{
// 1 生成文件的 blob 对象 // 指定转换成blob的类型 => 使用 Blob 创建一个指向类型化数组的URL
const blobData = new Blob([res], { type: "application/octet-stream" });
if(blobData instanceof Blob){
// 2 手动生成文件的 url
const url = window.URL.createObjectURL(blobData);
// 3 创建 a 标签,模拟点击事件
const link = document.createElement('a');
link.href = url;
// 3.1 重命名下载文件名称
link.download = `文件名称.xls`;
document.body.appendChild(link);
const evt = document.createEvent('MouseEvents');
evt.initEvent('click', false, false);
link.dispatchEvent(evt);
document.body.removeChild(link);
} else console.log("导出失败")
})
}
> 其中亮点是重名文件名称、通过事件派发点击事件,而不是直接 dom.click() > 原因是:为了防止有些浏览器可能会发生点击失效的问题。
document.createEvent()
event.initEvent()
element.dispatchEvent()
参考文档:MDN URL.createObjectURL:https://developer.mozilla.org/zh-CN/docs/Web/API/URL/createObjectURL
参考文档:MDN blob: https://developer.mozilla.org/zh-CN/docs/Web/API/Blob