文件下载
下载文件hooks
import { useUserStore } from '@/store/modules/user';
// 下载文件
export default function useDownloadFile() {
const userStore = useUserStore();
const downloadFile = (url, fileName) => {
const a = document.createElement('a');
a.href = url;
a.download = fileName || '';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
};
const downloadFileByGet = ({ url, params, fileName = '' }) => {
try {
const newUrl = new URL(`${import.meta.env.VITE_BASE_API_URL}/${url}`);
newUrl.searchParams.set('x-token', userStore.token || '');
if (params) {
Object.keys(params).forEach((key) => {
newUrl.searchParams.set(key, params[key]);
});
}
downloadFile(newUrl.href, fileName);
} catch (err) {
console.log('err', err);
}
};
const downloadByPost = ({ data, fileName }: { data: Blob; fileName?: string }) => {
const url = URL.createObjectURL(new Blob([data], { type: 'application/octet-stream' }));
downloadFile(url, fileName);
};
return {
downloadFile,
downloadFileByGet,
downloadByPost,
};
}
下载文件流二进制处理
调用后端接口返回的二进制流,进行下载
-
1、需要设置响应头
responseType为blob- 这样就可以正确接受到响应体为blob二进制类型
-
2、转换压缩类型:blob,如果下载的是zip压缩包,需要指定type为
application/zipconst blob = new Blob([data], { type: 'application/zip' }); -
3、把blob转换为url
- 通过创建临时的URL
-
4、在把url链接添加到a标签进行模拟下载
-
5、获取二进制请求头返回的文件名
- 后端需在响应头中暴露
Content-Disposition- 服务端配置响应头:
Access-Control-Expose-Headers: Content-Disposition
- 服务端配置响应头:
// 解析响应体获取请求头文件名export const parseFilename = (response) => {const disposition = response.headers['content-disposition'];// 匹配RFC5987编码格式const utf8Match = disposition.match(/filename\*=(?:UTF-8'')?(.+?)(?:;|$)/i);if (utf8Match) {return decodeURIComponent(utf8Match[1]);}// 匹配基础文件名格式const baseMatch = disposition.match(/filename=["']?([^;"']+)["']?/i);return baseMatch ? baseMatch[1].replace(/['"]/g, '') : 'download';}; - 后端需在响应头中暴露