各种下载文件方式总结

文件下载有多种方式,链接跳转方式下载,打开新页面下载,ajax下载文件。

以前ajax是不能下载文件的,现在的xhr2版本支持blob,可以将文件下载到内存中,然后弹出保存框,保存到本地。

这样不能下载太大的文件,内存会被撑爆。新的fetch Api也可以下载文件。

示例如下:

1. 跳转下载

function location_download(){
     location.href = '/file/build';
}

2. 超链接下载(可自由调整为本页下载或新开页面下载)

<a class="btn" download="data.zip" target="_blank" href="/file/build">
   超链接直接下载
</a>

3. 模拟超链接下载

function simulateA_download() {
    var a = document.createElement('a');
    a.href = '/file/build';
    //文件名无效
    a.download = 'data.zip';
    document.body.appendChild(a);
    a.click()
    document.body.removeChild(a);
}

4. 原生xhr下载

function ajax_download(){
    var url = '/file/build';
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);    // 也可以使用POST方式,根据接口
    xhr.responseType = "blob";  // 返回类型blob
    // 定义请求完成的处理函数,请求前也可以增加加载框/禁用下载按钮逻辑
    xhr.onload = function () {
        // 请求完成
        if (this.status === 200) {
            // 返回200
            var blob = this.response;
            var reader = new FileReader();
            reader.readAsDataURL(blob);  // 转换为base64,可以直接放入a表情href
            reader.onload = function (e) {
                // 转换完成,创建一个a标签用于下载
                var a = document.createElement('a');
                //文件名有效
                a.download = 'data.zip';
                //会造成跳转到空白页,解决方案???
                a.href = e.target.result;
                a.target = '_self';
                document.querySelector("body").appendChild(a);  // 修复firefox中无法触发click
                a.click();
                a.parentNode.remove();
            }
        }
    };
    // 发送ajax请求
    xhr.send()
}

5. axios下载

function axios_download(){
    let url = '/file/build';
    let fileName = 'data_axios.zip';
    let type = fileName;

    return axios({
        method: 'get',
        url: url,
        responseType: 'blob',
        headers: {
            'content-disposition': `attachment;filename=${type}`,
            'content-type': 'application/x-download;charset=utf-8'
        }
    })
    .then(res => {
        const blob = new Blob([res.data], {type: type})
        const url = window.URL.createObjectURL(blob)
        const link = document.createElement('a')
        link.style.display = 'none'
        link.href = url
        //文件名有效
        link.setAttribute('download', fileName)
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
    })
}

6. superagent下载

function superagent_download(){
    let url = '/file/build';
    let fileName = 'data_super.zip';
    let type = fileName;

    return superagent.get(url)
                        .set('content-disposition', `attachment;filename=${type}`)
                        .set('content-type', 'application/x-download;charset=utf-8')
                        .type('blob')
                        .then(res => {
                        const blob = new Blob([res.data], {type: type})
                        const url = window.URL.createObjectURL(blob)
                        const link = document.createElement('a')
                        link.style.display = 'none'
                        link.href = url
                        //文件名有效
                        link.setAttribute('download', fileName)
                        document.body.appendChild(link)
                        link.click()
                        document.body.removeChild(link)
                    })
                        
}

7. fetch下载

function fetch_download() { 
    //可以先提示'文件下载中...',这样在下载框弹出之前,用户体验会好很多
    var url = "/file/build"; 
    fetch(url).then(res => res.blob().then(blob => { 
        var a = document.createElement('a'); 
        var url = window.URL.createObjectURL(blob);   // 获取 blob 本地文件连接 (blob 为纯二进制对象,不能够直接保存到磁盘上)
        var filename = res.headers.get('Content-Disposition');
        a.href = url; 
        a.download = filename.split('filename=')[1];
        a.click(); 
        window.URL.revokeObjectURL(url); 
        //提示'下载完成'; 
    })); 
}

 8. 构造form下载

function form_download(values){
    let url = '/file/build';
    try{
        let form = document.createElement('form');
        //用target指向iframe会打开新页面,原因是?????
        //form.target = 'ifr-down';
        form.action = url;
        form.method = 'get';

        if(values && typeof values == 'object'){
            Object.keys(values).forEach(item => {
                form.insertAdjacentHTML('beforeend', `<input type="hidden" name="${item}" value="${values[item]}"/>`);
            })
        }

        let iframe = document.createElement('iframe');
        iframe.id = 'ifr-down';
        iframe.style = 'display:none';
        iframe.src = "about:blank";
        iframe.onload = function(){
            iframe.onload = null;
            //document.body.removeChild(form);
            //document.body.removeChild(iframe);
        }
        //document.body.appendChild(iframe);
        document.body.appendChild(form);
        form.submit();
    }
    catch(e){
        console.log(e);
    }
}

 

参考:https://www.cnblogs.com/YMaster/p/7707989.html

         https://segmentfault.com/a/1190000022255080

         https://www.jb51.net/article/122797.htm

posted @ 2020-08-06 19:49  全玉  阅读(1887)  评论(0编辑  收藏  举报