美文网首页
前端下载非同源文件自定义文件名方案

前端下载非同源文件自定义文件名方案

作者: 0月 | 来源:发表于2021-12-23 12:08 被阅读0次

    背景

    有时候我们需要点击下载一些资源如excel 、pdf、 ppt、图片等,并且要支持自定义下载名字。当下载链接与当前页是同源时,可以通过a标签download属性设置,比如我在a.com打开的页面下载a.pdf

    <a download="自定义名字.pdf" href="a.com/a.pdf">下载</a>
    

    这样子同源下载的文件名就是 "自定义名字.pdf"

    但是一般实际场景,文件资源都是有独立的资源服务器的,和主应用的域名不一致,上面的方法就不管用了。那么也没有其他方法呢?

    方案

    下载的实际原理就是前端发一个http请求去目标链接,然后资源服务器在接收请求后在response header里面设置content-type为文件流,和 Content-Disposition,例如:

    Content-Type: 'application/octet-stream',
    Content-Disposition: 'attachment;filename=a.pdf'
    

    然后浏览器在接收文件流时自动采用下载的方式接收,这是浏览器自动识别的,那么有没有人工手动控制这个流程呢?其实是可以的。

    搞清楚整个下载流程后,我们可以得到一个解决方案:

    前端可以通过ajax去请求资源链接,因为服务端返回的是文件流,前端要接收的话,就需要知道怎么去操作文件流,前端在html5之后有个Blob对象,所以我们在请求时要设置对应的responseType:blob就可以通过blob接收,最后把blob数据保存到本地。

    具体操作如下:

    利用现成工具,安装 axios 、file-saver

    npm i axios file-saver -S
    

    然后代码:

    /**
     * URL地址下载文件
     * @param url 下载地址
     * @param fileType  excel | csv 或者不确定类型的,直接传类型,例如 bipkg
     * @param fileName 文件名称
     * @private
     */
    const downloadByUrl = (url, fileType, fileName = '未命名') => {
      return axios.get(url, {
        responseType: 'blob',
        beforeErrorAction () {
          return false;
        },
      }).then(res => {
        let mime = '';
        switch (fileType) {
          case 'xlsx':
            mime = 'application/vnd.ms-excel';
            break;
          case 'csv':
            mime = 'text/csv';
            break;
          default:
            break;
        }
        const blob = new Blob([res], { type: mime });
        fileSaver.saveAs(blob, `${fileName}.${fileType}`);
      }).catch(() => {
        const aTag = document.createElement('a');
        aTag.href = url;
        aTag.download = fileName; // 此属性仅适用于同源 URL https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/a
        aTag.style.display = 'none';
        document.body.appendChild(aTag);
        aTag.click();
        // 下载完成后删除dom节点
        document.body.removeChild(aTag);
      });
    };
    
    

    调用方法下载

    downloadByUrl('xxx.com/a.pdf', 'pdf', '自定义名字')
    

    总结

    以上就是前端自定义下载文件名的解决方案,如果你有更好的方法欢迎交流。

    相关文章

      网友评论

          本文标题:前端下载非同源文件自定义文件名方案

          本文链接:https://www.haomeiwen.com/subject/xmxcqrtx.html