专栏首页acoolgiser_zhuanlan前端实现文件下载功能的三种方式

前端实现文件下载功能的三种方式

一些管理系统常常会有导出文件的功能,这里介绍三种文件下载的尝试

1. 通过文件地址下载文件

 此方式最为简易,只需要知道文件在服务器上的地址,就可以通过a标签实现下载

<a href="https://.../158ac1e6917445a4aa384a2a7209445a.xlsx" download="test">下载文件</a>
<a href="https://.../6d0e6934246c4ba9ba1a43c6992836ca.png" download="test">下载图片</a>

已知文件的地址,可以通过上面的方式将地址放入href属性内,download属性存放下载文件的名称,此属性为必须。

若文件地址为异步获取,即点击下载/导出按钮时才会从接口拿,则可以通过js插入a标签来实现。demo如下:

异步获取文件路径之后执行以下代码即可自动下载

// 创建a标签
let a = document.createElement('a')
// 定义下载名称
a.download = '文件名称'
// 隐藏标签
a.style.display = 'none'
// 设置文件路径
a.href = 'https://.../158ac1e6917445a4aa384a2a7209445a.xlsx'
// 将创建的标签插入dom
document.body.appendChild(a)
// 点击标签,执行下载
a.click()
// 将标签从dom移除
document.body.removeChild(a)

缺点:此方式只适用于非图片和非pdf格式的文件下载,当文件为图片或pdf时,浏览器会打开预览,而非下载。

2. 已知文件内容,通过URL.createObjectURL()下载文件

此方式需与后端配合,当点击下载按钮时,请求接口,返回文件流。

URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。 createObjectURL()支持传入 File 对象、Blob 对象或者 MediaSource 对象(媒体资源)。

Demo:

handleDownload(file) {
  service.get(`/download?fileId${file.id}`,{responseType: 'blob'}).then((blobContent)=>{
      let a = document.createElement('a')
      a.download = file.fileName
      a.style.display = 'none'
      let url = URL.createObjectURL(blobContent)
      a.href = url
      document.body.appendChild(a)
      a.click()
      URL.revokeObjectURL(url) // 销毁
      document.body.removeChild(a)
  }
},

注意URL.createObjectURL()创建的对象使用完成后,即下载后可以通过URL.revokeObjectURL()移除该对象,释放内存。理论上讲dom销毁时,URL.createObjectURL()创建的对象也会随之销毁,我们可以不必手动销毁。但当页面有类似表格形式的文件列表时,下载完文件立即手动销毁对象无疑是最好的选择。

3. 已知文件内容,通过FileReader.readAsDataURL()下载文件

此方式与上一种方式大抵相似,需与后端配合,当点击下载按钮时,请求接口,返回文件流。

readAsDataURL 方法会读取指定的 Blob 或 File 对象。读取操作为异步操作,当读取完成时,可以从onload回调函数中通过实例对象的result属性获取data:URL格式的字符串(base64编码),此字符串即为读取文件的内容,可以放入a标签的href属性中。

Demo:

handleDownload(file) {
  service.get(`/download?fileId${file.id}`,{responseType: 'blob'}).then((blobContent)=>{
      // 创建FileReader实例
      const reader = new FileReader()
      // 传入被读取的blob对象
      reader.readAsDataURL(blobContent)
      // 读取完成的回调事件
      reader.onload = (e) => {
        let a = document.createElement('a')
        a.download = file.fileName
        a.style.display = 'none'
        // 生成的base64编码
        let url = reader.result
        a.href = url
        document.body.appendChild(a)
        a.click()
        document.body.removeChild(a)
      }
  }
},

总结:第二种方式与第三种方式非常相似,都是通过将blob转成地址,再放入a标签实现下载。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 前端实现文件下载所有方式

    先请求音频的链接,再把返回值转换成二进制,再根据他二进制对象生成新链接,再创建a标签,点击a标签

    小小咸鱼YwY
  • 前端下载文件的5种方法的对比

    在前端站点上下载文件,这是一个极其普遍的需求,很早前就已经有各种解决方法了,为什么还写这么老的文章,只是最近在带一个新人,他似乎很多都一知半解,也遇到了我们必经...

    歪马
  • Android编程使用WebView实现文件下载功能的两种方法

    本文实例讲述了Android编程使用WebView实现文件下载功能的两种方法。分享给大家供大家参考,具体如下:

    砸漏
  • Android使用ftp方式实现文件上传和下载功能

    近期在工作上一直再维护平台OTA在线升级项目,其中关于这个升级文件主要是存放于ftp服务器上的,然后客户端通过走ftp协议方式下载至本地Android机进行一个...

    砸漏
  • Python HTTP下载文件并显示下载进度条功能的实现

    下面的Python脚本中利用request下载文件并写入到文件系统,利用progressbar模块显示下载进度条。

    砸漏
  • 记一次老项目中的跨页面通信问题和前端实现文件下载功能

    由于本文介绍的主要还是基于javascript,不涉及任何框架方面的问题(如果想研究vue,react,angular方面的技术问题,可以移步我的其他文章),所...

    徐小夕
  • php+js实现的无刷新下载文件功能示例

    本文实例讲述了php+js实现的无刷新下载文件功能。分享给大家供大家参考,具体如下:

    砸漏
  • 5种前端实现邮件发送至指定邮箱的方式

    在前端开发中,JavaScript并没有提供直接操作Email邮箱的功能方法,但是如果遇到这样的需求,我们应该如何实现js发送邮件至指定邮箱功能呢?下面列举能够...

    Nealyang
  • day32 - sturct功能的使用,实现一个文件下载或上传

    # 发给另一端 # 另一端固定 recv(4),再 unpack,得到二进制字典长度

    少年包青菜

扫码关注云+社区

领取腾讯云代金券