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

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

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

这里我先使用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

相关推荐
江华森24 分钟前
Web漏洞与中间件框架漏洞实战详解
面试
lovingsoft27 分钟前
Chrome Lighthouse 详解
前端·chrome
Qlly37 分钟前
全栈工程师怎么接需求?从一句「加个功能」聊到能开发、能验收
前端·后端
马可家的菠萝41 分钟前
你的微信“文件传输助手”,是不是已经成了第二个网盘?
前端·后端·架构
略略略啦41 分钟前
Vibe Coding 基于Spec DD和TDD的实践指南
前端
shmily麻瓜小菜鸡1 小时前
前端实现图片与PDF文字识别敏感信息打码方案
前端·pdf·状态模式
打工仔折腾 AI1 小时前
LangChain 工具调用实战:从 Tool 定义到 Agent 执行链路拆解
java·前端·人工智能·后端·python·langchain·ai agent 实战
汉堡大王95271 小时前
单次输出拉到100万Token:拆完 Gemini 4 Argon 的续写协议,才看懂谷歌这7个月在憋什么
前端·人工智能·后端
看浪的路人1 小时前
第9讲:大模型应用监控与可观测性——OpenTelemetry + Prometheus + Grafana 全链路追踪
java·前端·spring
内存过载1 小时前
用表格模拟甘特图:项目排期的土办法
前端·低代码