前端文件下载

190 阅读2分钟

前言

最近有个需求,涉及到文件下载相关内容,项目基本开发完成,做了个总结

使用window.open或者window.href = xxx

       // 仅支持 不可以直接打开的文件类型,如果可以直接查看的文件类型,打开的话会直接显示
        // window.open('https://aa.pdf')
        window.open('https://aa.zip')
        
        // 仅支持 不可以直接打开的文件类型,如果可以直接查看的文件类型,打开的话会直接在当前页显示
        // window.location.href = 'https://bb.pdf'
        window.location.href = 'https://bb.zip'

注意点:

1.会出现URL长度限制问题
2.需要注意url编码问题

使用 a href download

 <h3>非跨域文件:</h3>
          <a href="@/assets/img/IMG_1949.pdf" download="11.pdf">pdf  </a>  
          <a href="@/assets/img/IMG_1949.zip" download="11.zip">zip  </a>  
          <a href="@/assets/img/IMG_1949.jpeg" download="11.jpeg">png  </a>  
          <h3>跨域文件:可以直接打开的文件是无法下载的,无法直接打开的文件可以下载,但是无法修改文件名</h3>
          <a href="https://cc.pdf" download>pdf  </a>  
          <a href="https:/cc.zip" download="11.zip">zip  </a>  
          <a href="cc" download>png  </a>  

注意点:
1.非跨域文件在chrome下是没问题的,跨域文件只有直接打不开的文件才可以下载(zip,rar等)
2.跨域文件即使能下载,也不能使用download属性修改下载下来的文件名

利用二进制文件下载

进行下载的思路很简单:发请求获取二进制数据,转化为Blob对象,利用URL.createObjectUrl生成url地址,赋值在a标签的href属性上,结合download进行下载。

/**
 * 下载文件
 * @param {String} path - 下载地址/下载请求地址。
 * @param {String} name - 下载文件的名字/重命名(考虑到兼容性问题,最好加上后缀名)
 */
downloadFile (path, name) {
    const xhr = new XMLHttpRequest();
    xhr.open('get', path);
    xhr.responseType = 'blob';
    xhr.send();
    xhr.onload = function () {
        if (this.status === 200 || this.status === 304) {
            // 如果是IE10及以上,不支持download属性,采用msSaveOrOpenBlob方法,但是IE10以下也不支持msSaveOrOpenBlob
            if ('msSaveOrOpenBlob' in navigator) {
                navigator.msSaveOrOpenBlob(this.response, name);
                return;
            }
            // const blob = new Blob([this.response], { type: xhr.getResponseHeader('Content-Type') });
            // const url = URL.createObjectURL(blob);
            const url = URL.createObjectURL(this.response);
            const a = document.createElement('a');
            a.style.display = 'none';
            a.href = url;
            a.download = name;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        }
    };
}

注意:
1.可以指定文件名
2.下载文件的进度需要自己实现,而且用户的体验没有直接下载好
3.这种情况更适用于知道了文件的所有信息,文件名,类型等,直接下载文件改名

非公共方案

对于七牛云平台,参考链接:developer.qiniu.com/kodo/1659/d…

<a :href="http://baidu.com/a.pdf?attname=a.pdf}`">下载</a>

参考文章:juejin.cn/post/684490…