web通过文件链接直接下载文件给到用户,而不是先跳转预览

场景

  • 已知一个文件的存储链接,有下载操作,用户可以下载该文件,但是如果简单地通过window.location.href = file.path来实现的话,结果是web跳转到一个预览该文件的新页面,而且还需要手动点下载文件才能真正下载到本地。
  • 同理,a标签的href改成file.path也是同样的结果。

问题

  • 现在希望用户不用预览文件,而是在第一次下载操作之后就直接把文件下载到本地。

实现

  • 用XMLHttpRequest直接请求file.path,然后设置responseType能够控制请求返回的数据类型,默认是text类型,设置成blob型就能下载文件,还有arraybuffer, json等类型,什么场景用什么类型,具体情况具体分析,比如我只是想拿到文件文本内容做展示,那就直接text类型,比如我有一堆文件需要打包到zip里一起给到用户,那就用arraybuffer类型...... 所有类型见
  • 这里直接用axios封装就好了
    import axios from 'axios'
    
    export function getFile (path, type = 'text') {
      // path = '把路径前缀改成配置的proxy前缀,本地需要代理' // 本地把前缀换成代理前缀
      // 生产环境则是原path,但是需要后台配置跨域
      return new Promise((resolve, reject) => {
        axios.get(path, {
          responseType: type
        }).then((res) => {
          resolve(res.data) // 这里的res.data就是我们需要的文件对应responseType类型的数据了
        }).catch(err => {
          reject(err)
        })
      })
    }
    
  • 然后就能异步处理自己的逻辑了,这里只举下载文件的例子,具体情况具体分析
    // vue methods
    dwonload (record) {
      getFile(record.download_url, 'blob').then((file) => { // 直接下载文件传blob型
        const reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = (e) => {
          const a = document.createElement('a')
          // 获取文件名fileName
          a.download = record.file_name
          a.href = e.target.result
          document.body.appendChild(a)
          a.click() // 这样就触发浏览器下载文件了
          document.body.removeChild(a)
        }
      })
    }
    
posted @ 2022-12-01 10:51  Mizuki-Vone  阅读(399)  评论(0编辑  收藏  举报