发布于 

如何通过接口下载文件

后端通常会以文件流的形式将文件返回给前端,前端需要将获取到的文件内容转换成 blob 类型的数据,然后再下载到本地。

设置 responseType 为 blob

以 axios 为例,通过设置 responseTypeblob 把指定响应数据的类型指定为 Blob 对象

1
2
3
4
5
6
export function getFileFromApi() {
return axios.get({
url: `/xxx`,
responseType: 'blob'
})
}

获取文件名

可以从 content-disposition 响应头中拿到后端返回的文件名,当然也可以前端自定义文件名

content-disposition 响应头示例

1
content-disposition: attachment;filename="example.xlsx"
1
2
3
4
5
6
7
8
9
10
11
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 标签下载文件

1
2
3
4
5
6
7
8
9
10
11
12
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);
}

使用方式

1
2
3
getFileFromApi().then(response => {
downloadBlobFile(response.data, getFilename(response) || "example.xlsx")
})

(●'◡'●)ノ♥