后端通常会以文件流的形式将文件返回给前端,前端需要将获取到的文件内容转换成 blob 类型的数据,然后再下载到本地。
设置 responseType 为 blob
以 axios 为例,通过设置 responseType 为 blob 把指定响应数据的类型指定为 Blob 对象
export function getFileFromApi() {
return axios.get({
url: `/xxx`,
responseType: 'blob'
})
}
获取文件名
可以从 content-disposition 响应头中拿到后端返回的文件名,当然也可以前端自定义文件名
content-disposition 响应头示例
content-disposition: attachment;filename="example.xlsx"
const getFilename = (response: AxiosResponse): string => {
let filename = "";
const contentDisposition = response.headers["content-disposition"];
// 可匹配:
// attachment; filename="example.xlsx"
// attachment; filename=example.xlsx
// attachment; filename*=UTF-8''example.xlsx
const fileNameMatch = contentDisposition?.match(/filename\*?=['"]?(?:UTF-\d['"]*)?([^;\r\n"']*)['"]?;?/);
if (fileNameMatch?.length === 2) filename = decodeURIComponent(fileNameMatch[1]);
return filename;
};
通过 a 标签下载文件
const downloadBlobFile = (data: BlobPart, fileName: string): void => {
const blob = new Blob([data]);
const link = document.createElement("a");
link.download = fileName;
link.style.display = "none";
link.href = URL.createObjectURL(blob);
link.target = "blank";
document.body.appendChild(link);
link.click();
URL.revokeObjectURL(link.href); // 释放 URL 对象
document.body.removeChild(link);
}
使用方式
getFileFromApi().then(response => {
downloadBlobFile(response.data, getFilename(response) || "example.xlsx")
})
评论区
评论加载中...