一、前言
两种实现文件下载的方法:
二、同域下载
- 由于
a.download在跨域的情况下会失效,下列代码只可同域实现
function downloadFile(url, filename) {
const a = document.createElement('a');
a.href = url;
a.download = filename || '';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
三、跨域下载
1.解析为Blob对象
function getBlob(url) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = () => {
if(xhr.status === 200) {
resolve(xhr.response);
}
};
xhr.send();
});
}
2.获取文件扩展名
function getUrlExtension(url) {
return url.split(/[#?]/)[0].split('.').pop().trim();
}
3.调用
getBlob(fileUrl).then(blob => {
// 创建一个隐藏的<a>标签用于触发下载
let link = document.createElement("a")
// 隐藏链接,不显示在页面上
link.style.display = 'none'
// 设置下载文件名:自定义文件名 + 原始文件扩展名
link.download = `${customizeFileName}.${getUrlExtension(fileUrl)}`
// 创建Blob对象的URL并设置为链接的href
link.href = window.URL.createObjectURL(blob)
// 将链接临时添加到DOM中(某些浏览器需要元素在DOM中才能触发点击)
document.body.appendChild(link)
// 模拟点击链接触发下载
link.click()
// 下载完成后移除临时链接
document.body.removeChild(link)
})
4.完整代码案例及注释
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Document</title>
</head>
<body>
<button>下载</button>
</body>
<script>
let button = document.querySelector('button');
let customizeFileName = '自定义文件名';
let fileUrl = 'https://so1.360tres.com/t0165f9b1a3dca6c254.jpg';
function getBlob(url) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = () => {
if(xhr.status === 200) {
resolve(xhr.response);
}
};
xhr.send();
});
}
function getUrlExtension(url) {
return url.split(/[#?]/)[0].split('.').pop().trim();
}
button.addEventListener('click', function() {
getBlob(fileUrl).then(blob => {
let link = document.createElement("a");
link.style.display = 'none';
link.download = `${customizeFileName}.${getUrlExtension(fileUrl)}`;
link.href = window.URL.createObjectURL(blob);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
});
</script>
</html>