场景: 后端返回的下载链接为cdn链接,而cdn链接不能直接作为下载的链接地址
解决方案(步骤):
1. 向后端请求得到CDN的下载地址
2. 通过ajax的方式向cdn链接请求
3. 将请求得到的结果转成二进制流
4. 再将其变成一个下载的链接赋值给a标签的href属性,并自动触发a标签的下载
// 这里是批量下载,请求的谷歌云的链接
const ajax = (url, callback, options) => {
window.URL = window.URL || window.webkitURL;
const xhr = new XMLHttpRequest();
xhr.open('get', url, true);
if (options.responseType) {
xhr.responseType = options.responseType;
}
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
callback(xhr);
}
};
xhr.send();
};
// 生成符合可以请求的地址
const downloadAjax = (url) => {
const innerurl = url; // 文件地址
const name = url.replace(/(.*\/)*([^.]+).*/ig, '$2');
let filename = `${name}.${innerurl.replace(/(.*\.)/, '')}`;
filename = filename?.split('?')[0];
return new Promise((resolve) => {
ajax(innerurl, (xhr) => {
const p = { xhr, filename };
resolve(p);
}, {
responseType: 'blob',
});
});
};
const downUrlList = [] // 这里是链接的数组
const arr = [];
for (let index = 0; index < downUrlList?.length; index++) {
const url = downUrlList[index];
arr.push(downloadAjax(url?.replace('http://1.2.3.4', '/gcp')));
// 本地就需要切换成这个 由于会跨域:'http://1.2.3.4' 这个就需要替换
// arr.push(downloadAjax(url));
// 生产环境配置好跨域,直接传url就行,在开发环境就需要进行代理解决跨域问题
}
Promise.all(arr).then((res) => {
res.forEach((i) => {
const { xhr, filename } = i;
const content = xhr?.response;
const a = document.createElement('a');
const blob = new Blob([content]);
const urls = window.URL.createObjectURL(blob);
a.href = urls;
a.download = filename;
a.click();
window.URL.revokeObjectURL(urls);
});
})
下载时会遇到跨域问题,上面的代理是一种方法,但也可以试一试简单的方式
// 方式一
location.href = 'http://1.2.3.4/2342/2342.jpg'
// 方式二
window.open('http://1.2.3.4/123/2345.png')
有不当之处还望各位大佬指点