前端项目是如何实现文件下载的?

前端项目是如何实现文件下载的?

在业务开发中,我想大多数同学可能会遇到关于实现文件下载这方面的需求,例如说通过点击某一个小按钮或者标签来实现触发浏览器的下载功能

这里我先使用koa2作为后端,起一个小小的Demo

在这个Demo中我写了一个请求文件流的Api,当客户端向这个Api进行请求数据后,服务器端会返回一个File

接下来是前端部分了,我们用pnpm create vite快速起一个项目,这里我就不再演示这个过程了

我简单的写了一个按钮并绑定了对应的请求函数,我们来看看network中报文会返回什么数据

原来是跨域了,我们在vite.config.ts中处理一下,通过设置代理的方式来解决跨域问题

接下来,我再请求一次看看

现在,服务器也将我们想要的文件返回的过来,但是作为用户我是要下载这个文件,而不是在请求中看到这个文件的内容

我们预期是效果应该是通过浏览器来下载这个文件

问题不大,我们写一个小小的函数简单的解决这个问题

typescript 复制代码
function streamToDownloadFile(data: BlobPart, filename: string,type: string= 'application/octet-stream') {
  let blob = new Blob([data], { type });
  let url = window.URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = url;
  // 重命名文件
  link.download = filename;
  link.click();
  URL.revokeObjectURL(url);
}

const download = () => {
  console.log('download');
  axios.get('/api/download/foo').then(res => {
    // 触发浏览器下载机制
    streamToDownloadFile(res.data, 'foo.txt')
  })
}

注意,download属性是HTML5的新特性

这样子我们的问题就解决了,当用户点击"下载文件"时,浏览器会自动把文件下载到客户端上面

在代码中我们写了一个streamToDownloadFile函数,实现了将文件数据转换为可下载的文件并触发下载操作

主要步骤分为:

  1. 通过外部传入的文件数据和类型创建一个Blob对象
  2. 利用createObjectURL创建临时url,引用Blob对象的内容
  3. 创建a标签,设定href和download属性
  4. 通过click事件,触发浏览器下载机制
  5. 最后,使用revokeObjectURL释放之前创建的临时URL,以防止内存泄漏

返回链接下载

除了后端返回文件流的方式,后端也可以返回一个文件地址给前端,然后前端根据文件地址请求触发浏览器下载

我们来模拟一下,这个场景

配置一下koa2静态文件访问,需要安装pnpm add koa-static这个包来实现静态资源的问题

这里,我们会遇到一个比较常见的问题,在pdf、txt、jpg等文件用a标签直接用href属性,是不能实现下载功能的,浏览器会直接识别并显示这些文件

我们再写一个返回sheet.xlsx文件的地址的Api提供给前端使用

我们在前端请求下这个Api,我们可以得到一个对象,包括文件名,下载文件链接(有点废话..)

这种情况下,我们要采用和上面一样的方法去处理这些格式文件去下载,所以我们这里把文件改为xlsx文件进行测试

因为我的电脑上之前的安装了迅雷的扩展,所以默认有下载任务会被迅雷接管下载

这样,我们就实现了通过URL的方式来下载文件

相比前面通过文件流下载文件的方式,这个方法会比较简单一些,不过有时候可能也会出现一些小Bug,例如跳转后没有下载问题,而是打开文件

Demo地址:file-download-demo

相关推荐
骑着蜗牛撵大象3272 分钟前
LangChain 工具调用从声明到闭环:给智能体接上真实的手脚
前端
数据掘金13 分钟前
百度统计后台页面数据异常?从手动调用时机开始排查
前端
hunteritself14 分钟前
10 层 4K 实时剪辑,国产工作站进入广电制作核心
大数据·前端·人工智能·深度学习·transformer
踩着两条虫15 分钟前
我在浏览器里“盖”了一个村:Vue + Three.js 大屏开发踩坑记
前端·vue.js·three.js
默_笙18 分钟前
🧀 让大模型的答案"流"出来:NestJS AI 模块 + SSE + RxJS 实战
javascript·人工智能
mbshqqb20 分钟前
TypeScript基础教程之同步生成器
前端·javascript·typescript
嘟嘟同学和妮妮同学38 分钟前
【升级】一个中国历史可视化站:皇帝时间线梳理、古代思想流派、诗词鉴赏 (2)
前端·html
暗夜行者之光1 小时前
LangGraph + MCP 实战:构建"自然语言查数据"的 ChatBI Agent
前端·后端
触底反弹1 小时前
🎯 LangSmith 学习与面试全攻略:从 Agent「盲盒」到全链路观测与量化评估
人工智能·面试
一tiao咸鱼1 小时前
还在手动海投?我做了个 AI 求职助手,自动筛选 BOSS 职位再精准投递
前端·后端·面试