背景:后端已经将zip文件的URL传过来,前端需要带token下载这个zip文件
下载函数如下
function getFilenameFromHeadersOrUrl(disposition: string | undefined, url: string) {
let filename = '';
if (disposition) {
const m1 = disposition.match(/filename\*\s*=\s*UTF-8''([^;]+)/i);
const m2 = disposition.match(/filename\s*=\s*"?([^";]+)"?/i);
filename = decodeURIComponent((m1?.[1] || m2?.[1] || '').trim());
}
if (!filename) {
const parts = url.split('/');
filename = decodeURIComponent(parts[parts.length - 1] || 'download');
}
return filename;
}
async function downloadFile(url: string) {
const safeUrl = encodeURI(url);
try {
downloading.value = true;
const response = await axios.get(safeUrl, {
responseType: 'blob',
headers: {
Authorization: `Bearer ${localStorage.getItem('userToken')}`,
},
onDownloadProgress: (evt) => {
// total 可能为空(服务器未返回 Content-Length)
if (typeof evt.total === 'number' && evt.total > 0) {
downloadPercent.value = Math.min(100, Math.floor((evt.loaded / evt.total) * 100));
} else {
downloadPercent.value = null;
}
},
});
// 1) 尝试从 Content-Disposition 拿文件名
const disposition = response.headers?.['content-disposition'] as string | undefined;
const filename = getFilenameFromHeadersOrUrl(disposition, url);
downloadFilename.value = filename;
const blob = response.data as Blob;
const downloadUrl = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(downloadUrl);
message.success('下载成功');
} catch (error) {
console.error('下载失败:', error);
message.error('下载失败,请重试');
} finally {
downloading.value = false;
downloadPercent.value = null;
downloadFilename.value = '';
}
}