首页IT科技vue调用后端接口进行渲染(vue 中从后端获取到文件的 url 地址,前端根据 url 地址下载文件)

vue调用后端接口进行渲染(vue 中从后端获取到文件的 url 地址,前端根据 url 地址下载文件)

时间2025-04-30 18:58:38分类IT科技浏览4414
导读:前言 项目用的是 vben admin 框架,用的是 vue3 + TS...

前言

项目用的是 vben admin 框架,用的是 vue3 + TS

项目需求数据导出功能,前端需要实现文件下载功能

后端返回的是文件的 url 地址 (本项目中返回的是阿里云 oss 的文件地址)

一              、实现思路

从后端得到的是一个 url 地址,先通过 fetch api 请求这个 url 地址并转换成 blob 对象,通过 URL.createObjectUrl() 将 blob 对象生成 url 地址,绑定到 <a > 标签 的 href 属性上面,结合 download 来实现点击 <a > 标签下载文件

二                   、具体实现

1.完整代码

代码如下:

function exportData() { let data = getForm().getFieldsValue(); exportTowerHistoryToExcel({ deviceId, createTime: data.startTime }).then((url) => { downLoadFile(url); }); } function downLoadFile (url){ let fileName = url.slice(url.lastIndexOf(/) + 1); // 这里是通过从后端获取到的 url 地址中截出来原本的文件名 fetch(url) .then((res) => res.blob()) .then((blob) => { const link = document.createElement(a); link.href = URL.createObjectURL(blob); // 下载文件的名称及文件类型后缀 link.download = fileName; document.body.appendChild(link); link.click(); //在资源下载完成后 清除 占用的缓存资源 window.URL.revokeObjectURL(link.href); document.body.removeChild(link); }); }

2.代码分析

2.1 通过 fetch 将 url 地址转换为 blob 对象

以下图片来自w3cschool文档 fetch_api

分析

res.blob() 的返回值是什么 从文档中我们知道res.blob() 返回的并不是一个 blob 对象,而是一个 Promise,继续 .then 获取到的才是 blob 对象

res.blob() 到底做了什么

每调用一次 res.blob() 都会执行 consume budy 的动作

执行流程大概是这个样子 : 获取字节流的读取器 --> 通过读取器来读取到所有的数据 --> 将数据包装成 blob 对象并返回

2.2 通过 URL.createObjectUrl() 将 blob 对象生成 url 地址

以下图片来自MDN文档 URL.createObjectURL()

分析

URL.createObjURL() 做了什么

我们在调用 URL.createObjURL() 的时候传递的参数是一个 blob 对象,每次调用 URL.createObjURL() 的时候,都会创建一个新的 URL 对象

注意 : 即使是用同一个 blob 对象 , 每次调用 URL.createObjURL() 都会生成不同的 URL 对象

生成的的 URL 对象什么时候会被释放

浏览器在 docoment 卸载的时候,会自动释放

为了获得最佳性能和内存使用状况,应当在不需要使用这些 URL 对象的安全的实际,主动释放掉他们

怎么释放生成的的 URL 对象 通过调用 URL.removeObjectURL(需要释放的URL ) 可以来释放生成的 URL 对象

2.3 创建 <a> 标签元素,将该元素放到页面当中,并通过点击事件来实现下载功能

<a href="xxxxx"> <a href="xxxxx" download="xxxx">

href:文件的绝对/相对地址

download: 文件名(可省略              ,省略后浏览器自动识别源文件名 , 但是有可能导致自动识别源文件名的时候没有文件后缀,导致文件没有格式) const link = document.createElement(a); link.href = URL.createObjectURL(blob); // 下载文件的名称及文件类型后缀 link.download = fileName; // 这里 download 可以不写 document.body.appendChild(link); link.click();

总结

其实找到这个解决方案的时候直接拿来用挺顺利的,但是一开始并不明白它是怎么工作的,甚至每行都没太明白它为什么这么做,在整理下来的过程中,反而理解了一些东西,与君共勉~

声明:本站所有文章                   ,如无特殊说明或标注      ,均为本站原创发布            。任何个人或组织          ,在未征得本站同意时                    ,禁止复制      、盗用          、采集                    、发布本站内容到任何网站         、书籍等各类媒体平台                    。如若本站内容侵犯了原著者的合法权益         ,可联系我们进行处理       。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
显示路由的命令(route命令 – 显示与设置路由信息) redis数据模型(最近沉迷Redis网络模型,无法自拔!终于知道Redis为啥这么快了)