前端下载通常分为两种情形,一种是后端直接给一个文件地址,通过浏览器打开就可以下载,另外一种则需要发送请求,后端返回二进制流数据,前端解析流数据,生成URL,实现下载。

一.指定文件路径下载

该方式将下载逻辑放在后端处理,后端直接返回文件url地址

  window.location.herf = '/xxx/xxx/xxxx'

二.根据请求返回二进制数据流,生成流文件URL下载

根据二进制流数据生成下载URL可以有多种方式实现,具体实现如下:


1.将二进制数据封装为BLOB对象

前端通过创建a标签,为href属性赋值,模拟自动点击事件,最后在清除a标签即可,使用到URL.createObjectURL(object)这个方法

接收后端传过来的二进制流。默认情况下axios不会处理二进制数据,即请求可以正常被浏览器接收,但是axios不会去处理。需要在请求的时候设置responseType: 'blob'才可以 

// get 请求
axios({
    method: 'get',
    url,   // 这里自行设置传参
    params, // 这里自行设置传参
    responseType:'blob' // 这里是重点,敲黑板
}).then(res => {
        // 获取响应头中的文件名
        let filename = response.headers  //下载后文件名
        filename = filename["content-disposition"]
        filename = filename.split(";")[1].split("filename=")[1]
        // 创建 a 标签
        let elink = document.createElement('a');
        document.body.appendChild(elink);
        elink.style.display = 'none'; // 隐藏起来
        elink.download = filename
        // 如果后端没有返回,可以自己设置下载文件的名称 elink.download = 'XXX文件.pdf'; 
        let blob = new Blob([res.data]);
        // 兼容webkix浏览器,处理webkit浏览器中herf自动添加blob前缀,默认在浏览器打开而不是下载
        const URL = window.URL || window.webkitURL
        elink.href = URL.createObjectURL(blob) // 通过createObjectURL方法转换成对象url
          
        elink.click();
        document.body.removeChild(elink);
        URL.revokeObjectURL(elink.href); // 释放URL 对象
        
})

 2、将二进制数据封装为文件读取FileReader对象

注意: 使用 FileReader对象封装二进制流之后没办法设置下载的文件名,默认文件名为下载,文件格式根据读取的是请求返回的content-type。 

// utils.js
export const download = (res) => {
  // 创建文件对象
  let reader = new FileReader()
  // 监听读取完毕
  reader.onloadend = function () {
    // 返回base64位的文件内容
    let url = reader.result
    // 下载
    window.location.href = url
  }
  // 开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个data: URL格式的Base64字符串以表示所读取文件的内容。
  reader.readAsDataURL(res)
}

3.使用插件downloadjs

 npm install --save downloadjs
  • 引入插件
    import download from "downloadjs"

    或者

     const download = require('downloadjs')
    
      export const downloadFile = (res, type, filename) => {
        // 将二进制流转成blob对象
        const blob = new Blob([res], {
          type: type
        })
        // 调用插件方法
        download(blob, filename, type);
      }

注意:发送请求时一定要注意设置responseType: 'blob',否则后端返回的数据可能不是二进制流数据。 

(如有帮助,点赞加关注,追码不迷路) 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐