通过网页,下载文件是很常见的需求,如果是图片,txt等,点击链接就会直接在游览器中打开文件 📁 ,
想实现点击后下载,需要后端的配合。

写在前面

只要响应头 Content-Type 为 application/octet-stream 类型
并且响应文件流,游览器就会启用下载
对于前端来说,就是个下载地址,通过 get、post 请求即可。
下图为相关的响应头的说明

image

前端同步下载方式

  1. 使用 window.open 跳转即可实现下载。
  2. 通过 iframe 标签跳转的方式在当前页面实现下载。
window.open('//xmp.down.sandai.net/xmp/XMPSetup6.1.7.810xmpdl.exe', 'iframe-name')
// 调用后,游览器即开始下载

前端异步下载方式

通过 Blob 可以实现将需要的任何资源通过异步请求获取,先存到内存中
再通过 a 标签 download 特性下载到硬盘(下载到硬盘后释放内存)
注意,只有小文件才能用这种方式,大文件不适合!
方法如下:(下面使用了 file-saver 库,并且推荐使用)

// 基于 file-saver,解决兼容性问题
import FileSaver from 'file-saver';
import axios from 'axios'

axios
  .get('//xxx/xxx/xxx', {
    responseType: 'blob'
    // => xhr.responseType = 'blob'
  })
  .then(({ data: blob }) => {
    FileSaver.saveAs(blob, "hello world.txt");
  })
// 基于原生,可能有兼容问题(具体未测试)
import axios from 'axios'

axios
  .get('//xxx/xxx/xxx', {
    responseType: 'blob'
    // => xhr.responseType = 'blob'
  })
  .then(({ data }) => {
    // data 为 Blob 实例
    const blob = data;
    
    // 创建 a 标签(下载元素)
    const downloadElement = document.createElement('a')
    
    // 根据 blob 创建文件临时地址
    const href = window.URL.createObjectURL(blob)
    
    // 将 a 标签的 href 设置为临时文件路径
    downloadElement.href = href
    
    // 下载后文件名
    downloadElement.download = '1.mp4'
    
    // 页面追加 a 标签
    document.body.appendChild(downloadElement)
    
    // 手动触发点击事件,通过 download 特性下载文件
    downloadElement.click()
    
    // 删除 a 标签
    document.body.removeChild(downloadElement)
    
    // 释放内存
    window.URL.revokeObjectURL(href)
  })