a.download 下载txt、png、jpg、gif等文件(支持跨域)

825 阅读1分钟

在做文件管理方面的应用时,会遇到文件下载问题。比如点击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();
}

下载示例