vue從后端獲取到文件的?url?地址及前端根據(jù)?url?地址下載文件的實(shí)現(xiàn)思路
前言
項(xiàng)目用的是 vben admin 框架,用的是 vue3 + TS
項(xiàng)目需求數(shù)據(jù)導(dǎo)出功能,前端需要實(shí)現(xiàn)文件下載功能
后端返回的是文件的 url 地址 (本項(xiàng)目中返回的是阿里云 oss 的文件地址)
一、實(shí)現(xiàn)思路
從后端得到的是一個(gè) url 地址,先通過 fetch api 請(qǐng)求這個(gè) url 地址并轉(zhuǎn)換成 blob 對(duì)象,通過 URL.createObjectUrl() 將 blob 對(duì)象生成 url 地址,綁定到 <a >
標(biāo)簽 的 href 屬性上面,結(jié)合 download 來實(shí)現(xiàn)點(diǎn)擊 <a >
標(biāo)簽下載文件
二、具體實(shí)現(xiàn)
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 地址轉(zhuǎn)換為 blob 對(duì)象
以下圖片來自w3cschool文檔 fetch_api
分析
res.blob() 的返回值是什么
從文檔中我們知道res.blob() 返回的并不是一個(gè) blob 對(duì)象,而是一個(gè) Promise,繼續(xù) .then 獲取到的才是 blob 對(duì)象
res.blob() 到底做了什么
每調(diào)用一次 res.blob() 都會(huì)執(zhí)行 consume budy
的動(dòng)作
執(zhí)行流程大概是這個(gè)樣子 : 獲取字節(jié)流的讀取器 --> 通過讀取器來讀取到所有的數(shù)據(jù) --> 將數(shù)據(jù)包裝成 blob 對(duì)象并返回
2.2 通過 URL.createObjectUrl() 將 blob 對(duì)象生成 url 地址
以下圖片來自MDN文檔 URL.createObjectURL()
分析
URL.createObjURL() 做了什么
我們?cè)谡{(diào)用 URL.createObjURL() 的時(shí)候傳遞的參數(shù)是一個(gè) blob 對(duì)象,每次調(diào)用 URL.createObjURL() 的時(shí)候,都會(huì)創(chuàng)建一個(gè)新的 URL 對(duì)象
注意 : 即使是用同一個(gè) blob 對(duì)象 , 每次調(diào)用 URL.createObjURL() 都會(huì)生成不同的 URL 對(duì)象
生成的的 URL 對(duì)象什么時(shí)候會(huì)被釋放
瀏覽器在 docoment 卸載的時(shí)候,會(huì)自動(dòng)釋放
為了獲得最佳性能和內(nèi)存使用狀況,應(yīng)當(dāng)在不需要使用這些 URL 對(duì)象的安全的實(shí)際,主動(dòng)釋放掉他們
怎么釋放生成的的 URL 對(duì)象
通過調(diào)用 URL.removeObjectURL(需要釋放的URL )
可以來釋放生成的 URL 對(duì)象
2.3 創(chuàng)建 <a> 標(biāo)簽元素,將該元素放到頁面當(dāng)中,并通過點(diǎn)擊事件來實(shí)現(xiàn)下載功能
<a href="xxxxx" rel="external nofollow" rel="external nofollow" > <a href="xxxxx" rel="external nofollow" rel="external nofollow" download="xxxx">
href:文件的絕對(duì)/相對(duì)地址
download: 文件名(可省略,省略后瀏覽器自動(dòng)識(shí)別源文件名 , 但是有可能導(dǎo)致自動(dòng)識(shí)別源文件名的時(shí)候沒有文件后綴,導(dǎo)致文件沒有格式)
const link = document.createElement('a'); link.href = URL.createObjectURL(blob); // 下載文件的名稱及文件類型后綴 link.download = fileName; // 這里 download 可以不寫 document.body.appendChild(link); link.click();
總結(jié)
其實(shí)找到這個(gè)解決方案的時(shí)候直接拿來用挺順利的,但是一開始并不明白它是怎么工作的,甚至每行都沒太明白它為什么這么做,在整理下來的過程中,反而理解了一些東西,與君共勉~
到此這篇關(guān)于vue 中從后端獲取到文件的 url 地址前端根據(jù) url 地址下載文件的文章就介紹到這了,更多相關(guān)vue后端獲取 url 地址內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解vue與后端數(shù)據(jù)交互(ajax):vue-resource
本篇文章主要介紹了詳解vue與后端數(shù)據(jù)交互(ajax):vue-resource,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03一文詳解Vue選項(xiàng)式?API?的生命周期選項(xiàng)和組合式API
這篇文章主要為大家介紹了Vue選項(xiàng)式?API?的生命周期選項(xiàng)和組合式API變化詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03對(duì)vue下點(diǎn)擊事件傳參和不傳參的區(qū)別詳解
今天小編就為大家分享一篇對(duì)vue下點(diǎn)擊事件傳參和不傳參的區(qū)別詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09vue項(xiàng)目中使用rem,在入口文件添加內(nèi)容操作
這篇文章主要介紹了vue項(xiàng)目中使用rem,在入口文件添加內(nèi)容操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-11-11