在做文件管理方面的应用时,会遇到文件下载问题。比如点击A标签下载TXT 文件,浏览器不会帮你下载的,而是直接打开给你看。
txt、png、jpg、pdf 等文件,浏览器是直接浏览的;当然,可以通过右击a链接另存为的方式来达到下载的目的。
一般,我们可以使用 a.download 属性来达到点击下载目的,不过 download 不支持跨域的文件的下载。想在浏览器端流畅的下载文件,跨域下载的问题必须解决。现在有一个思路是:将文件的内容从服务端先拿回来(前提是服务端的文件支持跨域访问),然后再下载。
// 是否支持a的download。请使用Chrome 14+或Firefox 20+
const isSupportDownload = 'download' in document.createElement('a');
// 是否支持 Blob。请使用Chrome 20+或Firefox 13+
const isSupportBlob = 'Blob' in window;
/**
* 下载文件(支持跨域【服务端的文件支持跨域访问】)
* @path 下载地址
* @name 下载文件的名字
*/
function downloadFile (path, name) {
if(!isSupportDownload){
alert('当前浏览器不支持 a 的download属性。请使用Chrome 14+或Firefox 20+');return;
}
if(!isSupportBlob){
alert('当前浏览器不支持 Blob。请使用Chrome 20+或Firefox 13+');return;
}
if(!path){
alert('path 不能为空');return;
}
// 将 \ 转换为 /
let _path =path.replace(/\\/g,'/');
//获取文件的内容
let xhr = new XMLHttpRequest();
xhr.open('get', _path);
xhr.responseType = 'blob';
xhr.onload = function () {
if (this.status === 200 || this.status === 304) {
// 将文件的内容转换为 URL
let url = URL.createObjectURL(this.response);
//使用 a 标签下载文件
let aLink = document.createElement('a');
aLink.style.display = 'none';
aLink.href = url;
//设置下载文件名
let _urlName =_path.substring(_path.lastIndexOf('/')+1);
_urlName && ( _urlName = _urlName.split('?')[0]);
aLink.download = name || ( _urlName || 'undefined' );
document.body.appendChild(aLink);
aLink.click();
document.body.removeChild(aLink);
URL.revokeObjectURL(url);
}
};
xhr.send();
}
下载示例