关于前端下载得几个方法

504 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

前端下载整体上一共三种常用方法

1 a 标签超链接下载

下面是封装的一个下载的组件的代码,仅供参考

<template>
  <a
    ref="link"
    :href="url"
    :download="fileName"
  />
</template>

<script>
export default {
  name: 'HDownload',
  props: {
    hrefUrl: {
      type: String,
      default: ''
    },
    fileName: {
      type: String,
      default: ''
    },
    data: {
      type: Object,
      default: null
    }
  },
  computed: {
    url () { //
      const downData = this.data
      if (downData) {
        const params = Object.keys(downData).map(function (key) {
          const value = downData[key]
          return typeof (value) !== 'undefined' && value !== null ? encodeURI(key) + '=' + encodeURI(value) : ''
        }).join('&')
        return this.hrefUrl.includes('?') ? '&' + params : '?' + params
      }
      return this.hrefUrl
    }
  },
  methods: {
    // 下载用API
    download () {
      this.$nextTick(() => {
        this.$refs.link.click()
      })
    }
  }
}
</script>

这种下载有个缺点就是只要获取到你的连接地址无论是谁都能够下载文件,不具有鉴权的作用,会有安全风险 所以这时需要后端进行配合提供接口返回数据流给我们,通过创建按Blob对象来进行下载文件 具体Blob对象的类型可以根据需求自己来定义

 apiDownload(this.state.openRows.id).then(res => {
      const _href = window.URL.createObjectURL(new Blob(["\ufeff" + res], { type: 'application/msword' }));
      const _link = document.createElement('a');
      _link.style.display = 'none';
      _link.href = _href;
      let downName = `我的文档`;
      _link.setAttribute('download', this.state.openRows.name);
      document.body.appendChild(_link);
      _link.click();
      document.body.removeChild(_link);

    })

2 iframe标签来下载

iframe来下载和a标签大同小异 主要遇到超链接下载有一个弊端,就是对于xls文件 Microsoft Edge 浏览器下载会出问题的坑,不知道是浏览器问题还是我系统环境的问题所以可以用iframe下载进行个兼容

  var url = record.fileUrl  // 文件地址
      var iframe = document.createElement('iframe')
      iframe.src = url
      iframe.style.display = 'none'
      iframe.onload = function () {
        console.debug('start downloading...')
        document.body.removeAttribute(iframe)
      }
      document.body.appendChild(iframe)

3用window.open(url)来下载

这个也挺简单的 就是window.open(url)的属性进行下载,但是如果是打开新页面下载的话可能浏览器默认禁止打开新页面导致失败

4 关于下载中的问题

遇到过https的环境中请求下载的资源是http的 浏览器会抛出错误

Mixed Content: The site at 'https:' was loaded over a secure connection, but the file at 'http://enterprise/tax/adasd?' was loaded over an insecure connection. This file should be served over HTTPS. This download has been blocked. See https://blog.chromium.org/2020/02/protecting-users-from-insecure.html for more details.

这时候不要纠结前端怎么解决了,跟后端沟通提供三种思路
1:后端同事写接口,把请求好的数据通过流的形式返回前端,然后采取上文说的方法下载
2:同样需要后端同事帮忙,我们前端对资源改为https的,后端配置代理,代理到http的然后把资源进行返回
3: 把资源直接换成https的,这种方法最直接但是可能满足不了大部分业务需求