跳到主要内容

文件下载

下载文件hooks​

js
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/zip

    js
    const blob = new Blob([data], { type: 'application/zip' });
  • 3、把blob转换为url

    • 通过创建临时的URL
  • 4、在把url链接添加到a标签进行模拟下载

  • 5、获取二进制请求头返回的文件名

    • 后端需在响应头中暴露Content-Disposition
      • 服务端配置响应头: Access-Control-Expose-Headers: Content-Disposition
    js
    // 解析响应体获取请求头文件名
    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';
    };