这篇文章的产生源于某一天,产品给我提了一个优化问题~ 刚看到这个问题我也挺懵的,难道下载不是点击下载按钮,浏览器下方出现下载进度,静静的等待进度条拉满就好吗?
但是在我们的项目里,下载大文件时(上百兆的这种),会发现点击下载没有任何反应,然后突然看到一个已经拉满的进度条,下载完了。
我也挺好奇为什么这样,因为代码不是我写的,直到我看到了代码
.fetch
*****资源请求地址******,
{ method: 'PUT' }
)
.then(responseData => {
window
.fetch(responseData.url, { cache: 'no-cache' })
.then(res => res.blob())
.then(responseBlob => {
const a = document.createElementNS(
'http://www.w3.org/1999/xhtml',
'a'
) as HTMLAnchorElement;
a.href = URL.createObjectURL(responseBlob);
a.download = fileName;
a.click();
});
我在想为什么不用最简单的方式下载,就像这样:
<a id="a" download="4.png" href="">点我下载</a>
尝试之后果然是我片面了,并没有下载而是在新页面预览了😳 ,没错当时我就是这个表情。我们的资源是放在亚马逊云上的,跨域了啊。难怪前面的同学没有用这么简单的方式,年轻人👱 还是要谦虚呀,我能想到的别人怎么会想不到!
所以还是要找别的办法吧,既然是跨域问题,那就解决跨域问题呗,用什么解决呢,比较常见的iframe先试试咯:
// 下载资源
public downloadResource = (fileName: string, uuid: string) => {
alo7Api
.fetch(`********`,
{ method: 'PUT' }
)
.then(responseData => {
window.fetch(responseData.url, { cache: 'no-cache' }).then(res => {
const { url } = res;
resouseDownloadHelper(url, fileName);
});
})
.catch(error => message.error('下载失败:' + error.message));
};
export function resouseDownloadHelper(url: string, fileName: string) {
if (document.getElementById('iframe')) {
document.body.removeChild(document.getElementById('iframe'));
}
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.id = 'iframe';
iframe.setAttribute(
'src',
'https://s3.cn-north-1.amazonaws.com.cn/**********/download.html'
);
document.body.appendChild(iframe);
iframe.onload = () => {
iframe.contentWindow.postMessage(
{
url,
fileName,
},
'*'
);
};
}
在网页上放一个看不到的download.html,把这个页面也存在亚马逊云上,跨域问题完美规避掉了,下载进度也正常显示。
如果恰好解决了你的问题,帮忙点个赞👍 ~ 初入行小白,评论区欢迎各位大佬指点~