如何通过接口下载文件

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

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

设置 responseType 为 blob

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

ts
export function getFileFromApi() {
	return axios.get({
		url: `/xxx`,
		responseType: 'blob'
	})
}

获取文件名

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

content-disposition 响应头示例

text
content-disposition: attachment;filename="example.xlsx"
ts
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 标签下载文件

ts
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);
}

使用方式

ts
getFileFromApi().then(response => {
  downloadBlobFile(response.data, getFilename(response) || "example.xlsx")
})
CSS 垂直居中的几种方式
Vue 中的特殊变量 $event

评论区

评论加载中...